Fundamentals 15 min read

New Features of JDK 17: Text Blocks, Enhanced NPE, Records, Switch Expressions and More

This article introduces the most useful JDK 17 language enhancements—including text blocks, improved NullPointerException messages, records, switch expressions, private interface methods, pattern matching, collection factory methods, new String APIs, Stream API extensions, the modern HttpClient, JShell, direct java file execution, and the Z Garbage Collector—providing code examples and practical guidance for Java developers.

Java Architect Essentials
Java Architect Essentials
Java Architect Essentials
New Features of JDK 17: Text Blocks, Enhanced NPE, Records, Switch Expressions and More

Introduction

Java versions evolve rapidly; while JDK 20 is the latest, JDK 8 remains the most widely used in production. The author shares personal experience of upgrading to JDK 17 after seeing its new syntax features.

1. JDK 17 Language Features

1.1 Text Blocks

Text blocks simplify writing multi‑line strings such as JSON, HTML, or SQL, eliminating cumbersome concatenation.

/**
 * 使用JDK8返回HTML文本
 *
 * @return 返回HTML文本
 */
public static final String getHtmlJDK8() {
    return "<html>
" +
        " <body>
" +
        " <p>Hello, world</p>
" +
        " </body>
" +
        "</html>";
}

With JDK 17 the same method can be written using a text block:

/**
 * 使用JDK17返回HTML文本
 *
 * @return 返回HTML文本
 */
public static final String getHtmlJDK17() {
    return """
        <html>
            <body>
                <p>Hello, world</p>
            </body>
        </html>
        """;
}

1.2 Enhanced NullPointerException

JDK 17 provides more detailed NPE messages, helping developers locate the exact null reference.

public static void main(String[] args) {
    try {
        // 简单的空指针
        String str = null;
        str.length();
    } catch (Exception e) {
        e.printStackTrace();
    }
    try {
        // 复杂一点的空指针
        var arr = List.of(null);
        String str = (String)arr.get(0);
        str.length();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

1.3 Records

Records provide a concise syntax for data‑carrier classes, reducing boilerplate getter/setter code.

package com.summo.jdk17;

public record StudentRecord(Long stuId,
                           String stuName,
                           int stuAge,
                           String stuGender,
                           String stuEmail) {
    public StudentRecord {
        System.out.println("构造函数");
    }

    public static void main(String[] args) {
        StudentRecord record = new StudentRecord(1L, "张三", 16, "男", "[email protected]");
        System.out.println(record);
    }
}

1.4 Switch Expressions

Since JDK 12, switch became an expression with a return value; JDK 17 adds pattern matching, yield, and arrow syntax.

package com.summo.jdk17;

public class SwitchDemo {
    public int getByJDK8(Week week) {
        int i = 0;
        switch (week) {
            case MONDAY, TUESDAY: i = 1; break;
            case WEDNESDAY: i = 3; break;
            case THURSDAY: i = 4; break;
            case FRIDAY: i = 5; break;
            case SATURDAY: i = 6; break;
            case SUNDAY: i = 7; break;
            default: i = 0; break;
        }
        return i;
    }

    public int getByJDK17(Week week) {
        return switch (week) {
            case null -> -1;
            case MONDAY -> 1;
            case TUESDAY -> 2;
            case WEDNESDAY -> 3;
            case THURSDAY -> { yield 4; }
            case FRIDAY -> 5;
            case SATURDAY, SUNDAY -> 6;
            default -> 0;
        };
    }

    private enum Week { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }
}

1.5 Private Interface Methods

Java 17 allows private methods inside interfaces, enabling better decomposition of large default methods.

public interface PrivateInterfaceMethod {
    /**
     * 接口默认方法
     */
    default void defaultMethod() {
        privateMethod();
    }

    // 接口私有方法,在Java8里面是不被允许的
    private void privateMethod() {
    }
}

1.6 Pattern Matching for instanceof

Pattern matching removes the need for explicit casts.

/**
 * 旧式写法
 */
public void matchByJDK8(Object value) {
    if (value instanceof String) {
        String v = (String) value;
        System.out.println("遇到一个String类型" + v.toUpperCase());
    } else if (value instanceof Integer) {
        Integer v = (Integer) value;
        System.out.println("遇到一个整型类型" + v.longValue());
    }
}

/**
 * 新写法
 */
public void matchByJDK17(Object value) {
    if (value instanceof String v) {
        System.out.println("遇到一个String类型" + v.toUpperCase());
    } else if (value instanceof Integer v) {
        System.out.println("遇到一个整型类型" + v.longValue());
    }
}

1.7 Collection Factory Methods

Creating small immutable collections is now a one‑liner.

// JDK8 style
Set<String> set = new HashSet<>();
set.add("a");
set.add("b");
set.add("c");

// JDK17 style
Set<String> set = Set.of("a", "b", "c");

2. Other New Features

2.1 New String Methods

repeat

: repeat a string. isBlank: check for blank strings without external libraries. strip: trim whitespace including full‑width characters. lines: obtain a stream of lines. indent: add indentation. transform: apply a function to the string.

2.2 Stream API Enhancements

Added takeWhile, dropWhile, ofNullable, the three‑argument iterate, and toList for more functional style.

// takeWhile example
List<Integer> list = Stream.of(2,2,3,4,5,6,7,8,9,10)
        .takeWhile(i -> (i % 2 == 0)).toList(); // [2, 2]

// dropWhile example
List<Integer> list1 = Stream.of(2,2,3,4,5,6,7,8,9,10)
        .dropWhile(i -> (i % 2 == 0)).toList(); // [3,4,5,6,7,8,9,10]

var nullStreamCount = Stream.ofNullable(null).count(); // 0

Stream.iterate(0, n -> n < 10, n -> n + 1).forEach(System.out::println);
Stream.iterate(0, n -> n + 1).limit(10).forEach(System.out::println);

2.3 New HttpClient

The modern HttpClient (standard since JDK 11) offers a fluent API for both synchronous and asynchronous requests.

// Synchronous request
HttpClient client = HttpClient.newBuilder()
        .version(Version.HTTP_1_1)
        .followRedirects(Redirect.NORMAL)
        .connectTimeout(Duration.ofSeconds(20))
        .proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80)))
        .authenticator(Authenticator.getDefault())
        .build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());

// Asynchronous request
HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://foo.com/"))
        .timeout(Duration.ofMinutes(2))
        .header("Content-Type", "application/json")
        .POST(BodyPublishers.ofFile(Paths.get("file.json")))
        .build();
client.sendAsync(request, BodyHandlers.ofString())
        .thenApply(HttpResponse::body)
        .thenAccept(System.out::println);

2.4 JShell

JShell provides an interactive REPL for Java, allowing quick experimentation without creating full projects.

2.5 Direct Execution of Java Files

Since JDK 11 you can run a single source file directly:

java MyProgram.java

2.6 Z Garbage Collector (ZGC)

ZGC, introduced in JDK 11 and stable in later releases, aims for pause times under 10 ms even with heap sizes up to 16 TB, making it suitable for low‑latency workloads.

3. Conclusion

Keeping up with Java releases is essential; many projects are already migrating from Java 8 to Java 17 (e.g., Spring Boot 3.0). Leveraging the new language features and runtime improvements can greatly enhance code readability, maintainability, and performance.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Javajdk17New FeaturesrecordsText Blocks
Java Architect Essentials
Written by

Java Architect Essentials

Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.