1. Features in Java 17 (JDK 17)
Mutlu Okuducu/ Software Developer
Programmers typically target a specific, long-term support (LTS)
release when they develop applications. That means for the past
2. several years, most Java developers were limited to the Java 8 or Java
11 feature set.
The newest long-term support release for the Java SE platform is Java
17 LTS. Under the Oracle No-Fee Terms and Conditions License, JDK
17 binaries are free to use in production and redistribute at no cost.
LTS stands for long-term support. It will be available on September
15, 2021.
Several improvements in these Java 17 features will make enterprise
software development much easier.
Spring Boot 3.0 is now generally available. The new release is
based on Spring Framework 6.0 and requires Java 17.
Top 5 Java 17 features that developers
will love.
The new Java Record data type (JDK 14)
Java text blocks (JDK 14)
Helpful NullPointerException guidance (JDK 14)
Pattern Matching for Switch (Preview)
Sealed classes
Enhanced Pseudo-Random Number Generator
•
1.
2.
3.
4.
5.
6.
3. 1-The new Java Record data type;
Records:
Records focus on certain domain classes whose purpose is only to
store data in fields. A new class called record is a final class, not
abstract, and all of its fields are final as well. The record will
automatically generate the constructors , getters , equals() ,
hashCode() and toString() during compile-time and it can
implements interfaces.
Restrictions:
A record is a final class
A record cannot extend a class
The value (reference) of a field is final and cannot be changed
A record class is an immutable
A record can not setters
•
•
•
•
•
public record Transaction(int id, double amount,
}
/*
---- * You can use JShell with the flag --enable
Automatically generate:
4. You can find the code, records.
2- Java text blocks;
In Java, embedding HTML, XML, SQL, TEXT BLOCK or JSON snippets
into code is often hard to read and hard to keep, and to overcome
this problem, Java 14 has introduced Text Block. A text block
contains zero or more content characters enclosed by open and
closed delimiters.
The text block starts and ends with three quotation marks each. The
following rules apply:
* constructors
* getters
* equals()
* hashCode()
* toString()
*/
//You can use Transaction like any regular class
Transaction trans = new Transaction(5, 100, "Pay
int amount= trans.amount();
int description= trans.description();
5. Text block using three double-quote characters
newlines (line-terminator) denoted by
for white space (single space) denoted by /s
string format for a parameter using %s
You do not need to escape single or double quotes within the
text block, but you may (though SCA tools such as SonarLint
recommend not doing so).
•
•
•
•
•
String text = """"""; // illegal text block star
String text = """ """; // illegal text block sta
String text = """
"""; // legal text block
// Text block//Without Text Block HTML
String html = "<html>n" +
" <body>n" +
" <p>Hello, world</p>n" +
" </body>n" +
"</html>n";
System.out.println(html);
// Text Block HTML
String htmlTag = """
<html>
<body>
<p>Hello, world</p>
</body>
6. </html>
""";
// Text Block multi line (paragraph)
String text = """
two escape sequences first is fo
and, second is to signify white
or single space.
""";
// Text Block SQL Query
String query1 = """
SELECT `EMP_ID`, `LAST_NAME`
WHERE `CITY` = 'INDIANAPOLIS'
ORDER BY `EMP_ID`, `LAST_NAME
""";
// Text Block JSON Example
String json= """
{
"amount": {
"currency": "string",
"value": 0
},
"creditorAccount": {
"accountName": "string",
"accountNumber": "string",
"sortCode": "string"
},
"debtorAccount": {
"accountName": "string",
"accountNumber": "string",
"sortCode": "string"
},
"paymentDate": "string",
8. You can find the code, textsblocks.
3- Helpful NullPointerException guidance;
NullPointerExceptions cause frustrations because they often appear
in application logs when code is running in a production
environment, which can make debugging difficult. After all, the
original code is not readily available. For example, consider the code
below:
Before Java 14, you might get the following error:
Exception in thread
</body>
</html>
""".formatted("Hello3", "Java 14");
Account account =new Account();
String accountNumber=account.getAmount().getCur
System.out.println(accountNumber.length());
9. “main” java.lang.NullPointerException
com.java14features.nullpointerexception.Example1.main(Example
1.java:15)
Unfortunately, if at line 15, there’s an assignment with multiple
method invocations getAmount() and getCurrency() either one
could be returning null. So, it’s not clear what is causing the
NullPointerException
Now, with Java 17, there’s a new JVM feature through which you can
receive more-informative diagnostics:
Exception in thread “main” java.lang.NullPointerException: Cannot
invoke “com.java14features.dto.Amount.getCurrency()” because the
return value of “com.java14features.dto.Account.getAmount()” is
null at
com.java14features.nullpointerexception.Example1.main(Example
1.java:16)
The message now has two clear components:
The consequence: Amount.getCurrency() cannot be invoked.
The reason: The return value of Account.getAmount() is null.
The enhanced diagnostics work only when you run Java with the
following flag: -XX:+ShowCodeDetailsInExceptionMessages
You can find the code, null pointer exception.
10. 4- Pattern Matching for Switch (Preview):
The Switch Expressions were released in Java 14, and it becomes a
standard language feature, we can use these Switch Expressions
which can be used as an expression with help of an arrow (->) ,
and now can yield/return the value.
Switch Expressions are actually two enhancements that can be used
independently but also combined:
Arrow notation without break and fall-throughs
Using switch as an expression with a return value
The following examples call the method and return a new yield.
1.
2.
switch (day) {
case MONDAY, FRIDAY, SUNDAY -> System.out.prin
case TUESDAY -> System.out.prin
case THURSDAY, SATURDAY -> System.out.prin
case WEDNESDAY -> {
int three = 1 + 2;
System.out.println(three * three);
}
}
11. public static void main(String[] args) {
for (VehicleType vehicle : VehicleType.values())
int speedLimit = getSpeedLimit(vehicle);
System.out.println("Speed limit: " + vehicle
}
}
private static int getSpeedLimit(VehicleType veh
return switch (vehicleType) {
case BIKE, SCOOTER -> 40;
case MOTORBIKE, AUTOMOBILE -> 140;
case TRUCK -> 80;
};
}
public static void main(String[] args) {
Days day = FRIDAY;
int j = switch (day) {
case MONDAY -> 0;
case TUESDAY -> 1;
default -> {
int result = day.toString().length();
yield result;
}
};
System.out.println(j);
}
}
12. Pattern matching and null
Now we can test the null in switch directly.
Old code.
After JDK 17
public static void main(String[] args) {
testString("Java 16"); // Ok
testString("Java 11"); // LTS
testString(""); // Ok
testString(null); // Unknown!
}
static void testString(String s) {
if (s == null) {
System.out.println("Unknown!");
return;
}
switch (s) {
case "Java 11", "Java 17" -> System.
default -> System.
}
}
13. Further Reading
JEP 406: Pattern Matching for switch (Preview)
You can find the code, switches.
5- Sealed classes:
Sealed classes and interfaces were the big news in Java 17.
public static void main(String[] args) {
testStringJava17("Java 16"); // Ok
testStringJava17("Java 11"); // LTS
testStringJava17(""); // Ok
testStringJava17(null); // Unknown
}
static void testStringJava17(String s) {
switch (s) {
case null -> Syste
case "Java 11", "Java 17" -> Syste
default -> Syste
}
}
14. Inheritance is a powerful construct. But there are very few Java
syntax checkpoints that limit the potential for inheritance-based,
object-oriented corruption. The sealed Java class helps reign in the
overzealous and often detrimental abuse of Java inheritance.
Sealed classes allow a developer to explicitly declare the names of
the components that can legally inherit from a class they create. No
longer is the inelegant use of an access modifier the only way to
restrict the use of a superclass.
In this section, you will learn:
What are sealed classes and interfaces?
How exactly do sealed classes and interfaces work?
What do we need them for?
Why should we restrict the extensibility of a class hierarchy?
•
•
•
•
15. Let’s start with an example…
Sealed classes are declared using sealed modifier and
permits clause. permits clause specifies the sub-classes
which can extend the current sealed class.
•
sealed class SuperClass permits SubClassOne, Sub
{
//Sealed Super Class
}
final class SubClassOne extends SuperClass
{
//Final Sub Class
}
From: https://blogs.oracle.com/javamagazine/post/java-sealed-classes-fight-ambiguity
16. Permitted sub-classes must be either final or sealed or non-
sealed . If you don’t declare permitted sub-classes with any one
of these modifiers, you will get compile time error.
final class SubClassTwo extends SuperClass
{
//Final Sub Class
}
•
sealed class SuperClass permits SubClassOne, Sub
{
//Sealed Super Class
}
final class SubClassOne extends SuperClass
{
//Final Sub Class
}
sealed class SubClassTwo extends SuperClass perm
{
//Sealed Sub Class permitting another subcla
}
non-sealed class SubClassThree extends SuperClas
{
//non-sealed subclass
17. final permitted sub-classes can not be extended further,
sealed permitted sub-classes are extended further by only
permitted sub-classes and non-sealed permitted sub-classes
can be extended by anyone.
Sealed class must and should specify its permitted subclasses
using permits clause otherwise there will be a compilation
error.
Permitted sub-classes must and should extend their sealed
superclass directly.
}
final class AnotherSubClass extends SubClassTwo
{
//Final subclass of SubClassTwo
}
•
•
sealed class AnyClass
{
//Compile Time Error: Sealed class must spec
}
•
18. In the same way, you can also declare sealed interfaces with
permitted sub interfaces or sub classes.
sealed class SuperClass permits SubClassOne, Sub
{
//Sealed Super Class
}
final class SubClassOne
{
//Compile Time Error: It must extend SuperCl
}
non-sealed class SubClassTwo
{
//Compile Time Error: It must extend SuperCl
}
•
sealed interface SealedInterface permits SubInte
{
//Sealed Super Interface
}
non-sealed interface SubInterface extends Sealed
{
//Non-sealed Sub Interface
}
19. Permitted subinterfaces must be either sealed or non-sealed
but not final .
non-sealed class SubClass implements SealedInter
{
//Non-sealed subclass
}
•
sealed interface SealedInterface permits SubInte
{
//Sealed Super Interface
}
sealed interface SubInterfaceOne extends SealedI
{
//Sealed Sub Interface
}
non-sealed class SubClass implements SubInterfac
{
//non-sealed subclass implementing SubInterf
}
non-sealed interface SubInterfaceTwo extends Sea
{
//Non-sealed Sub Interface
}
20. Permitted sub types must have name. Hence, anonymous inner
classes or local inner classes can’t be permitted sub types.
A sealed super class can be abstract , and permitted sub
classes can also be abstract provided they can be either
sealed or non-sealed but not final .
final interface SubInterfaceThree extends Sealed
{
//Compile time Error: Permitted subinterface
}
•
•
abstract sealed class SuperClass permits SubClas
{
//Super class can be abstract and Sealed
}
abstract final class SubClassOne extends SuperCl
{
//Compile Time Error : Sub class can't be fi
}
abstract non-sealed class SubClassTwo extends Su
{
//Sub class can be abstract and Non-sealed
}
abstract sealed class SubClassThree extends Supe
21. While declaring sealed classes and sealed interfaces, permits
clause must be used after extends and implements clause.
With the introduction of sealed classes, two more methods are
added to java.lang.Class (Reflection API). They are
getPermittedSubclasses() and isSealed() .
Also Read :
Sealed Classes & Interfaces OpenJDK Reference
6- Enhanced Pseudo-Random Number
Generators:
This JEP introduced a new interface called RandomGenerator to make
future pseudorandom number generator (PRNG) algorithms easier
to implement or use.
{
//Sub class can be abstract and Sealed
}
final class AnotherSubClass extends SubClassThre
{
//Final sub class of SubClassThree
}
•
•
•
22. The below example uses the new Java 17 RandomGeneratorFactory to
get the famous Xoshiro256PlusPlus PRNG algorithms to generate
random integers within a specific range, 0 – 5.
RandomNumberGenerator.java
package java.util.random;
public interface RandomNumberGenerator {
//...
}
import java.util.random.RandomGenerator;
import java.util.random.RandomGeneratorFactory;
public class RandomNumberGenerator {
public static void main(String[] args) {
// legacy
// RandomGeneratorFactory.of("Random").cre
// default L32X64MixRandom
// RandomGenerator randomGenerator =
// RandomGeneratorFactory
RandomGenerator randomGenerator =
23. Output:
All the Java 17 PRNG algorithms.
RandomGeneratorFactory.of("Xoshi
System.out.println(randomGenerator.getClas
int counter = 0;
while(counter<=5){
// 0-5
int result = randomGenerator.nextInt(6
System.out.println(result);
counter++;
}
}
}
class jdk.random.Xoshiro256PlusPlus
4
6
9
5
7
6
24. Java 17 also refactored the legacy random classes like
java.util.Random , SplittableRandom and SecureRandom to extend
the new RandomGenerator interface.
Further Reading
JEP 356: Enhanced Pseudo-Random Number Generators
Java 17’s Enhanced Pseudo-Random Number Generators
Group ---- Name
-------------------------
LXM : L128X1024MixRandom
LXM : L128X128MixRandom
LXM : L128X256MixRandom
LXM : L32X64MixRandom
LXM : L64X1024MixRandom
LXM : L64X128MixRandom
LXM : L64X128StarStarRandom
LXM : L64X256MixRandom
Legacy : Random
Legacy : SecureRandom
Legacy : SplittableRandom
Xoroshiro : Xoroshiro128PlusPlus
Xoshiro : Xoshiro256PlusPlus