What are practically final variables?

Virtually final

It seems that Java lambda expressions can access local variables that are ** practically final **. The reference book said, "Variables that do not change even if they are not qualified with ** final **."

What do you mean

"It doesn't come with ** final **, but it hasn't changed at all since it was declared, so it's the same as ** final **!"

In this case, the local variable ʻi` is practically 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);
}

In this case, since the value of ʻi` has been changed by incrementing, it is not practically final and a compile error occurs.

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);
}

How about a reference type?

It does not change even if it is a reference type.

In this case, sb is becausesb.append ("d")is only changing the referenced object of the variable sb, not the variable sb itself. It becomes practically final and can be executed.

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);
}

If you reassign to sb, the reference destination of sb will change, so it will not be practically final. (Compile error)

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);
}

Summary

Substantially final variables are ** "variables that have not changed at all since the variable was declared" **.

Recommended Posts

What are practically final variables?
[Environment variables] What are rails environment variables?
What I learned in Java (Part 2) What are variables?
[Rails] What are params?
[Java Silver] What are class variables instance variables and local variables?
[rails] What are Strong Parameters?
What are command line arguments?
What are Ruby class methods?
config.ru What are you doing?
What are mass assignment vulnerabilities?
What are Java metrics? _Memo_20200818
[Java] How to use static modifiers (What are static final and static import)
Java array variables are reference types
What are the rules in JUnit?
Java local variables are thread safe
[Java] What are overrides and overloads?