With the latest version of your favorite programming language just around the corner, it’s time to get ahead of the curve and figure out if updating is worthwhile. In this article, we’ll take a look at what’s being added to Java that will have an immediate impact on how you write code and the overall performance of your applications.
Java 11 Installation
Obviously, you’ll need to get JDK installed on your machine first. Just head to the early-access builds page and choose the appropriate version for your OS,, specifically, whether you want the OpenJDK or Oracle JDK build.
We need to wait until September for the official release of Java 11, but, if you’re lucky, your IDE might just support it. I updated my version of IntelliJ IDEA 2018.6 so that I could use Java 11 features. It looks like the latest Eclipse Photon doesn’t support Java 11 yet, but that will probably be included in the next quarterly update. And, there’s always the command line!
Language and API Updates
Local-Variable Syntax for Lambda Parameters
Java 10 brought about var
for local variables, but there was a limitation and you could not use these in lambda expressions. Effectively, you can have this:
var numbers = new int[]{1, 2, 3, 4, 5, 6, 7};
int[] subset = Arrays.stream(numbers).filter(( var a) -> a > 5).toArray();
for(int i = 0; i < subset.length; i++){
System.out.println(subset[i]);
}
However, you might remember that Java 8 allows you to remove type information so that var
isn’t always necessary. What it does give you is uniformity with local variables, and, more importantly, it allows you to add annotations to the parameters like @Nonnull
or @Nullable
.
HTTP Client
The HTTP client was introduced in Java 9 as an incubation feature. It was updated in Java 10, and, now, it has finally reached maturity. As such, the incubated API is removed, and you’ll get access to the standard API now in java.net.http, which you can think of as a complete rewrite, making the client non-blocking and bringing in RX flow concepts.
Unicode 10
There will be updates to the platform to ensure support with Unicode 10, which add to 8,518 characters, 56 of which are new emojis!
Security
Key Agreement With Curve25519 and Curve448
The existing elliptic curve key agreement is a native C implementation, but this implementation of RFC 7748 gives a pure Java implementation that is platform independent, which results in better performance and security.
Transport Layer Security (TLS) 1.3
TLS 1.3 adds many security and performance improvements over previous versions. There are no new public APIs for this, and it really just helps the language to stay relevant and up-to-date.
ChaCha20 and Poly1305 Cryptographic Algorithms
Implementation of the ChaCha20 and ChaCha20-Poly1305 ciphers are specified in RFC 7539. In general, this is cheaper to run on CPUs in comparison to AES and is widely used in TLS.
Tooling
Launch Single-File Source-Code Programs
This is an excellent addition to the JVM for those who are learning the language. This allows you to execute your Java source file from the command line using java HelloWorld.java
. This might sound small, but it means that you save yourself from needing to first compile the file using javac and then run it using Java — two steps become one.
What’s more — any arguments placed after the file name are treated as arguments for the class, allowing commands such as java Factorial.java 3 4 5
.
Flight Recorder
Instead of using third-party tools, this JEP provides a data collection for helping to troubleshoot Java applications with APIs for producing and consuming data as events. While event-based JVM tracing has been around for a while, now, events can be created in Java.
So, if you want to create an event, you can do so by first extending the jdk.jfr.Event
class.
"Hello World") (
"Helps the programmer getting started") (
class HelloWorld extends Event {
"Message") (
String message;
}
Then, the event can be committed during the program execution:
public static void main(String... args) throws IOException {
HelloWorld event = new HelloWorld();
event.message = "hello, world!";
event.commit();
}
Low-Overhead Heap Profiling
Profiling is a big deal, and understanding what’s going on in the heap is essential. In order to get more detail from you heap allocations, this JEP adds to the JVM Tool Interface (JVM TI) with heap profiling extensions.
ZGC: A Scalable Low-Latency Garbage Collector
This is an experimental garbage collection that reduces the length of pauses. Note that this feature will only work on Linux/x64 for the moment. If it goes well, this could be a huge boost to Java application performance.
Epsilon: A No-Op Garbage Collector
This might seem like a strange one in the face of it, because you’ve got a garbage collector that doesn’t do any garbage collection. Without the reclamation of memory, once you reach the limits of the Java heap, the JVM exits. Why would you want this? Well, if you want to create your own GC, it would provide a good reference implementation to start. It also has some benefits for performance testing and memory pressure testing. It’s doubtful that you’ll rush to try this out, but it’s there if you ever want to see what would happen!
Under The Hood Stuff
Apart from these language-level changes, you’ll find other new features listed on the JDK 11 page that relate more to how the JVM works under the hood. It is unlikely that these items will actually affect you, but knowing about them can't hurt.
- Nest-Based Access Control — The “nest mates” concept is simple enough. If you nest multiple classes inside another, they can access each other's private data. This addition means that there’s no need for compiler magic (access bridges) to allow this to happen.
- Dynamic Class-File Constants — This is an extension of the Java class-file format to support a new constant-pool form, including one for language designers and those implementing compilers.
- Improve Aarch64 Intrinsics — This will provide performance improvements for string and arrays, as well as standard Math.sin, cos and log functions. It’s all under the hood, but you might see changes without making any code changes. And, it is faster. This little code example runs at about 100 milliseconds on Java 8, while running at half that time on average with JDK 11 public static void main(String... args) { long start = System.currentTimeMillis(); for(int i = 0; i < 1000000; i++){ Math.sin((double) i); Math.cos((double) i); Math.log((double) i); } long end = System.currentTimeMillis(); System.out.println(" Took " + (end-start) + " milliseconds"); }
- Removal of Java EE and CORBA Modules — These were marked for deprecation in Java 9, and rather than hanging onto them, they are now gone!