JEP 401: Implications of migrating a class to a primitive one
Tim Feuerbach
feuerbach at spell.work
Tue Jan 11 13:24:59 UTC 2022
Hi,
after reading JEP 401, I have a couple of questions regarding the
conversion of existing classes into primitive classes, specifically: is
this change (bytecode) compatible or not?
Let's assume we have a Point class like in the JEP, but not yet declared
as primitive. There's also another class, PointHolder:
class PointHolder {
Point point;
boolean isInitialized() {
return Objects.nonNull(point);
}
}
(I used Objects.nonNull since I didn't know whether you want to make
"non-ref'd primitive == null" a compile time error).
Before primitive class conversion, after compiling both Point and
PointHolder, I run the following program:
PointHolder ph = new PointHolder();
System.out.println(ph.isInitialized()); // false
Now I add "primitive" to the Point class and recompile *only the Point
class*.
1. Does the program still run after that change?
From my understanding, the "point" field in PointHolder was an L type
and therefore the JVM will happily initialize the field to null. The
output is still "false".
2. Can I recompile PointHolder without errors?
I assume yes, and the Point field (which was implicitly Point.ref) will
now refer to the primitive Q type. However, since this will result in
the field being initizialized with Point.default, the semantics of the
program will change (isInitialized() returns true). This seems like a
source for potential errors and would mean once I published a type, I
should never migrate it to a primitive (I can however choose to migrate
to a value class, as is planned for LocalDate etc.). Also, it's counter
intutitive that the program will break only once I recompile the
consumer of a changed class, not the changed class itself.
JEP 402 gets away with making Integer etc. primitives and not breaking
existing code by declaring Integer an alias of int.ref. Users will not
have this ability (for now).
3. Are there plans for the (distant) future to bring primitive
aliasing capabilities to the user space as well?
For example, the following fictitious syntax would make the change above
semantically compatible:
primitive class point ref-alias Point {...}
Tim
More information about the valhalla-dev
mailing list