首页 > 解决方案 > 使用带有枚举和标记接口的 switch 语句

问题描述

我有一个标记界面

public interface Marker{}

和两个实现标记的枚举

public enum Sharpie implements Marker{
    RED,
    BLUE,
    BLACK
}

public enum Crayola implements Marker{
    PURPLE,
    ORANGE,
    GREEN
}

我正在尝试做的是利用 switch 语句,例如

public boolean isOwned(Marker m){
    // Take in a marker of either Sharpie, or Crayola
    switch(m){
        case BLUE:
        case BLACK:
        case GREEN:
            return true;
        default:
            return false;
    }
}

有没有办法在不使用昂贵的instanceof电话的情况下做到这一点?

像这样的东西会起作用,但我试图避免使用instanceof,坦率地说,它看起来有点难看。

public boolean isOwned(Marker m){

    // First determine instanceof and then cast the marker 
    // to the appropriate Type before utilizing the switch statement
    if (m instanceof Sharpie){
       switch((Sharpie) m){
           Case BLUE:
           Case BLACK:
               return true;
           default:
               return false;
       }
    } else {
       switch((Crayola) m){
           case Green:
               return true;
           default:
               return false;
       }
    }
}

标签: javaenumsswitch-statement

解决方案


看起来是为开关表达式尝试新的 Java 功能密封接口模式匹配的好场景(* 这是 jdk 17 的预览功能)

首先做成Marker密封接口

public sealed interface Marker permits Crayola, Sharpie {}

然后我们可以使用 switch 表达式来摆脱那些instanceof检查。

    public boolean isOwned(Marker marker) {
        boolean isOwned = switch (marker) {
            case Sharpie s -> s == Sharpie.BLACK || s == Sharpie.BLUE;
            case Crayola c -> c == Crayola.GREEN;
        };
        return isOwned;
    }

推荐阅读