LoginSignup
10
3

More than 3 years have passed since last update.

実質的にfinalな変数とは何か

Last updated at Posted at 2019-05-19

実質的にfinal

Javaのラムダ式では実質的にfinalなローカル変数にアクセスできるらしい。
参考書には「finalで修飾されていなくても変更されない変数」とあった。

どういうことか

final付いていないけど宣言時から一切変更無いからつまりfinalと同じだよね!」ってこと

この場合、ローカル変数iは実質的finalだけど、

LambdaStudy.java
public class LambdaStudy {

    public static void main(String[] args) {
        int i = 10;
        Calculate c = x -> x + i;
        System.out.println(c.calc(20));//30
    }
}

interface Calculate {
    public int calc(int x);
}

この場合はインクリメントでiの値を変えてしまっているので、実質的finalでは無くなり、コンパイルエラーとなってしまう。

LambdaStudy.java
public class LambdaStudy {

    public static void main(String[] args) {
        int i = 10;
        i++;
        Calculate c = x -> x + i;//Local variable i defined in an enclosing scope must be final or effectively final
        System.out.println(c.calc(20));
    }
}

interface Calculate {
    public int calc(int x);
}

参照型ではどうか

参照型であっても変わらない。

この場合、sb.append("d")は変数sbの参照先のオブジェクトに変更を与えているだけで変数sbそれ自体を変更している訳では無いのでsbは実質的finalとなり実行できる。

LambdaStudy.java
public class LambdaStudy {

    public static void main(String[] args) {
        int i = 10;
        StringBuilder sb = new StringBuilder("abc");
        sb.append("d");
        Calculate c = x -> {
            System.out.println(sb.toString());//abcd
            return  x + i;
        };
        System.out.println(c.calc(20));//30
    }
}

interface Calculate {
    public int calc(int x);
}

sbに再代入したらsbの参照先が変わってしまうので実質的finalでは無くなってしまう。(コンパイルエラー)

LambdaStudy.java
public class LambdaStudy {

    public static void main(String[] args) {
        int i = 10;
        StringBuilder sb = new StringBuilder("abc");
        sb.append("d");
        sb = new StringBuilder("efg");
        Calculate c = x -> {
            System.out.println(sb.toString());//Local variable sb defined in an enclosing scope must be final or effectively final
            return  x + i;
        };
        System.out.println(c.calc(20));
    }
}

interface Calculate {
    public int calc(int x);
}

まとめ

実質的finalな変数とは「変数宣言時から一切変更がない変数」のことである。

10
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
3