๐ŸŽ“ A1Learner
๐Ÿ”
0 of 30 lessons completed

Java Pattern Matching in Switch

Pattern matching in switch tests a value and binds a typed variable in one step. Each matched branch uses the variable with its real type, with no cast.

The old chain tests and casts by hand

Each branch tests the type, then casts the value. The answers are right, and the code is long.

public class Main {
  static String describe(Object value) {
    if (value instanceof String) {
      String text = (String) value;
      return "Text: " + text;
    } else if (value instanceof Integer) {
      Integer number = (Integer) value;
      return "Count: " + number;
    } else if (value instanceof Double) {
      Double price = (Double) value;
      return "Price: " + price;
    } else if (value instanceof Boolean) {
      Boolean flag = (Boolean) value;
      return "Flag: " + flag;
    }
    return "Other";
  }
  public static void main(String[] args) {
    System.out.println(describe("hello"));
    System.out.println(describe(Integer.valueOf(42)));
    System.out.println(describe(Double.valueOf(2.5)));
    System.out.println(describe(Boolean.TRUE));
  }
}

Type patterns bind the value in one step

The switch binds a typed variable in each branch. The four printed lines match the old chain.

public class Main {
  static String describe(Object value) {
    return switch (value) {
      case String text -> "Text: " + text;
      case Integer number -> "Count: " + number;
      case Double price -> "Price: " + price;
      case Boolean flag -> "Flag: " + flag;
      default -> "Other";
    };
  }
  public static void main(String[] args) {
    System.out.println(describe("hello"));
    System.out.println(describe(Integer.valueOf(42)));
    System.out.println(describe(Double.valueOf(2.5)));
    System.out.println(describe(Boolean.TRUE));
  }
}

A guard sorts long text from short

The guard tests the length of the bound String. Long text and short text print different lines.

public class Main {
  static String size(Object value) {
    return switch (value) {
      case String s when s.length() > 3 -> "Long text: " + s;
      case String s -> "Short text: " + s;
      case Integer number -> "Count: " + number;
      default -> "Other";
    };
  }
  public static void main(String[] args) {
    System.out.println(size("banana"));
    System.out.println(size("hi"));
    System.out.println(size(Integer.valueOf(7)));
  }
}

Case null prints its own line

A null value matches the case null branch. It prints its line instead of throwing an error.

public class Main {
  static String describe(Object value) {
    return switch (value) {
      case null -> "No value";
      case String s -> "Text: " + s;
      default -> "Other";
    };
  }
  public static void main(String[] args) {
    System.out.println(describe(null));
    System.out.println(describe("hi"));
  }
}

Example

public class Main {
  static String describe(Object value) {
    return switch (value) {
      case null -> "No value";
      case String s when s.length() > 3 -> "Long text: " + s;
      case String s -> "Short text: " + s;
      case Integer number -> "Count: " + number;
      case Double price -> "Price: " + price;
      case Boolean flag -> "Flag: " + flag;
      default -> "Other";
    };
  }
  public static void main(String[] args) {
    System.out.println(describe(null));
    System.out.println(describe("banana"));
    System.out.println(describe("hi"));
    System.out.println(describe(Integer.valueOf(42)));
    System.out.println(describe(Double.valueOf(2.5)));
    System.out.println(describe(Boolean.TRUE));
  }
}

Key points

  • A type pattern names a type and a variable for the matched value.
  • The bound variable holds the value already cast to the pattern type.
  • A guarded pattern adds a when clause that must also pass.
  • A case null branch matches a null value before any type pattern runs.
  • Branch order matters, and a guarded branch sits before its plain branch.

In this example, one switch handles null, guarded and plain text, and three more types, and each call prints the line for its branch.

Note

A switch over Object still needs a default branch, because no family is closed.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

What does a guarded pattern add to a type pattern?