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

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

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

如何使用switch…case实现它?


当前回答

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

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

在最近发布的Java 19中,这非常简单和有用: 创建接口,并具有名为makesomenoise()的方法,它接受动物参数。

void makeSomeNoise (Animal animal) {
switch (animal) {
case Dog dog → dog.bark();
case Cat catcat.meow();
default throw new RuntimeException ("WTH is it???");
}
}

java 7 +

public <T> T process(Object model) {
    switch (model.getClass().getSimpleName()) {
    case "Trade":
        return processTrade((Trade) model);
    case "InsuranceTransaction":
        return processInsuranceTransaction((InsuranceTransaction) model);
    case "CashTransaction":
        return processCashTransaction((CashTransaction) model);
    case "CardTransaction":
        return processCardTransaction((CardTransaction) model);
    case "TransferTransaction":
        return processTransferTransaction((TransferTransaction) model);
    case "ClientAccount":
        return processAccount((ClientAccount) model);
    ...
    default:
        throw new IllegalArgumentException(model.getClass().getSimpleName());
    }
}

你可以通过在getSimpleName中引入常量并使用完整的类名来省略字符串操作,这甚至更快:

public static final TRADE = Trade.class.getName();
...
switch (model.getClass().getName()) {
case TRADE:

你不能只使用字节,short, char, int, String和枚举类型(以及原语的对象版本,这也取决于你的java版本,字符串可以在java 7中切换)