我有一个问题,使用开关情况的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实现它?
当前回答
以防万一有人读到
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)”中有描述
其他回答
以防万一有人读到
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)”中有描述
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:
像这样使用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() }
}
While it is not possible to write a switch statement, it is possible to branch out to specific processing for each given type. One way of doing this is to use standard double dispatch mechanism. An example where we want to "switch" based on type is Jersey Exception mapper where we need to map multitude of exceptions to error responses. While for this specific case there is probably a better way (i.e. using a polymorphic method that translates each exception to an error response), using double dispatch mechanism is still useful and practical.
interface Processable {
<R> R process(final Processor<R> processor);
}
interface Processor<R> {
R process(final A a);
R process(final B b);
R process(final C c);
// for each type of Processable
...
}
class A implements Processable {
// other class logic here
<R> R process(final Processor<R> processor){
return processor.process(this);
}
}
class B implements Processable {
// other class logic here
<R> R process(final Processor<R> processor){
return processor.process(this);
}
}
class C implements Processable {
// other class logic here
<R> R process(final Processor<R> processor){
return processor.process(this);
}
}
然后在任何需要“开关”的地方,你可以这样做:
public class LogProcessor implements Processor<String> {
private static final Logger log = Logger.for(LogProcessor.class);
public void logIt(final Processable base) {
log.info("Logging for type {}", process(base));
}
// Processor methods, these are basically the effective "case" statements
String process(final A a) {
return "Stringifying A";
}
String process(final B b) {
return "Stringifying B";
}
String process(final C c) {
return "Stringifying C";
}
}
这个怎么样?
switch (this.name)
{
case "A":
doA();
break;
case "B":
doB();
break;
case "C":
doC();
break;
default:
console.log('Undefined instance');
}