Skip to Content
Course content

111: Pattern Matching for switch

Click on the "Edit" button in the top corner of the screen to edit your slide content.

A few years ago, I was reviewing a PR for a payment processing module. The developer had written a massive if-else if chain to handle different payment types—CreditCard, PayPal, Crypto, and BankTransfer. Each block looked exactly the same: check if the object is an instance of a class, then manually cast it to that class, then finally call a method on it. It was a sea of boilerplate. The worst part? In one of the blocks, they'd copy-pasted the code but forgot to change the cast variable. It looked like if (p instanceof PayPal) { CreditCard cc = (CreditCard) p; ... }. It compiled perfectly, but it would have crashed the production server with a ClassCastException the moment a PayPal payment hit. That's the kind of fragility I hate in Java.

Killing the Boilerplate Cast

If you've spent much time with Java, you know the "instanceof" dance. For decades, we've had to check a type and then immediately cast it. Pattern matching for switch finally puts an end to that redundancy. Instead of checking the type and casting in two separate steps, you do it all in the case label.

Take a look at how we can handle those payment types now. Instead of a messy if chain, we use the switch expression to bind the variable directly:

public String processPayment(Object payment) {
    return switch (payment) {
        case CreditCard cc -> "Processing credit card ending in " + cc.getLastFour();
        case PayPal pp -> "Redirecting to PayPal account: " + pp.getEmail();
        case Crypto crypto -> "Verifying wallet address " + crypto.getAddress();
        case null -> "No payment method provided!";
        default -> "Unsupported payment method";
    };
}

See what happened there? case CreditCard cc does two things: it checks if payment is a CreditCard, and if it is, it automatically creates a variable cc of type CreditCard for you to use in that branch. I love that we can now handle null as an explicit case, too. Previously, switching on a null object would just throw a NullPointerException and crash your app.

Adding Guard Conditions with When

Sometimes, just knowing the type isn't enough. You might only want a specific case to trigger if some other condition is also true. In the old days, you'd have to put another if statement inside your case block, which added more nesting and more visual noise.

Now, we have "guards" using the when keyword. This allows you to refine your pattern matching without leaving the case label. It keeps the logic flat and readable.

public String validateTransaction(Object payment) {
    return switch (payment) {
        case CreditCard cc when cc.isExpired() -> "Card has expired!";
        case CreditCard cc when cc.getAmount() > 10000 -> "High-value transaction requires manual review";
        case CreditCard cc -> "Card validated";
        case PayPal pp when !pp.isVerified() -> "PayPal account not verified";
        case PayPal pp -> "PayPal validated";
        default -> "Generic payment validation failed";
    };
}

One thing to keep in mind: order matters. The switch evaluates cases from top to bottom. If I had put the generic case CreditCard cc above the when cc.isExpired() case, the generic one would always win, and the expired card check would never run. Always put your most specific conditions at the top.




📋 Practical Task

Implementing a Smart Notification Dispatcher

You are building a notification system that handles different types of alerts. You have a base interface Notification and three implementations: EmailNotification (with a subject and isUrgent flag), SmsNotification (with a phoneNumber), and PushNotification (with a deviceId).

Your task is to implement a method public String dispatch(Notification notification) using Pattern Matching for switch that returns the following strings:

  • If it's an EmailNotification and isUrgent is true: "URGENT EMAIL: [subject]"
  • If it's an EmailNotification and isUrgent is false: "Standard Email: [subject]"
  • If it's an SmsNotification: "SMS sent to [phoneNumber]"
  • If it's a PushNotification: "Push sent to device [deviceId]"
  • If the notification is null: "No notification provided"
  • For any other type: "Unknown notification type"

Make sure you use the when keyword for the urgency check and handle the null case explicitly within the switch.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.