On 02/19/2016 03:07 PM, Aleksey Shipilev wrote:
Hi Peter,
On 02/19/2016 05:05 PM, Peter Levart wrote:
Your comment in String:
140 * @implNote Note this field is not {@link Stable}, because we
want
141 * LATIN1 (0) coder to fold too. {@link Stable} would not allow
that,
142 * as it reserves the default value as "not initialized" value.
143 * Constant-folding this field is handled internally in VM.
144 */
145 private final byte coder;
Couldn't @Stable final instance fields constant-fold the default value
too in general? I mean can't it be assumed that the final field has been
set before JIT kicks in?
We've been over this multiple times, actually. @Stable is not designed
to fold default value -- it is a part of its design to ignore final
fields with default values. Because @Stable is used largely for lazy
initialization, and default value is the important marker in field's
lifecycles.
Cheers,
-Aleksey
Yes, I understand the general principle of @Stable design and the role
of default value in @Stable fields. But given that:
- instance final fields must be set in the constructor
- the reference to the constructed object can not be assigned to a
static final field until the constructor is finished
...the compiler could assume that even the default value is the final
field's stable value, couldn't it?
I understand that these are Java language constraints and not
necessarily bytecode constraints. Also, while a static final field can
only be assigned to reference an instance after the instance is fully
constructed, this does not hold for @Stable fields in general, for example:
class Foo {
@Stable static Foo foo;
@Stable final int coder;
Foo() {
foo = this;
// outside code could already access Foo.foo.coder and constant
fold it to 0
coder = 1;
}
}
...given that @Stable is an internal annotation, such usages could be
advised against. It is generally bad practice to publish an object from
within its constructor anyway.
But never mind. This is just me thinking loud.
Regards, Peter