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

Christoph Dreis christoph.dreis at freenet.de
Thu Jun 11 17:08:39 UTC 2020


Hi,

I hope this is the correct mailing list and hopefully not a too stupid mail.

Today I experimented around with constant folding and created the following class:

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

To my surprise javap showed the following bytecode (excerpts only):

  private final java.lang.String world;
    descriptor: Ljava/lang/String;
    flags: (0x0012) ACC_PRIVATE, ACC_FINAL
    ConstantValue: String world

  public java.lang.String worldField();
    Code:
       0: ldc           #14                 // String Hello world
       2: areturn

  public java.lang.String worldFieldThis();
    Code:
       0: aload_0
       1: invokestatic  #16                 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
       4: pop
       5: ldc           #7                  // String world
       7: invokedynamic #22,  0             // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String;
      12: areturn

I would have expected to actually see things in worldFieldThis to be constant folded as well.
Especially since the field is initialized directly and not anywhere else (e.g. in the constructor).
Why is "this" making a difference here?

Is this a bug or a known deficit? I wonder if it would be possible to constant fold these cases, too, or why they're maybe not constant foldable?
After all, even with reflection I can't change the field (to the best of my knowledge).
Also the spec [1] would lead me to the conclusion that those cases might be constant foldable. Serialization also shouldn't be an issue here, shouldn't it?

> 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.

Thanks in advance for any information on the topic.

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