Search code examples
javapattern-matchingjava-21record-patterns

Record patterns in java without instanceof nor switch


Java 21 record patterns promises the introduction of destructuring to the Java language. However, it seems to be tightly coupled to pattern matching that can only be used as part of instanceof comparison or in switch statements/expressions.

Consider the following record.

public record Point(int x, int y) {}

Is there a way to destructure an object of that particular type without using instanceof or switch? The following attempts do destructure point. But the code makes little sense as neither instanceof nor switch are unnecessary if we assume null-safety.

Point point = new Point(0, 0);

// destructuring with instanceof
if (point instanceof Point(int x, int y)) {
    System.out.printf("Point at (%d,%d)", x, y);
}

// destructuring with switch
switch (point) {
    case Point(int x, int y) -> System.out.printf("Point at (%d,%d)", x, y);
}

Solution

  • As pointed out in @Michael's answer, currently switch or instanceof is required for destructuring records patterns. However, that answer does not reflect what is coming down the pipeline.

    I talk to the creators of pattern-matching in Java on an infrequent basis (you can ask them questions on the amber-dev mailing list), and the features that have come out in Java 21 are only the start of pattern-matching. We haven't even reached the half-way point of what they want to include in the language for pattern-matching. I don't think we've even reached the 1/4 point.

    Now, to answer your specific question, the feature that they are currently deliberating on that is custom built to solve your exact, specific problem is currently called match (or let, again, this is work-in-progress, so the name is not even hammered down yet. All of this is still not guaranteed).

    Here is how they are thinking it might work: The Future of Java: Records, Sealed Classes and Pattern Matching - Jose Paumard.

    Circle circle = ...;
    
    match Circle(var center, var radius) = circle;
    // center and radius are binding variables
    

    Now, none of this is guaranteed, as they don't know for a fact that all of this stuff will work the way they expect. If something is not a good fit for the language, they refuse to include it. Hence why none of this is guaranteed. But there is so much more that they are going to try to put into the language.

    I would watch the rest of the video. They explore a lot more of what pattern-matching might be in Java. And again, that's not all. If even half of what they described comes out, then we are not even close to the halfway point. The future is exciting for Java!

    But yeah, don't use instanceof or switch for this. You can, it's not a sin. But they're building the actual feature you are going to want to use for your exact use-case later. So maybe use instanceof or switch for now, and then fix them to use the proper thing if/when the actual feature comes out.

    Note that the person leading pattern-matching for Java is @BrianGoetz. If he sees this, he will be able to answer this question in better detail than I can.

    Also, here is the official Java YouTube channel. They teach about stuff like this all the time. They have a great video series talking about Java 21, as well as Pattern-Matching in Java thus far.

    https://www.youtube.com/@java/videos