Directly initialized final field is not constant folded later when prefix with "this"

Christoph Dreis christoph.dreis at freenet.de
Thu Jun 11 19:00:33 UTC 2020


Hi Remi,

> and Christoph, you can change the value of a final field by reflection :(

if I put this to the test with the following:

public class Main {

	public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
		Hello hello = new Hello();
		Field field = Hello.class.getDeclaredField("world");
		field.setAccessible(true);

		field.set(hello, "Reflection");
		System.out.println(hello.worldField());
	}

}

public class Hello {

	private final String world = "world";

	public String world() {
		return "Hello " + "world";
	}

	public String worldField() {
		return "Hello " + world;
	}

	public String worldFieldThis() {
		// This is not constant folded
		return "Hello " + this.world;
	}

}

It will print "Hello world" instead of "Hello Reflection".
Keep in mind that the final field is already initialized.

The original mail included the following from the spec [1]:

> If a final field is initialized to a constant expression (§15.29) in the field declaration,
> changes to the final field may not be observed, since uses of that final field are replaced at compile time with the value of the constant expression.

Am I missing something?
Based on reading spec, my belief was that it doesn't actually matter if it's prefixed with "this" or not. Especially, the "uses of that final field" part.

Cheers,
Christoph


[1] https://docs.oracle.com/javase/specs/jls/se14/html/jls-17.html#jls-17.5.3





More information about the compiler-dev mailing list