Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does switch support objects other than Byte, Short, Character, Integer, enumerated types, and the String type?

JDK 7 added support for String with a switch, which extended the list of types supported by switch. As of Java 7, a switch supported the primitive types byte, short, char, and int, their respective wrapper types (Byte, Short, Character, and Integer), enumerated types, and the String type.

Does switch support objects other than Byte, Short, Character, Integer, enumerated types, and the String type?

like image 565
Arvind Kumar Avinash Avatar asked Jul 20 '26 05:07

Arvind Kumar Avinash


1 Answers

Java 21

In Java 16, JEP 394 extended the instanceof operator to take a type pattern and perform pattern matching. Leveraging this feature, in Java 21, JEP 441 made it possible to use case labels with patterns rather than just constants with switch statements and expressions.

Demo:

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

class Main {
    private static final DateTimeFormatter FORMATTER =
            DateTimeFormatter.ofPattern("[MMMM dd, uuuu][ h:mm a][ VV][ XXX]")
                    .localizedBy(Locale.ENGLISH);

    static String format(Object obj) {
        return switch (obj) {
            case null -> "🤔";
            case LocalDate date -> date.format(FORMATTER);
            case LocalTime time -> time.format(FORMATTER).trim();
            case OffsetDateTime odt -> odt.format(FORMATTER);
            case ZonedDateTime zdt -> zdt.format(FORMATTER);
            default -> obj.toString();
        };
    }

    public static void main(String[] args) {
        // Some sample values
        ZoneId zone = ZoneId.of("America/New_York");
        ZoneOffset offset = ZoneOffset.of("+05:30");
        LocalDate date = LocalDate.of(2025, Month.FEBRUARY, 21);
        LocalTime time = LocalTime.of(20, 30, 40);
        OffsetDateTime odt = OffsetDateTime.of(date, time, offset);
        ZonedDateTime zdt = ZonedDateTime.of(date, time, zone);

        // Test format
        System.out.println(format(date));
        System.out.println(format(time));
        System.out.println(format(odt));
        System.out.println(format(zdt));
        System.out.println(format(null));
        System.out.println(format(Instant.now()));
    }
}

Output from a sample run:

February 21, 2025
8:30 PM
February 21, 2025 8:30 PM +05:30
February 21, 2025 8:30 PM America/New_York -05:00
🤔
2025-02-22T11:25:36.329272700Z

Guard clauses and case dominance

It also allows a guard clause with a case in the form case <pattern> where <guard clause>. The case dominance rule must be maintained between cases with a guard clause. As per this rule, a more-dominant case must be below a less-dominant case. It is analogous to catch blocks and the order of caught exceptions.

Demo:

class Main {
    enum Day {MON, TUE, WED, THU, FRI, SAT, SUN}

    public static void main(String[] args) {
        Object[] values = {
                -10, 20, false, Day.SAT, 30.0, Double.NaN, Day.THU, Day.SUN
        };
        for (Object obj : values) {
            switch (obj) {
                case Integer i when i > 0 -> 
                        System.out.println("A positive integer");
                case Integer i when i < 0 -> 
                        System.out.println("A negative integer");
                case Double d when d.isNaN() -> 
                        System.out.println("0.0/0.0");
                case Double d -> 
                        System.out.println("Double - Not NaN");
                case Day d when d == Day.SAT || d == Day.SUN -> 
                        System.out.println("Weekend");
                case Day d -> System.out.println("Weekday");
                case null, default -> 
                        System.out.println("Discard");
            }
        }
    }
}

Output:

A negative integer
A positive integer
Discard
Weekend
Double - Not NaN
0.0/0.0
Weekday
Weekend

⚠️Warning: The order of case Double d when d.isNaN() and case Double d is important. It is because case Double d dominates over case Double d when d.isNaN() and therefore putting case Double d when d.isNaN() below case Double d will make case Double d when d.isNaN() unreachable. Similar is the case with case Day d when d == Day.SAT || d == Day.SUN and case Day d.

like image 167
Arvind Kumar Avinash Avatar answered Jul 22 '26 19:07

Arvind Kumar Avinash



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!