如何在 Java 中组合枚举、开关和实例



我想使用 switch 语句(而不是 else if)测试三种情况。现在,这些情况每个测试变量是否是类的实例。我想做这样的事情:

switch(var){
case A: doA();
case B: doB();
case C: doC();
} 
public enum{
A, B, C
}

我希望 A 代表var instanceof A的情况。有没有办法将此信息分配给枚举中的值?

像下面这样声明枚举:

private enum ClassType {
    A,
    B,
    C,
    D,
    Unknown;
}

现在,编写一个返回类型的方法:

private ClassType getClassType(Object object){
    ClassType type = null;
    try{
        type = ClassType.valueOf(object.getClass().getSimpleName());
    }catch(IllegalArgumentException e){
        type = ClassType.Unknown;
    }
    return type;
}

现在,将其与开关一起使用:

switch(getClassType(object)){
    case ClassType.A:
        //do something
        break;
}

对于新类,您需要在 switch 中添加值和大小写。

你首先需要给你的枚举一个名字。

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY 
}
public class EnumTest {
Day day;
public EnumTest(Day day) {
    this.day = day;
}
public void tellItLikeItIs() {
    switch (day) {
        case MONDAY:
            System.out.println("Mondays are bad.");
            break;
        case FRIDAY:
            System.out.println("Fridays are better.");
            break;
        case SATURDAY: case SUNDAY:
            System.out.println("Weekends are best.");
            break;
        default:
            System.out.println("Midweek days are so-so.");
            break;
    }
}
public static void main(String[] args) {
    EnumTest firstDay = new EnumTest(Day.MONDAY);
    firstDay.tellItLikeItIs();
    EnumTest thirdDay = new EnumTest(Day.WEDNESDAY);
    thirdDay.tellItLikeItIs();
    EnumTest fifthDay = new EnumTest(Day.FRIDAY);
    fifthDay.tellItLikeItIs();
    EnumTest sixthDay = new EnumTest(Day.SATURDAY);
    sixthDay.tellItLikeItIs();
    EnumTest seventhDay = new EnumTest(Day.SUNDAY);
    seventhDay.tellItLikeItIs();
}
}

该示例取自 Java SE 教程页面中的枚举。这正是您的用例。

https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html

不知道为什么你想要枚举。 从Java 7开始,你可以打开字符串。 所以一种选择是

switch(myObject.getClass().getCanonicalName()) {
  case "java.lang.String" : doA(); break;
  case "com.Acme.foobar" : doB(); break;
  default: throw new IllegalArgumentException();
}

也就是说,如果这些类是相关的,并且您可以控制它们,那么@dpr是正确的:使用多态性和重载可能更好。

我会使用映射将运行时类型映射到枚举常量,例如:

public enum ClassType{
    A(Integer.class),
    B(String.class),
    C(Object.class),
    UNKNOWN(null);      
    private static final Map<Class<?>, ClassType> typesMap = new HashMap<>();
    public final Class<?> type;
    static{
        for (ClassType classType : EnumSet.allOf(ClassType.class)){             
            if(classType.type != null){
                typesMap.put(classType.type, classType);
            }
        }
    }
    private ClassType(Class<?> type){
        this.type = type;           
    }
    public static ClassType getClassTypeOf(Class<?> type){
        return typesMap.getOrDefault(type, UNKNOWN);
    }
}

它可以像这样使用:

switch(ClassType.getClassTypeOf(var.getClass())){
    case A:         
        break;
    case B:         
        break;
    case C:
        break;          
    default:            
        break;      
}

但是,此版本不考虑var类型的超类型。若要支持超类型查找,可以将 getClassTypeOf-方法更改为:

public static ClassType getClassTypeOf(Class<?> type){      
    for(Class<?> lookupType = type; lookupType != null; lookupType = lookupType.getSuperclass()){
        ClassType classType = typesMap.get(lookupType);
        if(classType != null){
            return classType;
        }
    }       
    return UNKNOWN;
} 

最新更新