Directly initialized final field is not constant folded later when prefix with "this"
forax at univ-mlv.fr
forax at univ-mlv.fr
Thu Jun 11 19:35:03 UTC 2020
----- Mail original -----
> De: "Christoph Dreis" <christoph.dreis at freenet.de>
> À: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "compiler-dev" <compiler-dev at openjdk.java.net>, "Alex Buckley" <alex.buckley at oracle.com>
> Envoyé: Jeudi 11 Juin 2020 21:00:33
> Objet: Re: Directly initialized final field is not constant folded later when prefix with "this"
> 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.
in your example, the field is changed but you don't access it because you try to access it using javac which as you said consider it as a constant expression,
try using reflection or a VarHandle to acces to the field
System.out.println(field.get(hello));
>
> Cheers,
> Christoph
regards,
Rémi
>
>
> [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