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

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

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

如何使用switch…case实现它?


当前回答

我知道这有点晚了,但对于未来的读者来说……

注意上面的方法,这些方法仅仅是基于A, B, C类的名称…:

除非你能保证A, B, C…(Base的所有子类或实现者)是final,然后A, B, C的子类…不会被处理。

即使if, elseif, elseif ..方法对于大量子类/实现者较慢,它更准确。

其他回答

这是子类型多态有助于实现的典型场景。执行以下步骤

interface I {
  void do();
}

class A implements I { void do() { doA() } ... }
class B implements I { void do() { doB() } ... }
class C implements I { void do() { doC() } ... }

然后您可以简单地在此上调用do()。

如果您不能自由地更改A、B和C,则可以应用访问者模式来实现相同的目的。

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

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

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

参见Java中避免instanceof

还有一种更简单的方法来模拟使用instanceof的开关结构,你可以通过在方法中创建一个代码块并用标签命名它来实现。然后使用if结构来模拟case语句。如果情况为真,则使用断点LABEL_NAME来退出临时的开关结构。

        DEFINE_TYPE:
        {
            if (a instanceof x){
                //do something
                break DEFINE_TYPE;
            }
            if (a instanceof y){
               //do something
                break DEFINE_TYPE;
            }
            if (a instanceof z){
                // do something
                break DEFINE_TYPE;
            }
        }

Eclipse建模框架有一个有趣的想法,它也考虑了继承。Switch接口中定义了基本概念:通过调用doSwitch方法来完成切换。

真正有趣的是实现。对于每种类型的兴趣,a

public T caseXXXX(XXXX object);

方法必须实现(默认实现返回null)。doSwitch实现将尝试为对象的所有类型层次结构调用所有caseXXX方法。之类的东西:

BaseType baseType = (BaseType)object;
T result = caseBaseType(eAttribute);
if (result == null) result = caseSuperType1(baseType);
if (result == null) result = caseSuperType2(baseType);
if (result == null) result = caseSuperType3(baseType);
if (result == null) result = caseSuperType4(baseType);
if (result == null) result = defaultCase(object);
return result;

实际框架为每个类使用一个整数id,所以逻辑实际上是一个纯切换:

public T doSwitch(Object object) {
    return doSwitch(object.class(), eObject);
}

protected T doSwitch(Class clazz, Object object) {
    return doSwitch(getClassifierID(clazz), object);
}

protected T doSwitch(int classifierID, Object theObject) {
    switch (classifierID) {
    case MyClasses.BASETYPE:
    {
      BaseType baseType = (BaseType)object;
      ...
      return result;
    }
    case MyClasses.TYPE1:
    {
      ...
    }
  ...

您可以查看ECoreSwitch的完整实现,以获得更好的理解。