In the post "JVM Language Summit 2018 and Valhalla EA Build 0", I mentioned that Project Valhalla's "L-World Value Types" Early-Access Builds are now available for Linux/x64, macOS/x64, and Windows/x64. Specifically, "Build 0 (2018/7/30)" is available for download as a "convenience." In that same post, I also mentioned that the JVM Language Summit 2018 had just wrapped up and I provided a link to one of that event's presentations: "LWorld: the next steps on the journey to Valhalla". In this post, I use code based on the Project Valhalla "L-World Value Types" Early-Access Build 0 to illustrate some of the points made in the JVM Language Summit 2018 presentation on early versions of L-World.
CAUTION: The build discussed in this post is "intended for expert users interested in Project Valhalla", is NOT intended for production, and has severe limitations and disclaimers associated with it. This build is primarily intended for those who want to "play" with L-World value types and not for other more general uses. In announcing this build on the valhalla-dev OpenJDK mailing list, David Simms described this Build 0 as follows:
"The first truly usable value type prototype" with experimental language support. Based on JDK mainline, almost complete JDK 11. This is build "0", there are bugs, performance issues, and usability issues.
The following code listing (including the __ByValue
) compiles against the L-World Value Types Early Access Build 0:
package dustin.examples.valhalla; public final __ByValue class DoubleComplex { public final double real; public final double imaginary; public DoubleComplex(final double newReal, final double newImaginary) { this.real = newReal; this.imaginary = newImaginary; } }
The L-World Value Types Early Access Build 0 javac compiler adds some methods to the DoubleComplex
class shown above beyond those added by the compiler in other versions of Java. These are perhaps most easily identified by running javap against the generated class.
As the above screen snapshot demonstrates, javap
tells us that several methods were added to the DoubleComplex.class
class file generated from the DoubleComplex.java
source file by the L-World Value Types Early Access Build 0 javac
compiler:
Compiled from "DoubleComplex.java" public final value class dustin.examples.valhalla.DoubleComplex { public final double real; public final double imaginary; public dustin.examples.valhalla.DoubleComplex(double, double); public final int hashCode(); public final boolean equals(java.lang.Object); public final java.lang.String toString(); public final long longHashCode(); public static dustin.examples.valhalla.DoubleComplex $makeValue$(double, double); }
Normally, we'd only expect the javap
output of a .class
file generated from the .java
file shown above to include the two fields and the constructor that are present in the source Java file. However, the L-World Value Types Early Access Build 0 javac
compiler generated a .class
file with a hashCode()
implementation, an equals(Object)
implementation, a toString()
implementation, a longHashCode() implementation (that returns long
instead of the int
returned by standard hashCode()
), and a mysterious-looking static method $makeValue$
because of the __ByValue
reference in the source code. I wasn't able to get __MakeValue
to work for me in creating an instance of this value type, but I will demonstrate the other added methods in this generated class file.
I will show some output of these methods generated on value type DoubleComplex
that were not explicitly specified in the Java source code file. For these output examples, the following three instances of the DoubleComplex
will be used:
private final static DoubleComplex complex1 = new DoubleComplex(15.0, 25.0); private final static DoubleComplex complex2 = new DoubleComplex(25.0, 35.0); private final static DoubleComplex complex3 = new DoubleComplex(25.0, 35.0);
The second and third instances (complex2
and complex3
) have the same values and the complex1
instance has different values. Based on these instances, the methods added to ComplexDemo
by the L-World Value Types EA Build 0 javac
compiler generate results that look like the following:
Examples of Methods Added to Value Type) | |
---|---|
Method Added to Value Type | Results for Instances of DoubleComplex Value Type(methods' output in bold |
toString() |
[value class dustin.examples.valhalla.DoubleComplex, 15.0, 25.0] [value class dustin.examples.valhalla.DoubleComplex, 25.0, 35.0] [value class dustin.examples.valhalla.DoubleComplex, 25.0, 35.0] |
equals(Object) |
Comparing [value class dustin.examples.valhalla.DoubleComplex, 15.0, 25.0] to [value class dustin.examples.valhalla.DoubleComplex, 25.0, 35.0]: false Comparing [value class dustin.examples.valhalla.DoubleComplex, 25.0, 35.0] to [value class dustin.examples.valhalla.DoubleComplex, 25.0, 35.0]: true |
hashCode() |
Complex1.hashCode(): -478263309 Complex2.hashCode(): -455358477 Complex3.hashCode(): -455358477 |
longHashCode() |
Complex1.longHashCode(): 1610134472691 Complex2.longHashCode(): 1610157377523 Complex3.longHashCode(): 1610157377523 |
The table above demonstrates that reasonable implementations of toString(), equals(Object), and hashCode() are provided by default for Java value types compiled with the L-World Value Types Early Access Build 0.
To run code that used my value type, I needed to use the flag -XX:+EnableValhalla
in addition to specifying the JVM flag --enable-preview
. If I failed to supply the -XX:+EnableValhalla
flag to the L-World Value Types Early Access Build 0 java launcher, I was presented with the error message
Exception in thread "main" java.lang.ClassFormatError: Class modifier ACC_VALUE in class dustin/examples/valhalla/DoubleComplex requires option -XX:+EnableValhalla
Things You Cannot Do with Value Types in L-World Value Types EA Build 0
There are some interesting things you cannot do with the value types created with L-World Value Types Early Access Build 0 (several of these are intentional and likely to not be changed):
- Compare two value types with
==
- Compile-time error: "error: value types do not support =="
- Pass value type to System.identityHashCode(Object)
- Compile-time error: "error: value types do not support identityHashCode"
- Synchronize on a value type
- Compile-time error:
error: unexpected type synchronized (complex1) ^ required: reference found: DoubleComplex
- Compile-time error:
- Value Type cannot extend another class
- Compile-time error: "error: value type may not extend another value or class"
Class.isValue()
Although I don't demonstrate it here, there is a method available on the java.lang.Class class with this L-World Value Types Early Access Build 0 that indicates whether the class is a value type class or not. The method, Class.isValue()
, returns true
if the class is a value type class or false
if it is NOT a value type class.
The isValue()
method also appears to throw InternalErrors if it is called upon a class that is internally labeled a value type but whose Modifiers indicate it is also an interface, an abstract class, or extends a class other than Object. This implies, of course, that a value type class cannot be declared abstract
("error: illegal combination of modifiers: abstract and final" or "error: illegal combination of modifiers: abstract and value") or be an interface ("error: illegal combination of modifiers: interface and value").
L-World's Future
Although significant progress has been made in Project Valhalla related to Value Types, there is still much work to come. The JVM Language Summit presentation I cited earlier ends with discussion about "L-World major milestones" in the slides titled "L-World Roadmap." These slides and the speakers discuss major milestones "LW1", "LW10", and "LW100" and the features and characteristics expected for each of these major milestones. There will, of course, be milestones between those numbers as well. The availability of L-World Value Types Early Access Build 0 provides a convenient mechanism for interested parties to start playing with L-World value types.
6 comments:
Nice, just found your blog and posts are really up-to-date with the JDK and interesting! Good job.
Do you think value types will be out for JDK 12?
Hello Edoardo,
Although much work has been put into value types, they still have a long way to go, so I think it's highly unlikely we'll see them in JDK 12.
Dustin
Doug Lea has posted "Value type sorting" in which he discusses applying various sorting algorithms to value types and provides links to examples based on the Valhalla L-World Early Access Build 0 referenced in my blog post.
Is the case class construction suitable as a replacement for the final __ByValue class syntax?
See Uberto Barbini's post "A Taste of Value Types" for a detailed look at how to download and apply the Valhalla Early Access Build.
A new Valhalla Early Access Build [Build jdk-14-valhalla+1-8 (2019/7/4)] is available for the LW2 prototype ("inline classes"). I have posted on Valhalla LW2 inline types and using this new early access build in the posts "Valhalla LW2 Progress - Inline Types" and "Project Valhalla: A First Look at LW2 Inline Types".
Post a Comment