我有一个问题,使用开关情况的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的开关结构,你可以通过在方法中创建一个代码块并用标签命名它来实现。然后使用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 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();
};
不管怎样,他们一直在用开关做很酷的东西。
像这样使用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中的最佳解决方案是:
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)”中有描述
如果需要通过“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”语句的编译时错误。