What is new in Java 17

Introduction

We want to shorty show all features which are new in Java 17. I have a repository to check out all new features in Java 17. Please check it out 🙂

1. Sealed Classes

Sealed classes and interfaces restrict which other classes or interfaces can extend or implement them, allowing for more control over class hierarchy and better encapsulation

Suppose you have a superclass called Animal, which represents different types of animals. You want to create a hierarchy of subclasses that inherit from Animal, but you want to restrict which classes can be subclasses of Animal. In this case, you can use the sealed keyword to specify a limited set of permitted subclasses.

Java
public sealed class Animal permits Dog, Cat, Bird {

   private String name;

   public Animal(String name) {
      this.name = name;
   }

   public String getName() {
      return name;
   }

   public void makeSound() {
      // implementation varies based on subclass
   }
}

public final class Dog extends Animal {

    public Dog(String name) {
        super(name);
    }
    public void makeSound() {
        System.out.println("woof woof");
    }

}

public class SealedClasses {
    public static void main(String[] args) {
        Dog dog = new Dog("Nasus");
        dog.makeSound(); // Woof woof
    }
}

Any other attempts to extend from Animals will lead to a compiler error. E.g.

Java
package codenest.org.animals;

public final class Whale extends Animal { // Will not compile, since Whale is not in sealed Animal

    public Whale(String name) {
        super(name);
    }

}

2. Records

Records provide a concise syntax for defining classes that are mainly used to store data, making it easier to write and read data classes. The main advantage of records to simple POJOs is the removal of boilerplate code for the getters, setters, toString-Method, equals, hashCode, etc. Look how easy it is to create a Person with name and age with the „record“ feature

Java
public record Person(String name, int age) {
    public Person {
        if (age < 0) {
            throw new IllegalArgumentException("Age must be positive");
        }
    }
}

    Person p = new Person("Alice", 30);
      // Notice, that we didn't define any Constructor or getter in Person
      System.out.println(p.name()); // Alice
      System.out.println(p.age()); // 30

Records are by default immutable. Each Attribute (name, age) is called a component.

3. Pattern Matching for instanceof

Pattern matching simplifies the process of typecasting objects, making it easier to check if an object is an instance of a certain class and then use its methods. Before we had to check the type (e.g. object instance of String) and then cast the object to the specific type. Now it is done in one step with instanceof

Java
        Object obj = "hello";

        if (obj instanceof String s) {
            // Now we dont have to cast obj to string anymore
            System.out.println(s.length())
        }
    }

As we see, we don’t have to cast „obj“ to String anymore, since we used „instanceOf„.

4. Switch Expressions Enhancements

The switch expression feature has been updated to make it more concise and easier to read by allowing multiple cases to share the same code block and using the arrow operator to replace break statements.

Java
        String day = "Tuesday";
        int numLetters = switch (day) {
            case "Monday", "Friday", "Sunday" -> 6;
            case "Tuesday" -> 7;
            case "Thursday", "Saturday" -> 8;
            case "Wednesday" -> 9;
            default -> throw new IllegalArgumentException("Invalid day: " + day);
        };
        System.out.println("Number of letters in " + day + ": " + numLetters);

As you can see, for our first case, we can just simply write all cases in one row.

Also the casting of one object like in step 3. is also done automatically:

Java
        Object obj = "I'm a String";
        switch (obj) {
            case String str -> System.out.println("String length: " + str.length()); // no need to cast obj to String anymore.
            case Integer num -> System.out.println("Number value: " + num);
            default -> throw new IllegalArgumentException("Unsupported type: " + obj.getClass());
        }

5. TextBlocks

One really neat addition is to write multiline text blocks. It was always a hustle to write those. Not it is really easy. Just use three quotation marks to let Java now, you are writing multi-line text blocks

Java
String multilineBlock = """ blub
still a string 
""";

6. Helpful NullPointerExceptions

You always had the problem with Nullpointerexceptions. Now you will get more information about the exception. Especially helpful, when you chain multiple methods and e.g. the first is already null.

Java
        String str = null;

        int len = str.length(); // NullPointerException with helpful error message
        // Cannot invoke "String.length()" because "str" is null

7. The new pseudo-Random Generator

The new pseudo-random number generators provide improved performance and more predictable behavior, making it easier to generate random numbers in a secure and efficient manner.

The Random the class has been updated in Java 17 to use the LXM algorithm, which is faster and produces better-quality random numbers than the previous algorithm.

Java
        Random random = new Random();
        
        // Generate 5 random integers between 0 and 100
        for (int i = 0; i < 5; i++) {
            int randomInt = random.nextInt(101);
            System.out.println("Random Integer " + (i + 1) + ": " + randomInt);
        }
    }

8. Additional Features

I want to mention some more features, but not in detail:

  • New APIs for Accessing Context-Specific Deserialization:
  • Strongly Encapsulate JDK Internals by Default
  • Deprecate the Applet API for Removal
  • Foreign-Memory Access API

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Nach oben scrollen