Java 14 was released on March 17th 2020 with some interesting new features added to the language – notably the finalization of switch expression enhancements, which leads to addition of the yield keyword. Another cool stuff is that, JDK 14 comes with a new packaging tool called jpackage– allows programmers to create native installer for Java applications.

And like previous Java releases, performance for the Java Virtual Machine (JVM) is continuously improved with several updates for garbage collectors. Among that, something is deprecated for removal in future as well as some other things are actually removed in JDK 14.

Table of content:

1. New Language Features in Java 14

2. Updates for Tools and APIs in Java 14

3. JVM Performance Improvements in JDK 14

4. What’s Deprecated in JDK 14

5. What’s Removed in JDK 14

Now, let’s dive into the details for what’s new, deprecated in removed in Java 14.

 

1. New Language Features in Java 14

Enhancements for switch expressions become standard, whilst Text blocks, Records and Pattern matching for instanceof are still in preview.

Switch Expression Enhancements:

The switch-case expression in Java is well-known for its verbosity for multiple-case fall through. Consider the following method:

public void dayOfMonth(int month) {
	switch (month) {
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:
		case 12:
			System.out.println("this month has 31 days");
			break;
		case 2:
			System.out.println("this month has 28 or 29 days");
			break;
		case 4:
		case 6:
		case 9:
		case 11:
			System.out.println("this month has 30 days");
			break;
		default:
			System.out.println("invalid month number");
	}
}

This is clearly very verbose. Now with Java 14’s enhancements for switch expression, we can rewrite this method as follows:

public static void dayOfMonth(int month) {
	switch (month) {
		case 1, 3, 5, 7, 8, 10, 12 -> System.out.println("this month has 31 days");

		case 4, 6, 9, 11 -> System.out.println("this month has 30 days");

		case 2 -> System.out.println("this month probably has 28 days");

		default -> System.out.println("invalid month number");
	}
}

You see, it’s much clearer and more readable, isn’t it?

Moreover, the switch block can return a value to be used in an expression like this:

int days = switch(month) {
	case 1, 3, 5, 7, 8, 10, 12 -> 31;

	case 4, 6, 9, 11 -> 30;

	case 2 -> 28;

	default -> 0;
};

If the code in a case is a block, we can use the yield keyword to return the value, for example:

int days = switch(month) {
	case 1, 3, 5, 7, 8, 10, 12 -> 31;

	case 4, 6, 9, 11 -> 30;

	case 2 -> {
		System.out.print("Enter year: ");
		Scanner scanner = new Scanner(System.in);
		int year = scanner.nextInt();

		if (year % 4 == 0)
			yield 29;
		else
			yield 28;
	}

	default -> 0;
};

So, since Java 14, yield becomes the keyword used in switch expression to return a value. Read the JDK Enhancement Proposal JEP 361 that covers the full detailed of enhancements for switch expression.

For more code examples with detailed explanation, read this post Java 14: Switch Expressions Enhancements Examples.

 

Text Blocks (preview):

This feature allows programmers to write lengthy String literals in a way that is more readable and effortlessly. Consider the following String literal:

String html = "<html>\n" +
		"    <head>\n" +
		"        <title>Homepage</title>\n" +
		"    </head>\n" +
		"    <body>\n" +
		"        <h1>This is the homepage</h1>\n" +
		"    </body>\n" +
		"</html>\n";

From Java 14, you can rewrite this String literal as follows:

String html = """
	  <html>
	      <head>
		  <title>Homepage</title>
		  </head>
		  <body>
			  <h1>This is the homepage</h1>
		  </body>
	  </html>
	  """;

You see, it looks much more naturally, right? A text bock starts with 3 double quotes follow by a new line character, and ends with 3 double quotes.

With text block, you don’t have to escape special characters like new lines or double quotes. Note that the Java compiler will automatically trim the leading spaces in a text block, making it more convenient for programmers.

Read the JEP 368 that describes text block in full details.

Update: Text blocks become a standard feature in JDK 15. Learn more: Understand Text Blocks Feature in Java 15?

 

Records (preview):

Records are a new kind of type declaration in the Java language. It simplifies the coding of classes that merely act as “data carrier” i.e. domain classes or POJO classes. Consider the following class:

public class Book {
	private String title;
	private String author;

	public Book(String title, String author) {
		this.title = title;
		this.author = author;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getTitle() {
		return this.title;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public String getAuthor() {
		return this.author;
	}
} 

Now, with the new record type, you can simply write:

record Book (String title, String author) { }

Then the Java compiler will automatically generate appropriate fields, constructor, getter and setter methods. In addition, a record also implements equals(), hashCode() and toString() methods implicitly.

Read the JEP 359 for more information about Records features.

 

Pattern matching for instanceof operator (preview):

Another new feature was proposed for the Java language is enhancement for the use of instanceof operator. Consider a very familiar use case below:

if (obj instanceof String) {
	String s = (String) obj;
	// use s
}

Here, the statement that casts the obj object to a type of String is somewhat verbose because when the if statement evaluates to true, the type of the object is indeed String. Now with Java 14, we can improve the instanceof statement as follows:

if (obj instanceof String s) {
	// we use s directly here
}

As you can see, it eliminates the verbose cast statement. More advanced, we can add expression to the right like this:

if (obj instanceof String s && s.length() > 5) {
	// use String s if its length > 5
}

This would make the use of instanceof operator more flexible and concise. Read the JEP 305 that covers the greater details of pattern matching for instanceof.

Note that the preview features require the switches --enable-preview and --source 14 when compiling and running. Preview features need further feedback and improvements until they become finalized in future releases of JDK. 

 

2. Updates for Tools and APIs in Java 14

Another interesting feature in JDK 14 is the introduction of a new packaging tool, among some updates for JDK APIs.

New Packaging Tool (Incubator)

JDK 14 shipped with jpackage tool that allows programmers to package a Java application into platform-specific package that includes all of the necessary dependencies. This tool will generate installer program for your Java application in native formats: msi and exe on Windows, pkg and dmg on macOS, and deb and rpm on Linux.

I’ve experimented this tool for creating a Windows installer for my Java application, using this command:

jpackage --name CodeJavaForm --input dist --main-jar GUIFormExamples.jar 
--main-class examples.ContactEditor --type msi 
--win-dir-chooser --win-menu --win-shortcut

And I got a nice installer program that looks like this:

jpackage setup win

So I think for the first time in history, programmers can create native installer programs for their Java applications with ease. Read the JEP 343 for more information about packaging tool in JDK 14.

 

Java IO: Non-Volatile Mapped Byte Buffers

This update adds new JDK-specific file mapping modes so that the FileChannel API can be used to create MappedByteBuffer instances that refer to non-volatile memory. Check the JEP 352 for details.

 

Helpful NullPointerExceptions

Perhaps, NullPointerException is the most well-known error in Java programming. However, the way which the JVM reports NullPointerException is ambiguous in non-trivial cases. Given two classes A and B as follows:

class A { int i; }
class B { int j; } 

And a statement that uses object references of A and B like this:

a.i = b.j;

If NullPointerException throws at this line, JVM will terminate with the following error message: 

Exception in thread "main" java.lang.NullPointerException
        at MyProgram.test(MyProgram.java:14)
        at MyProgram.main(MyProgram.java:6)

It points exactly the line where the exception occurred. But wait, which variable is null in this case, a or b??? So programmers have to debug the program or write some checking code to know which a or b is null.

The good news is, JDK 14 now computes the null-detail message to help programmers quickly and exactly identify which variable is null. To enable null-detail message, we must specify the following switch when running Java program:

java -XX:+ShowCodeDetailsInExceptionMessages MyProgram

Then JVM will produce more meaningful error message like this:

Exception in thread "main" java.lang.NullPointerException: Cannot assign field "i" because "this.a" is null
        at MyProgram.test(MyProgram.java:14)
        at MyProgram.main(MyProgram.java:6)

I think this is a cool feature that saves programmer’s time in debugging their code. Read the JEP 358 for more details.

 

Foreign-Memory Access API (Incubator)

This feature introduces an API to allow Java programs to safely and efficiently access foreign memory outside of the Java heap. These three interfaces are introduced: MemorySegment, MemoryAddress and MemoryLayout. Read the JEP 370 for greater details.

 

Java Flight Recorder (JFR) Event Streaming

For better consumption of data generated by the Java Flight Recorder (JFR), JDK 14 introduces an API that allows Java programs to subscribe to JFR’s data events asynchronously, for continuous monitoring of the Java Virtual Machine. Read the JEP 349 for more information about this feature.

 

3. JVM Performance Improvements in JDK 14

JVM performance is continued to be improved in this release. The Garbage First (G1) collector performance is improved by implementing the NUMA-aware memory allocation. NUMA stands for Non-Uniform Memory Access – a modern memory architecture on multi-processor machines.

In addition, the Z Garbage Collector (ZGC) is now available for macOS and Windows operating systems - but in experimental phase. ZGC is a scalable low latency garbage collector since JDK 11.

 

4. What’s Deprecated in JDK 14

JDK 14 deprecates the two garbage collection algorithms, namely Parallel Scavenge and Serial Old because they are very little used but requires a significant amount of maintenance effort.

JDK 14 also deprecates ports to Solaris/SPARC, Solaris/x64, and Linux/SPARC – which means there will be no JDK builds for Solaris operating system running on SPARC and x64 architecture, and no JDK builds for Linux operating system running on SPARC architecture.

 

5. What’s Removed in JDK 14

JDK 14 removes the Concurrent Mark Sweep (CMS) garbage collector. CMS has been intented to be replaced by G1 since JDK 6. That also allows the JDK development team to focus on ZGC and Shenandoah garbage collectors.

JDK 14 also removes the pack200 and unpack200 tools, and the Pack200 API in the java.util.jar package. These tools and API were used by developers to compress and uncompress their JAR files – but the major consumer of Pack200 – the JDK itself – no longer needs it.

To help you easily understand how to use new language features in Java 14, I've also published the following video. Watch it now:

 

References:

 

You may be also interested in:


About the Author:

is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.



Add comment

   


Comments 

#2SACHIN RAI2020-12-13 14:31
I want support 404, found
Quote
#1kimi2020-04-11 03:26
Very interesting i like it.
Quote