Unlock Java 14: Master instanceof Pattern Matching, Switch Expressions, and Text Blocks

This article walks through the sixteen JDK 14 JEPs, focusing on JEP 305’s instanceof pattern matching, JEP 361’s switch expressions, and JEP 368’s text blocks, providing design motivations, code comparisons, step‑by‑step usage, and practical tips for modern Java development.

JavaEdge
JavaEdge
JavaEdge
Unlock Java 14: Master instanceof Pattern Matching, Switch Expressions, and Text Blocks

JDK 14 New Features Overview

JDK‑343: Packaging Tool (Incubator)

JDK‑345: G1 NUMA Memory Allocation Optimizations

JDK‑349: JFR Event Streaming

JDK‑352: Non‑Atomic Byte‑Buffer Mapping

JDK‑358: Friendly NullPointerExceptions

JDK‑359: Records (Preview)

JDK‑361: Switch Expressions (Standard)

JDK‑362: Deprecate Solaris and SPARC Ports

JDK‑363: Remove CMS Garbage Collector

JDK‑364: ZGC on macOS

JDK‑365: ZGC on Windows

JDK‑366: Deprecate ParallelScavenge + SerialOld GC combo

JDK‑367: Remove Pack200 Tools and API

JDK‑368: Text Blocks (Second Preview)

JDK‑370: External Storage API (Incubator)

JEP 305: instanceof Pattern Matching

JEP 305 adds pattern‑matching capabilities to the instanceof operator, allowing a type test and a cast to be expressed in a single, concise statement.

Design Intent

When code needs to branch based on an object's type, the traditional approach required a separate type check and a cast, leading to verbose and error‑prone code.

Traditional Approach

public void beforeWay(Object obj) {
    // check type
    if (obj instanceof String) {
        // cast and use
        String str = (String) obj;
        System.out.println(str.length());
    }
}

Check the real type of obj.

If the check succeeds, cast obj to String.

Assign the cast value to a new local variable str.

Problems with this pattern include repetitive syntax, duplicated type names, and unnecessary temporary variables.

Verbose and cumbersome.

Type check and cast are performed separately.

The type name appears multiple times.

Redundant code.

JDK 14 introduces a streamlined form:

public void patternMatching(Object obj) {
    if (obj instanceof String str) {
        // <code>str</code> is already cast
        System.out.println(str.length());
    } else {
        // <code>str</code> not available here
    }
}

Note: the bound variable str is only in scope inside the if block.

Simplifying equals()

Using pattern matching, equals() can be reduced to a single expression:

public class Student {
    private String name;
    public Student(String name) { this.name = name; }
    @Override
    public boolean equals(Object obj) {
        return (obj instanceof Student s) && Objects.equals(this.name, s.name);
    }
    @Override
    public int hashCode() { return Objects.hash(name); }
}

This eliminates the need for an explicit cast and a separate null/type check.

JEP 361: Switch Expressions (Standard)

Switch expressions extend the traditional switch statement, allowing it to produce a value and eliminating the need for explicit break statements.

Design Intent

Java’s switch has evolved from Java 5 (enum support) to Java 7 (String support) and Java 11 (implicit fall‑through warnings). JDK 12 introduced the arrow syntax and expression form, which became standard in JDK 14.

Evolution of switch

Java 5+: enums are allowed.

Java 7+: String cases are allowed.

Java 11+: compiler warns about missing break.

Legacy switch example

public class Demo01 {
    public static void main(String[] args) {
        var score = 'C';
        switch (score) {
            case 'A': System.out.println("优秀"); break;
            case 'B': System.out.println("良好"); break;
            case 'C': System.out.println("中"); break;
            case 'D': System.out.println("及格"); break;
            case 'E': System.out.println("不及格"); break;
            default: System.out.println("数据非法!");
        }
    }
}

Missing break leads to fall‑through.

No‑break arrow syntax

public class Demo02 {
    public static void main(String[] args) {
        var score = 'C';
        switch (score) {
            case 'A' -> System.out.println("优秀");
            case 'B' -> System.out.println("良好");
            case 'C' -> System.out.println("中");
            case 'D' -> System.out.println("及格");
            case 'E' -> System.out.println("不及格");
            default -> System.out.println("成绩数据非法!");
        }
    }
}

Mixing old and new syntax causes a compilation error:

Compilation error when mixing switch syntaxes
Compilation error when mixing switch syntaxes

Switch as an expression

public class Demo03 {
    public static void main(String[] args) {
        var score = 'C';
        String s = switch (score) {
            case 'A' -> "优秀";
            case 'B' -> "良好";
            case 'C' -> "中";
            case 'D' -> "及格";
            case 'F' -> "不及格";
            default -> "成绩输入错误";
        };
        System.out.println(s);
    }
}

The switch now yields a value that can be assigned directly.

Multiple case values

public class Demo04 {
    public static void main(String[] args) {
        var score = 'B';
        String s = switch (score) {
            case 'A', 'B' -> "上等";
            case 'C' -> "中等";
            case 'D', 'E' -> "下等";
            default -> "成绩数据输入非法!";
        };
        System.out.println(s);
    }
}

Yielding a value

When a case needs a block, the block must end with a yield statement to produce the expression’s value.

public void print(int days) {
    var score = 'B';
    String result = switch (score) {
        case 'A', 'B' -> "上等";
        case 'C' -> "中等";
        case 'D', 'E' -> "下等";
        default -> {
            if (score > 100) {
                yield "数据不能超过100";
            } else {
                yield score + "此分数低于0分";
            }
        }
    };
    System.out.println(result);
}

Switch expressions cannot contain break; each arm must produce a value or throw an exception. They must be exhaustive, usually requiring a default clause unless the selector is an enum that is fully covered.

JEP 368: Text Blocks

Introduction

Text blocks simplify the creation of multi‑line string literals, improving readability for large pieces of text such as JSON, HTML, or SQL.

Design Intent

Introduced as a preview in JDK 13 (JEP 355) and refined in JDK 14, a text block is delimited by three double‑quote characters.

Description

A text block starts with """, may be followed by optional spaces, and ends with another """. The content begins after the line‑terminator of the opening delimiter and ends before the closing delimiter. Indentation is automatically stripped based on the minimal common whitespace.

Basic example

line 1
line 2
line 3

Equivalent to the traditional string literal:

"line 1
line 2
line 3
"

HTML example

String html = """
    <html>
        <body>
            <p>Hello, world</p>
        </body>
    </html>
""";

SQL example

String query = """
    SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
    WHERE `CITY` = 'INDIANAPOLIS'
    ORDER BY `EMP_ID`, `LAST_NAME`;
""";

Multilingual script example

ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
Object obj = engine.eval("""
    function hello() {
        print('"Hello, world"');
    }
    hello();
""");

Text blocks also support two special escape sequences: \ to suppress a line break and \s to insert a single space without affecting trailing whitespace handling.

These new JDK 14 features reduce boilerplate, make code clearer, and enable developers to write more expressive Java programs.

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.

JavaJEPinstanceofText BlocksSwitch ExpressionsJDK 14
JavaEdge
Written by

JavaEdge

First‑line development experience at multiple leading tech firms; now a software architect at a Shanghai state‑owned enterprise and founder of Programming Yanxuan. Nearly 300k followers online; expertise in distributed system design, AIGC application development, and quantitative finance investing.

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.