> There is, furthermore, mechanical sympathy between stable values and the Java runtime. Under the hood, the content of a stable value is stored in a non-final field annotated with the JDK-internal @Stable annotation. This annotation is a common feature of low-level JDK code. It asserts that, even though the field is non-final, the JVM can trust that the field’s value will not change after the field’s initial and only update. This allows the JVM to treat the content of a stable value as a constant, provided that the field which refers to the stable value is final. Thus the JVM can perform constant-folding optimizations for code that accesses immutable data through multiple levels of stable values, e.g., Application.orders().getLogger().
> Consequently, developers no longer have to choose between flexible initialization and peak performance.
> Under the hood, the content of a stable value is stored in a non-final field annotated with the JDK-internal @Stable annotation.
This is saying that the StableValue instance will have a non-final field annotated that way, not that there is no StableValue instance allocated. Note that the user-code-level field is final, so that's not the field being referred to here. In fact, this description is what makes me think that the StableValue object might exist even after JITting.
The general thinking around this is that if you're still in interpreted code, you're not in the kind of context where the cost of an extra object allocation is worth worrying about.