我有一个问题,使用开关情况的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实现它?
当前回答
如果您可以操作公共接口,您可以在枚举中添加,并让每个类返回唯一的值。您不需要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块仍然可以工作。
其他回答
如果需要通过“this”对象的类类型“切换”,这个答案是最好的https://stackoverflow.com/a/5579385/2078368
但如果你需要将“switch”应用于任何其他变量。我建议另一种解决办法。定义以下接口:
public interface ClassTypeInterface {
public String getType();
}
在你想要“切换”的每个类中实现这个接口。例子:
public class A extends Something implements ClassTypeInterface {
public final static String TYPE = "A";
@Override
public String getType() {
return TYPE;
}
}
之后,你可以用以下方式使用它:
switch (var.getType()) {
case A.TYPE: {
break;
}
case B.TYPE: {
break;
}
...
}
你唯一需要关心的是——在实现ClassTypeInterface的所有类中保持“类型”的唯一性。这不是一个大问题,因为在任何交集的情况下,您都会收到“switch-case”语句的编译时错误。
你不能只使用字节,short, char, int, String和枚举类型(以及原语的对象版本,这也取决于你的java版本,字符串可以在java 7中切换)
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();
};
不管怎样,他们一直在用开关做很酷的东西。
这是子类型多态有助于实现的典型场景。执行以下步骤
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,则可以应用访问者模式来实现相同的目的。
创建一个带有类名的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;
}
}
}
希望这能有所帮助。