Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 16 pattern matching problem with Switch in Intellij IDEA 2020.3.3 (Expression expected)

As we know Java 16 brings with a new features like Records, sealed interfaces and classes, and also pattern matching.

Today I wanted use them in my training project. However, I ran into a problem, maybe I don't understand something.

So situation looks like in the given code which represents my Intellij Idea project: I have packages: client and order Client class is a sealed interface with three implementation: Regular, Vip and SuperVip:

package com.example.records.domain.client;
public sealed interface Client permits Client.Regular, Client.SuperVip, Client.Vip {
        
            Limit currentLimit();
        
            record Regular() implements Client {
        
                @Override
                public Client.Limit currentLimit() {
                    return Client.Limit.of((short) 10);
                }
            }
        
        
            record Vip() implements Client {
        
                @Override
                public Client.Limit currentLimit() {
                    return Client.Limit.of((short) 20);
                }
            }
        
            record SuperVip() implements Client {
        
                @Override
                public Client.Limit currentLimit() {
                    return Client.Limit.of((short) 100);
                }
            }
        
        
            record Limit(short value) {
                public Limit {
                    if (value < 0) throw new IllegalArgumentException("Values below 0 not allowed!");
                }
        
                static Limit of(short value) {
                    return new Limit(value);
                }
            }
        }

Order class is a simple aggregate knows from DDD: But there is a problem with switch statement:

package com.example.records.domain.order;

import com.example.records.domain.OrderId;
import com.example.records.domain.client.Client;
import com.example.records.domain.client.Client.*;
import com.example.records.shared.Money;
import com.example.records.shared.Result;

import java.util.LinkedList;
import java.util.List;

public class Order() {
    private final OrderId orderId;
    private final Client client;
    private final LinesItems linesItems = LinesItems.empty();

    Order(OrderId orderId, Client client) {
        this.orderId = orderId;
        this.client = client;
    }

    public Result add(LineItem lineItem) {
       return switch (client) {
            case Regular r -> addAnItemIfTheLimitIsNotExceeded(r.);
            case Vip v -> addAnItemIfTheLimitIsNotExceeded(v.);
            case SuperVip sv -> addAnItemIfTheLimitIsNotExceeded(sv.);
        };
    }

    private Result addAnItemIfTheLimitIsNotExceeded(Limit limit) {
        // TODO need impl
        return Result.OK;
    }


    private static class LinesItems {
        private final List<LineItem> lines = new LinkedList<>();

        private LinesItems() {}

        void add(LineItem lineItem) {
            this.lines.add(lineItem);
        }

        Money cost() {
            return lines.stream().map(LineItem::cost).reduce(Money.ZERO, Money::add);
        }

        static LinesItems empty() {
            return new LinesItems();
        }
    }
}

record LineItem(Money cost) {}

Other classes:

package com.example.records.domain;

public record OrderId(String value) {

    public OrderId {
        validate();
    }

    private void validate() {
        if (value == null)
            throw new IllegalArgumentException("Null value not allowed!");
        if (value.isBlank())
            throw new IllegalArgumentException("Blank value not allowed!");
    }
}
package com.example.records.shared;

import java.math.BigDecimal;

public record Money(BigDecimal value) {

    public static final Money ZERO = new Money(new BigDecimal("0.00"));

    public Money add(Money money) {
        return new Money(this.value.add(money.value));
    }
}
package com.example.records.shared;

public sealed interface Result {

    Success OK = new Success();

    record Success() implements Result{}
    record Failure(String message) implements Result {}
}

I'm getting "(Expression expected)" Where did I go wrong? (Experimental features is enabled, I've installed Java 16 open jdk)

enter image description here

enter image description here

like image 210
K2mil J33 Avatar asked Mar 18 '21 15:03

K2mil J33


People also ask

How to Setup Java 16 on IntelliJ?

IntelliJ IDEA Configuration You can also download Java 16 directly from IntelliJ IDEA. To do so, go to Platform Settings and click on SDKs, then click the '+' sign at the top, choose Download JDK, then select the Vendor and version and the directory to download the JDK to.

Does IntelliJ support Java 16?

Get up to speed on Java 16 with our top tips. IntelliJ IDEA always supports the most recent version of Java. If you want to see the new features that are most interesting to Java developers, and see how IntelliJ IDEA helps us to use these features, these tips are a great place to start.

Does IntelliJ support JDK 15?

IntelliJ IDEA is not only committed to supporting new Java features, but also to ensuring that our existing intentions and inspections work with them. IntelliJ IDEA 2020.2 already supports all the new language features from Java 15.

Which Java version allows pattern matching in switch?

The Java SE 17 release introduces pattern matching for switch expressions and statements (JEP 406) as a preview feature. Pattern matching provides us more flexibility when defining conditions for switch cases.


2 Answers

Type patterns in instanceof are a final (non-preview) feature in Java 16. However, type patterns in switch are not yet in Java 16; they are expected to arrive soon.

like image 139
Brian Goetz Avatar answered Sep 24 '22 01:09

Brian Goetz


The owner of jeps 394 Gavin Bierman has already submitted a JEP for that feature.

Pattern Matching for switch (Preview)

It has not yet been targeted to a release.

Edit: Just a quick update here. This feature has been proposed to be included in JDK 17. It is the JEP 406 here

like image 35
Panagiotis Bougioukos Avatar answered Sep 22 '22 01:09

Panagiotis Bougioukos