Java 16 Is Coming!
nipafx news #81–6th of December 2020
Hi everyone,
in a few days (on the 10th) Java 16 will be forked from the main line (think of it like creating a release branch) and after that, only bug fixes will make it into the new release. That means it’s a good time to see what we’ll get. In this newsletter, I’ll do that by highlighting the various projects and how they’re moving along.
I send this newsletter out some Sundays. Or other days. Sometimes not for weeks. But as an actual email. So, subscribe!
Project Amber
The biggest news still come from Project Amber. For Java 16, it progresses the three preview features it currently has in the race.
Pattern Matching
Pattern matching for instanceof
gets finalized with two small changes:
- pattern variables are no longer required to be effectively final
- pattern matching against a super type is a compile error (because it is meaningless and thus likely a developer mistake)
As an example for the latter:
// if Tiger extends/implements Animal,
// this is a compile error
if (tiger instanceof Animal animal)
// ...
Records
Records are also finalized (yay!) without changes compared to Java 15. But they prompted a different change that is quite interesting: Inner (i.e. non-static nested) classes can now contain static members. So the two lines with static
no longer cause compile errors:
public class OuterClass { public class InnerClass { static final String DATE =
LocalDateTime.now().toString(); static String date() {
return DATE;
} }}
That means records, which are always static, can now be a member of an inner class. So, outer class with inner class with inner record — a Matryoshka doll situation that I wouldn’t exactly recommend.
Sealed Classes
Last, but not least, sealed classes get another round on the preview-track. The changes over Java 15 are JLS-edits and edge case handling that I’ll leave for interested readers to explore in the JEP.
Project Valhalla
With Amber taking much of the spotlight, it has been pretty quiet around Project Valhalla lately. I didn’t have time to check the mailing lists either, but it appears to be chugging along. In Java 16, it prepares the important step of removing the performance penalty of primitive wrapper classes like Integer
and Float
.
It does that by designating them as value-based classes, which tells developers that they should not do any identity-sensitive operations on them. If we don’t, the JVM is free to play fast and loose with their identity, meaning it can destroy and recreate instances as it sees fit, which gives it a lot of leeway to optimize performance.
Classic identity-based operations are construction (because unlike a static factory method, a constructor always gives you a new instance) and synchronization (because you want to be sure not to also lock equal-but-not-same instances). Consequently, Java 16 will issue compiler warnings when you use new
or synchronized
with such classes. Or at least it will once JEP 390 is targeted to 16, but I assume it will soon.
In case you’re wondering, String
is not part of this change. Even though it would make a great value-based class, it's "hopelessly polluted with identity-sensitive uses" (to quote Brian Goetz).
To mass-replace new Integer
with Integer.valueOf
in your code, check these tweets - take the described process to heart, but focus on using the tools recommended in the replies.
Project Jigsaw
Hah, I bet you didn’t expect to hear from Jigsaw again, did you?! I hope you paid attention over the last years, though, because the noose is tightening (to make the metaphor more positive, imagine the noose is made of flowers).
The module system strongly encapsulates internal APIs, but to aid migration of otherwise incompatible code, Java 9 made an exception: Code that was compiled against Java 8 or lower could access JDK-internal APIs that already existed in Java 8. This behavior could be configured with the command line flag --illegal-access
, which had four values:
permit
: warning on first reflective access to a packagewarn
: warning on each reflective accessdebug
: likewarn
plus stack tracedeny
: illegal access denied (static + reflective)
Since Java 9, permit
was the default, but in Java 16 this changes to deny
. That means you either:
- don’t have any code or dependencies that use internal APIs
- use
--add-exports
or--add-opens
to configure specific exceptions - use
--illegal-access=permit
to configure a blanket exception
This is also the order from most to least maintainable. Take note that a future change will remove --illegal-access
entirely (not based on anything specific I guess it will happen in Java 21/22) and to prepare you, using the flag in Java 16+ will yield a warning (it didnt yet in my tests, though).
NB: This does not touch on the existence of the jdk.unsupported module and its export of sun.misc.Unsafe
.
Project Panama
Project Panama deals with calls into non-Java, foreign memory, etc. and lies squarely out of my comfort zone (I can’t even write C/C++), so I’ll keep it short. Panama has currently three incubating APIs and in Java 16, they’re all incubating a bit more:
Project Everything Else
Not really a project, but here’s what else happened.
APIs were improved:
Performance was improved:
- ZGC: Concurrent Thread-Stack Processing
- Elastic Metaspace
- better handling of weak references and load spikes in Shenandoah
- probably more that I missed
New ports were ported:
The move to GitHub was finalized:
Misc:
Java Advent
If you’re interested to see where these (and other) Java projects are going, I recommend to keep an eye on the The JVM Programming Advent Calendar. There has already been a post on Project Loom and my post, scheduled for December 10th, will give you an overview over all of them. Here’s a sneak preview of the intro:
Java 2077
(Imagine a desolate urban area. Smoke rising from the rubble, worn-down people hiding in collapsed buildings. Text appearing on the screen, read with a raspy voice.)
The year is 2077.
The Java version is 128. It doesn’t have long-term support.
We were worried about climate change. Global pandemics. Antibiotic-resistant bacteria. Rougue AI. In the end all of that happened, but it was the Java wars that really did us in. Well, they’re still doing us in.
Nobody recalls how it all started. Some say it was MongoDB blowing up Amazon headquarters over their use of their Open Source Java driver. Others claim it was Google vs Oracle. Nobody believes Microsoft was innocent and don’t get me started on Alibaba. The guilty are legion, but after 50 years, most names are lost to time.
What remains are the killer robots. And they run on Java 128.0.2. We’ve tried everything to shut them down…
I’m thinking on publishing a dramatic reading on YouTube. :D
If the 2077 caught your eye, yes, it’s because of Cyberpunk 2077. Release is also on the 10th (coincidence?) and I’m hurrying to get everything done by then, so I can play at least all through the weekend. Why not join me on Twitch?
And that’s all about Java 16 for now. Stay healthy and I’ll see you around!
so long … Nicolai
PS: Don’t forget to subscribe or recommend! :)
