我有一个问题,使用开关情况的instanceof对象:

例如:我的问题可以在Java中重现:

if(this instanceof A)
    doA();
else if(this instanceof B)
    doB();
else if(this instanceof C)
    doC():

如何使用switch…case实现它?


当前回答

创建一个带有类名的Enum。

public enum ClassNameEnum {
    A, B, C
}

找到对象的Class名称。 在枚举上写一个开关案例。

private void switchByClassType(Object obj) {

        ClassNameEnum className = ClassNameEnum.valueOf(obj.getClass().getSimpleName());

        switch (className) {
            case A:
                doA();
                break;
            case B:
                doB();
                break;
            case C:
                doC();
                break;
        }
    }
}

希望这能有所帮助。

其他回答

如果您可以操作公共接口,您可以在枚举中添加,并让每个类返回唯一的值。您不需要instanceof或visitor模式。

对我来说,逻辑需要写在switch语句中,而不是对象本身。这就是我的解决方案:

ClassA、ClassB和ClassC实现了CommonClass

接口:

public interface CommonClass {
   MyEnum getEnumType();
}

枚举:

public enum MyEnum {
  ClassA(0), ClassB(1), ClassC(2);

  private int value;

  private MyEnum(final int value) {
    this.value = value;
  }

  public int getValue() {
    return value;
  }

Impl:

...
  switch(obj.getEnumType())
  {
    case MyEnum.ClassA:
      ClassA classA = (ClassA) obj;
    break;

    case MyEnum.ClassB:
      ClassB classB = (ClassB) obj;
    break;

    case MyEnum.ClassC:
      ClassC classC = (ClassC) obj;
    break;
  }
...

如果你使用的是java 7,你可以为枚举设置字符串值,并且switch case块仍然可以工作。

不幸的是,这是不可能开箱即用的,因为开关case语句需要一个常量表达式。要克服这个问题,一种方法是将枚举值与类名一起使用。

public enum MyEnum {
   A(A.class.getName()), 
   B(B.class.getName()),
   C(C.class.getName());

private String refClassname;
private static final Map<String, MyEnum> ENUM_MAP;

MyEnum (String refClassname) {
    this.refClassname = refClassname;
}

static {
    Map<String, MyEnum> map = new ConcurrentHashMap<String, MyEnum>();
    for (MyEnum instance : MyEnum.values()) {
        map.put(instance.refClassname, instance);
    }
    ENUM_MAP = Collections.unmodifiableMap(map);
}

public static MyEnum get(String name) {
    return ENUM_MAP.get(name);
 }
}

这样就可以像这样使用switch语句

MyEnum type = MyEnum.get(clazz.getName());
switch (type) {
case A:
    ... // it's A class
case B:
    ... // it's B class
case C:
    ... // it's C class
}

不,这是不可能的。然而,您可能想要做的是将多态性作为处理这类问题的一种方法。

以防万一有人读到

java中的最佳解决方案是:

public enum Action { 
    a{
        void doAction(...){
            // some code
        }

    }, 
    b{
        void doAction(...){
            // some code
        }

    }, 
    c{
        void doAction(...){
            // some code
        }

    };

    abstract void doAction (...);
}

这种模式的最大好处是:

你只需要这样做(完全没有开关): void someFunction (Action Action) { action.doAction(…); } 在这种情况下,如果你添加新的动作称为“d”,你必须实现doAction(…)方法

注意:此模式在Joshua’s Bloch“Effective Java (2nd Edition)”中有描述

你不能。switch语句只能包含case语句,case语句是编译时常量,计算结果为整数(最多Java 6和Java 7中的字符串)。

在函数式编程中,您要寻找的是所谓的“模式匹配”。

参见Java中避免instanceof