使用带有枚举和标记接口的 switch 语句

Utilizing switch statements with enums and marker interface

我有一个标记界面

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;
       }
    }
}

我不知道你在做什么。此示例对 2 个不同的枚举使用独特的功能。我认为你应该在枚举 like this.

中使用扩展

只需将 switch 更改为 if。不需要 instanceof:

public boolean isOwned(Marker m){
    if(m == Sharpie.BLUE || m == Sharpie.BLACK || m == Crayola.GREEN)
        return true;
    return false;
}

看起来是尝试新 Java 功能的好方案 Sealed Interface and Pattern Matching for switch Expressions(* 这是 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;
    }