我有一个问题,使用开关情况的instanceof对象:
例如:我的问题可以在Java中重现:
if(this instanceof A)
doA();
else if(this instanceof B)
doB();
else if(this instanceof C)
doC():
如何使用switch…case实现它?
我有一个问题,使用开关情况的instanceof对象:
例如:我的问题可以在Java中重现:
if(this instanceof A)
doA();
else if(this instanceof B)
doB();
else if(this instanceof C)
doC():
如何使用switch…case实现它?
当前回答
像这样使用switch语句不是面向对象的方式。相反,您应该使用多态性的力量。简单的写
this.do()
之前已经建立了一个基类:
abstract class Base {
abstract void do();
...
}
它是A, B和C的基类:
class A extends Base {
void do() { this.doA() }
}
class B extends Base {
void do() { this.doB() }
}
class C extends Base {
void do() { this.doC() }
}
其他回答
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:
不,这是不可能的。然而,您可能想要做的是将多态性作为处理这类问题的一种方法。
下面是在Java 8中使用http://www.vavr.io/来实现这一功能的方法
import static io.vavr.API.*;
import static io.vavr.Predicates.instanceOf;
public Throwable liftRootCause(final Throwable throwable) {
return Match(throwable).of(
Case($(instanceOf(CompletionException.class)), Throwable::getCause),
Case($(instanceOf(ExecutionException.class)), Throwable::getCause),
Case($(), th -> th)
);
}
Java现在允许你以op的方式切换。他们称之为模式匹配切换。它在Java 17发布。JEP中给出的例子是
String formatted;
switch (obj) {
case Integer i: formatted = String.format("int %d", i); break;
case Byte b: formatted = String.format("byte %d", b); break;
case Long l: formatted = String.format("long %d", l); break;
case Double d: formatted = String.format("double %f", d); break;
case String s: formatted = String.format("String %s", s); break
default: formatted = obj.toString();
}
或者使用他们的lambda语法并返回一个值
String formatted =
switch (obj) {
case Integer i -> String.format("int %d", i)
case Byte b -> String.format("byte %d", b);
case Long l -> String.format("long %d", l);
case Double d -> String.format("double %f", d);
case String s -> String.format("String %s", s);
default -> obj.toString();
};
不管怎样,他们一直在用开关做很酷的东西。
如果你绝对不能编码到接口,那么你可以使用枚举作为中介:
public A() {
CLAZZ z = CLAZZ.valueOf(this.getClass().getSimpleName());
switch (z) {
case A:
doA();
break;
case B:
doB();
break;
case C:
doC();
break;
}
}
enum CLAZZ {
A,B,C;
}