by BehindJava

Java new features that needs to be at your finger tips

Home » java » Java new features that needs to be at your finger tips

In this tutorial we are going to learn about the new important and interesting features of Java with its recent adaptation of six month release of new features to the Java developers.

Today we will see few features with examples:

  1. Optional class
  2. Record
  3. String methods
  4. Switch expressions
  5. Text blocks
  6. Sealed classes

1. Optional class

  • Every programmer come across the NullPointer Exception knowingly or unknowingly and its hard to use too many null checks in our code.
  • Since Java 8 Optional class has been introduced in util package which helps in writing a clean code without many null checks.

NullPointer Exception without Optional

public class BehindJava {  
    public static void main(String[] args) {  
        String[] str = new String[10];  
        String lcStr = str[5].toLowerCase();  
        System.out.print(lcStr);  
    }  
}  

Output:

Exception in thread "main" java.lang.NullPointerException
	at BehindJava.main(BehindJava.java:6)

Optional class supports various approaches to deal with different situations based on the scenario. isPresent() method is one of them that you can use to do an if-check. Below is the example.

Only run code if value is present

import java.util.Optional;  
public class BehindJava {  
    public static void main(String[] args) {  
        String[] str = new String[10];
        //str[5] = "JAVA OPTIONAL CLASS EXAMPLE";  
        Optional<String> checkNull = Optional.ofNullable(str[5]);  
        if(checkNull.isPresent()){  // check for value is present or not  
            String lcStr = str[5].toLowerCase();  
            System.out.print(lcStr);  
        }else  
            System.out.println("string value is not present");  
    }  
}  

Output:

string value is not present

2. Record

  • Basically it is a an immutable data class which can hold few data attributes.

What is a record in java 16?
Records are immutable data classes which require the datatype and the name of the field.

When we specify the data type and the name of the fields it will generate hashcode, equals,constructor, tostring method automatically by the compiler.

For example in a Java application we are making a query to database to fetch few results to hold this results we need to create a data transfer object class i.e., DTO in the Java program where we can use record class to hold these values.

We will see how Data classes i.e., DTO’s are created before Java 16.

  1. private, final field for each piece of data.
  2. Getter for each field.
  3. Public constructor with a corresponding argument for each field.
  4. Equals method that returns true for object of the same class when all fields match. 5.Hashcode method that returns the same value when all fields match.
  5. toString method that includes the name of the class and the name of each field and its corresponding value. or\ we can use LOMBOK framework but LOMBOK needs extra support in the form of IDE plugin.

A simple immutable DTO

public class MyClass {
    public static void main(String args[]) {
      Student myStudent = new Student("Rani", 10);

      System.out.println(String.format("My Student %s is aged %s", myStudent.getName(), myStudent.getAge()));
    }
}
class Student {
    String name;
    Integer age;
    public Student(String name, Integer age){
        this.name = name;
        this.age = age;
    }
    public String getName(){
        return this.name;
    }
    public Integer getAge(){
        return this.age;
    }
}

In the above DTO we need to generate all the methods i.e., getters, setters and the actual problem is lot of boiler plate code which Java 16 tries to resolve with the record class by generating the equals, HashCode and toString methods as well as the priavte, final fileds and public constrcutor by the Java compiler.

Using the record keyword

public class MyClass {
    public static void main(String args[]) {
       Student myStudent = new Student("Rani", 10);

      System.out.println(String.format("My Student %s is aged %s", myStudent.getName(), myStudent.getAge()));
    }
}

public record Student(String name, Integer age) {}

Note that records cannot be subclassed.

3. String methods

  • Java Strings are object that allows us to store a sequence of character which may contain alpha numeric values enclosed in double qoutes.
  • Since Java 10 and Java 12, several useful new String methods has been introduced with respect to string manipulation and two new methods for simplifying text file access.

String.lines() example

import java.io.IOException;
import java.util.stream.Stream;
public class MyClass {
    public static void main(String args[]) throws IOException{
      String str = "bed \nbed2 \n\rbed3 \r";
      Stream line = str.lines();
      line.forEach(System.out::println);
    }
}

Output:
bed
bed2
bed3

String.readString(Path path) example

Path path = Path.of("myFile.txt"); 
String text = Files.readString(path);
System.out.println(text);

4. Switch expressions

  • Switch is a multiple choice decision making selection statement that is usedd when we want to select only one case out of multiple cases.
  • Since Java 12 the switch expression was modified as such that which allows for switch to be used inline within a statement i.e., returns a value and also provides an arrow syntax that eliminates the need for a break.
  • From Java 13 the yield keyword was introduced to explicitly denote what value the switch case must return.

Let’s look at some examples. First example of a switch statement in Java 8 format. This code uses a variable to output the name of a number if it is known.

Old Java switch

class Main { 
  public static void main(String args[]) {
    int size = 3;
    String message = "";

switch (size){
 case 1 :
message = "one";
 case 3 :
   message = "three";
break;
 default :
message = "unknown";
break;
}

System.out.println("The number is " + message);
  }
}

Now this code is quite verbose. Fact that there is already an error in it! Look closely for a missing break. below example simplifies it by using a switch expression.

New switch

class NewSwitch { 
  public static void main(String args[]) {
    int size = 3;

    System.out.println("The number is " +
      switch (size) {
        case 1 -> "one";
        case 3 -> "three";
        default -> "unknown";
      }
    );
  }
}

In the above code switch statement goes right inside the System.out.println. That adds a big readability to the code and message variable. Also arrow reduces the code by eliminating the break statement. The yield keyword is used when not using the arrow syntax.

5. Text blocks

  • This feature is production ready since Java 15 and was in preview mode in the previous versions of JDK.
  • The purpose of this feature is to express Strings that span several lines of source code to avoid concatenation and escape sequences in similar cases.
  • Make multi line string literals more readable and more maintainable.
  • The key usage of this feature is to embed a snippet of JSON, XML, and SQL in a String literal.

JSON Snippet using a text block

class TextBlock { 
  public static void main(String args[]) {
    String json = """
      {
        "site" : "Behind Java",
        "link" : "https://www.behindjava.com"
      }
    """;

    System.out.println(json);
  }
}

6. Sealed classes

Sealed classes was introduced in Java 15 to achieve the following goals:

  • Control which classes can extend a class.
  • Restrict the use of a super class to only some known sub classes.
  • prevent arbitaty unknown subclasses.
  • prepare for other enhancements in Java for example pattern matching in switch and instanceof

Sealed class example

public abstract sealed class Animal
    permits Cat, Dog, Quokka {...}

The above interface uses the sealed keyword to specify which class is permitted to extend the Animal class.