Java, one of the most popular programming languages, has undergone significant enhancements in recent years. From version 10 to 17, Java has introduced a plethora of features that have improved developer productivity, code readability, and overall performance. In this comprehensive guide, we'll explore the key features introduced in Java versions 10 through 17, providing detailed explanations and practical examples for each.

Java 10 Features

Local-Variable Type Inference (var)

Java 10 introduced the var keyword, allowing for local-variable type inference. This feature reduces boilerplate code and improves readability.

// Before Java 10
String message = "Hello, Java 10!";

// With Java 10
var message = "Hello, Java 10!";

The var keyword can be particularly useful with complex types:

// Before Java 10
Map<String, List<String>> userRoles = new HashMap<>();

// With Java 10
var userRoles = new HashMap<String, List<String>>();

🔍 Note: The var keyword can only be used for local variables with initializers. It cannot be used for method parameters, return types, or class fields.

Optional.orElseThrow()

Java 10 added a no-argument orElseThrow() method to the Optional class:

Optional<String> optionalValue = Optional.empty();
String result = optionalValue.orElseThrow(); // Throws NoSuchElementException

This method is a concise way to throw a NoSuchElementException if the optional is empty.

Java 11 Features

String Methods

Java 11 introduced several new methods to the String class:

isBlank()

String str1 = "  ";
String str2 = "Hello";
System.out.println(str1.isBlank()); // true
System.out.println(str2.isBlank()); // false

lines()

String multiline = "Line 1\nLine 2\nLine 3";
multiline.lines().forEach(System.out::println);
// Output:
// Line 1
// Line 2
// Line 3

strip(), stripLeading(), stripTrailing()

String text = "  Hello, Java 11!  ";
System.out.println("'" + text.strip() + "'");        // 'Hello, Java 11!'
System.out.println("'" + text.stripLeading() + "'"); // 'Hello, Java 11!  '
System.out.println("'" + text.stripTrailing() + "'");// '  Hello, Java 11!'

File Methods

Java 11 simplified file operations with new methods in the Files class:

import java.nio.file.Files;
import java.nio.file.Path;

// Writing to a file
Path file = Path.of("example.txt");
Files.writeString(file, "Hello, Java 11!");

// Reading from a file
String content = Files.readString(file);
System.out.println(content); // Hello, Java 11!

HTTP Client (Standard)

Java 11 standardized the HTTP Client API, which was introduced as an incubator module in Java 9:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://api.example.com/data"))
        .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

This new HTTP client supports both HTTP/1.1 and HTTP/2, and provides both synchronous and asynchronous programming models.

Java 12 Features

Switch Expressions (Preview)

Java 12 introduced switch expressions as a preview feature:

String day = "MONDAY";
String result = switch (day) {
    case "MONDAY", "FRIDAY", "SUNDAY" -> "Slow day";
    case "TUESDAY" -> "Productive day";
    case "WEDNESDAY", "THURSDAY" -> "Busy day";
    case "SATURDAY" -> "Chore day";
    default -> "Unknown day";
};
System.out.println(result);

This new syntax allows switch to be used as an expression and introduces the -> operator for concise case labels.

String Methods

Java 12 added the indent() method to the String class:

String text = "Hello\nJava\n12!";
System.out.println(text.indent(4));
// Output:
//     Hello
//     Java
//     12!

Java 13 Features

Text Blocks (Preview)

Java 13 introduced text blocks as a preview feature, making it easier to write multiline strings:

String json = """
              {
                  "name": "John Doe",
                  "age": 30,
                  "city": "New York"
              }
              """;
System.out.println(json);

This feature significantly improves the readability of multiline strings, especially for formats like JSON, XML, or SQL queries.

Switch Expressions (Second Preview)

Java 13 refined the switch expressions preview, introducing the yield keyword for returning values:

int day = 3;
String dayName = switch (day) {
    case 1, 2, 3, 4, 5 -> "Weekday";
    case 6, 7 -> "Weekend";
    default -> {
        if (day < 1) {
            yield "Invalid day, too low";
        } else {
            yield "Invalid day, too high";
        }
    }
};
System.out.println(dayName);

Java 14 Features

Records (Preview)

Java 14 introduced records as a preview feature, providing a concise way to declare classes that are simple carriers for immutable data:

record Person(String name, int age) {}

Person john = new Person("John Doe", 30);
System.out.println(john.name()); // John Doe
System.out.println(john.age());  // 30

Records automatically generate constructors, accessors, equals(), hashCode(), and toString() methods.

Pattern Matching for instanceof (Preview)

Java 14 introduced pattern matching for instanceof as a preview feature:

Object obj = "Hello, Java 14!";
if (obj instanceof String s) {
    System.out.println(s.toUpperCase());
}

This feature eliminates the need for explicit casting after an instanceof check.

Switch Expressions (Standard)

Switch expressions became a standard feature in Java 14:

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);
};

Java 15 Features

Sealed Classes (Preview)

Java 15 introduced sealed classes as a preview feature, allowing developers to restrict which classes can inherit from a sealed class:

public sealed class Shape permits Circle, Rectangle, Triangle {
    // ...
}

final class Circle extends Shape {
    // ...
}

final class Rectangle extends Shape {
    // ...
}

final class Triangle extends Shape {
    // ...
}

Sealed classes provide more control over class hierarchies and can be useful for domain modeling.

Text Blocks (Standard)

Text blocks became a standard feature in Java 15:

String query = """
               SELECT id, name, email
               FROM users
               WHERE active = true
               ORDER BY name
               """;
System.out.println(query);

Hidden Classes

Java 15 introduced hidden classes, which are classes that cannot be used directly by the bytecode of other classes:

String className = "HiddenClass";
byte[] classData = // ... generate class bytes ...
Class<?> hiddenClass = MethodHandles.lookup()
    .defineHiddenClass(classData, true, MethodHandles.Lookup.ClassOption.NESTMATE)
    .lookupClass();

Hidden classes are primarily intended for use by frameworks that generate classes at runtime.

Java 16 Features

Records (Standard)

Records became a standard feature in Java 16:

record Point(int x, int y) {
    // Compact constructor
    public Point {
        if (x < 0 || y < 0) {
            throw new IllegalArgumentException("Coordinates must be non-negative");
        }
    }
}

Point p = new Point(5, 10);
System.out.println(p); // Point[x=5, y=10]

Pattern Matching for instanceof (Standard)

Pattern matching for instanceof became a standard feature in Java 16:

Object obj = "Hello, Java 16!";
if (obj instanceof String s && s.length() > 5) {
    System.out.println("Long string: " + s.toUpperCase());
}

Stream.toList()

Java 16 introduced a convenient toList() method for streams:

List<String> list = Stream.of("a", "b", "c")
                          .toList();
System.out.println(list); // [a, b, c]

This method provides a more concise way to collect stream elements into an unmodifiable list.

Java 17 Features (LTS)

Sealed Classes (Standard)

Sealed classes became a standard feature in Java 17:

public sealed interface Vehicle permits Car, Truck, Motorcycle {
    void start();
}

final class Car implements Vehicle {
    @Override
    public void start() {
        System.out.println("Car starting...");
    }
}

final class Truck implements Vehicle {
    @Override
    public void start() {
        System.out.println("Truck starting...");
    }
}

final class Motorcycle implements Vehicle {
    @Override
    public void start() {
        System.out.println("Motorcycle starting...");
    }
}

Pattern Matching for switch (Preview)

Java 17 introduced pattern matching for switch as a preview feature:

Object obj = "Hello";
String result = switch (obj) {
    case Integer i -> "Integer: " + i;
    case String s -> "String: " + s;
    case Long l -> "Long: " + l;
    default -> "Unknown";
};
System.out.println(result); // String: Hello

This feature allows for more expressive and concise switch statements and expressions.

Random Number Generators

Java 17 introduced new random number generator interfaces and implementations:

import java.util.random.RandomGeneratorFactory;

var randomGenerator = RandomGeneratorFactory.getDefault().create();
int randomInt = randomGenerator.nextInt(100);
System.out.println("Random number: " + randomInt);

These new generators provide improved performance and additional algorithms for random number generation.

Conclusion

Java versions 10 through 17 have brought a wealth of new features and enhancements to the language. From local-variable type inference to sealed classes, these updates have made Java more expressive, concise, and powerful. As Java continues to evolve, it remains a robust and versatile language for modern software development.

By staying up-to-date with these features, developers can write more efficient and maintainable code, leveraging the full power of the Java language. Whether you're working on small scripts or large-scale applications, these new Java features offer something valuable for every project.

Remember to check your Java version and compiler settings when using these features, especially those that were introduced as preview features before becoming standard. Happy coding with Java's latest enhancements! 🚀👨‍💻👩‍💻