https://docs.oracle.com/en/java/javase/16/index.html
https://docs.oracle.com/en/java/javase/
JDK 16 is the open-source reference implementation of version 16 of the Java SE Platform, as specified by by JSR 390 in the Java Community Process.
JDK 16 reached General Availability on 16 March 2021. Production-ready binaries under the GPL are available from Oracle; binaries from other vendors will follow shortly.
The features and schedule of this release were proposed and tracked via the JEP Process, as amended by the JEP 2.0 proposal. The release was produced using the JDK Release Process (JEP 3).
As mentioned at the very beginning of this guide: Essentially all (don’t be picky now) Java 8 language features work in Java 13. The same goes for all other Java versions in between.
In turn, this means that all language features from Java 8 serve as a good Java base knowledge, and everything else (Java 9-13) is pretty much additional features on top of that baseline.
Here’s a quick overview of what specific versions have to offer:
Java 8 was a massive release and you can find a list of all features at the Oracle website. There’s two main feature sets I’d like to mention here:
Language Features: Lambdas, etc.
Before Java 8, whenever you wanted to instantiate, for example, a new Runnable, you had to write an anonymous inner class, like so:
Runnable runnable = new Runnable(){
@Override
public void run(){
System.out.println("Hello world !");
}
};
You also got method references, repeating annotations, default methods for interfaces, and a few other language features.
Collections & Streams
In Java 8, you also got functional-style operations for collections, also known as the Stream API. A quick example:
List<String> list = Arrays.asList("franz", "ferdinand", "fiel", "vom", "pferd");
Now, pre-Java 8, you basically had to write for-loops to do something with that list.
With the Streams API, you can do the following:
list.stream()
.filter(name -> name.startsWith("f"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
Java 9 also was a fairly big release, with a couple of additions:
Collections
Collections got a couple of new helper methods to easily construct Lists, Sets, and Maps.
List<String> list = List.of("one", "two", "three");
Set<String> set = Set.of("one", "two", "three");
Map<String, String> map = Map.of("foo", "one", "bar", "two")
Streams
Streams got a couple of additions, in the form of takeWhile, dropWhile, and iterate methods.
Stream<String> stream = Stream.iterate("", s -> s + "s")
.takeWhile(s -> s.length() < 10);
Optionals
Optionals got the sorely missed ifPresentOrElse method.
user.ifPresentOrElse(this::displayAccount, this::displayLogin);
Interfaces
Interfaces got private methods:
public interface MyInterface {
private static void myPrivateMethod(){
System.out.println("Yay, I am private!");
}
}
Other Language Features
And a couple of other improvements, like an improved try-with-resources statement or diamond operator extensions.
JShell
Finally, Java got a shell where you can try out simple commands and get immediate results.
% jshell
| Welcome to JShell -- Version 9
| For an introduction type: /help intro
jshell> int x = 10
x ==> 10
HTTPClient
Java 9 brought the initial preview version of a new HttpClient. Up until then, Java’s built-in Http support was rather low-level, and you had to fall back on using third-party libraries like Apache HttpClient or OkHttp (which are great libraries, btw!).
With Java 9, Java got its own, modern client — although this is in preview mode, which means that it is subject to change in later Java versions.
Project Jigsaw: Java Modules and Multi-Release Jar Files
Java 9 got the Jigsaw Module System, which somewhat resembles the good old OSGI specification. It is not in the scope of this guide to go into full detail on Jigsaw, but have a look at the previous links to learn more.
Multi-Release .jar files made it possible to have one .jar file which contains different classes for different JVM versions. So, your program can behave differently/have different classes used when run on Java 8 vs. Java 10, for example.
There have been a few changes to Java 10, like garbage collection, etc. But the only real change you as a developer will likely see is the introduction of the var keyword, also called local-variable type inference.
Local-Variable Type Inference: var-keyword
// Pre-Java 10
String myName = "Marco";
// With Java 10
var myName = "Marco"
Feels Javascript-y, doesn’t it? It is still strongly typed, though, and only applies to variables inside methods (thanks, dpash, for pointing that out again).
Java 11 was also a somewhat smaller release, from a developer perspective.
Strings & Files
Strings and files got a couple of new methods (not all listed here):
"Marco".isBlank();
"Mar\nco".lines();
"Marco ".strip();
Path path = Files.writeString(Files.createTempFile("helloworld", ".txt"), "Hi, my name is!");
String s = Files.readString(path);
Run Source Files
Starting with Java 10, you can run Java source files without having to compile them first. A step towards scripting.
ubuntu@DESKTOP-168M0IF:~$ java MyScript.java
Local-Variable Type Inference (var) for Lambda Parameters
The header says it all:
(var firstName, var lastName) -> firstName + lastName
HttpClient
The HttpClient from Java 9 in its final, non-preview version.
Other Goodies
Flight Recorder, No-Op Garbage Collector, Nashorn-Javascript-Engine deprecated, etc.
Java 12 got a couple of new features and clean-ups, but the only ones worth mentioning here are Unicode 11 support and a preview of the new switch expression, which you will see covered in the next section.
You can find a complete feature list here, but essentially, you are getting Unicode 12.1 support, as well as two new or improved preview features (subject to change in the future):
Switch Expression (Preview)
Switch expressions can now return a value. And you can use a lambda-style syntax for your expressions, without the fall-through/break issues:
Old switch statements looked like this:
switch(status) {
case SUBSCRIBER:
// code block
break;
case FREE_TRIAL:
// code block
break;
default:
// code block
}
Whereas with Java 13, switch statements can look like this:
boolean result = switch (status) {
case SUBSCRIBER -> true;
case FREE_TRIAL -> false;
default -> throw new IllegalArgumentException("something is murky!");
};
Multiline Strings (Preview)
You can finally do this in Java:
String htmlBeforeJava13 = "<html>\n" +
" <body>\n" +
" <p>Hello, world</p>\n" +
" </body>\n" +
"</html>\n";
String htmlWithJava13 = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
Will be covered here, as soon as they are getting released. Check back soon!
By now, you should have a pretty good overview of a couple of things:
How to install Java, which version to get, and where to get it from (hint: AdoptOpenJDK).
What a Java distribution is, which ones exist, and what are the differences.
What are the differences between specific Java versions.
Feedback, corrections, and random input are always welcome! Simply leave a comment down below.
Thanks for reading!