StackTips
Java

Java 17 Interview Questions and Answers

A curated set of interview questions and answers on Java 17.

1. What is the Records in Java?

Records is a new language feature introduced in Java 14 and finalized in Java 16. A record is a special type of class in Java allows us to define classes that act as transparent carriers for immutable data. Records can be used to replace traditional POJOs, which are often verbose and require a lot of boilerplate code.

This is how we can define the records

public record Vehicle(String make, String model, int year) {}

The fields of a record are implicitly final, which means that once a record instance is created, the data it contains cannot be changed.

Records provides several built-in methods for common operations such as equals(), hashCode(), and toString(). Like a regular class, these methods can be extended to provide custom implementation.

Records allow you to define a Compact constructor which omits the parameter list, assuming the same parameters as the record components. Within this constructor, you can include validation or normalization logic for the fields.

public record Vehicle(String make, String model, int year) {
    
    // Compact constructor
    public Vehicle {
        if (year < 1886) { // The first car was made in 1886
            throw new IllegalArgumentException("Invalid year");
        }
        make = make.trim();
        model = model.trim();
    }
}

Records are ideal for creating simple data-carrier classes, such as DTOs (Data Transfer Objects), value objects in domain-driven design, tuples, and more. Records are serializable by default, provided that all their components are serializable.

2. What are Sealed Classes in Java 17?

Sealed classes are a new language feature introduced in Java 17 as part of JEP 409. They provide a way to restrict the subclasses that can extend a class or implement an interface. This feature is useful to create more robust and maintainable code and to define a closed hierarchy of types.

Sealed Classes allow you to specify a limited set of subclasses that can extend a given class or implement an interface.

This is how we can declare a sealed class in Java

public sealed abstract class Vehicle permits Car, Truck, Motorcycle {
    private final String make;
    private final String model;

    public Vehicle(String make, String model) {
        this.make = make;
        this.model = model;
    }
    
    public abstract void displayVehicleInfo();
}

public final class Car extends Vehicle {
    private final int seatingCapacity;

    public Car(String make, String model, int seatingCapacity) {
        super(make, model);
        this.seatingCapacity = seatingCapacity;
    }

    @Override
    public void displayVehicleInfo() {
        System.out.println("Car: " + getMake() + " " + getModel() + ", Seating Capacity: " + seatingCapacity);
    }
}

The permits clause is used to specify the allowed subclasses for type Shape.

Since the compiler knows all the possible subtypes of a sealed class, it will prevent any other class except Circle, Square or Rectangle to extend the Shape class.

3. How does the pattern matching for instanceof work in Java 17?

Pattern Matching for instanceof in Java 17 enhances the instanceof operator and eliminates the need of type casting and checking.

Traditional approach

if (obj instanceof Car) {
    Car str = (Car) obj;
    // Use car object here 
}

With pattern matching for instanceof

if (obj instanceof Car car) {
    // Use car object here 
}

As you can notice, it makes the code more concise but also enhances readability and reduces the possibility of errors, such as incorrect casting.

4. How does the Pattern matching for the switch work?

Pattern Matching for switch is introduced as a preview feature in Java 17. This feature extends the switch expression and switch statement to allow pattern matching in case labels. Pattern Matching for switch aims to make code more readable and safe, especially when dealing with type testing and casting.

Please note, the Pattern Matching for switch is still in preview and not yet a finalized.

switch (obj) {
    case String s -> System.out.println("It's a string: " + s);
    case Integer i -> System.out.println("It's an integer: " + i);
    case null -> System.out.println("It's null");
    default -> System.out.println("It's something else");
}