Phi*_*hil 0 java reflection methods refactoring switch-statement
我有算法给我一个整数.基于这个Integer,我想调用一个方法.每个Integer都是唯一的(如数据库中的主键),并且有一个方法可以调用.每个方法都返回相同的数据类型.这些方法都在同一个类中,并在此类中调用.
经过几个小时的搜索,我只得到这2个解决方案,但我不知道哪个是"更好"?(运行时间,资源)
切换解决方案:第一个想法,但感觉不是很好
switch (code) {
case 1:
nextOperation = doMethod1();
break;
case 2:
nextOperation = doMethod2();
break;
//many more cases...
default:
break;
}
public MyObject doMethod1(MyObject myObject){
//do something with operation
return myObject;
}
Run Code Online (Sandbox Code Playgroud)
反射解决方案:运行时间可能不好(?)
try{
String methodName = "doMethod" + Integer.toString(operation.getOperationCode());
//operation.getOperationCode() same like code in switch solution
Method method = this.class.getDeclaredMethod(methodName, parametertype);
nextOperation = (MyObject) method.invoke(this, parameter);
}
catch (Exception e){
LogReport.writeLog(e.toString()); //own Log-Report filewriter
}
Run Code Online (Sandbox Code Playgroud)
对我的问题或其他解决方案可能有更好的方法吗?如果你能给我一点提示,我会很高兴的.
第三种选择是从数字构建地图Runnables并查找要调用的方法.我不确定运行时间会如何比较,但我想它会比使用反射更快.
Map<Integer, Runnable> methodMap = new ConcurrentHashMap<>();
methodMap.put(1, () -> doMethod1());
methodMap.put(2, () -> doMethod2());
methodMap.put(3, () -> doMethod3());
// ... and so on ...
// look up the method and run it:
Runnable method = methodMap.get(code);
if (method != null) {
method.run();
}
Run Code Online (Sandbox Code Playgroud)
我正在使用一个ConcurrentHashMap以防万一这个地图需要在程序运行时动态修改,但是如果你在开始时只构建一次地图然后从不修改它,那么普通HashMap也可以这样做.我使用lambdas来创建Runnables调用每个方法.
构建地图的代码仍然很长.您可以通过使用反射来帮助构建地图来缩短它.这样会比较慢,但是在构建地图时,您只需支付一次反射罚款,而不是每次需要按编号调度方法时.
注意:这是在不使用lambdas的情况下将方法添加到地图的另一种方法:
methodMap.put(1, new Runnable() { public void run() { doMethod1(); } });
methodMap.put(2, new Runnable() { public void run() { doMethod2(); } });
methodMap.put(3, new Runnable() { public void run() { doMethod3(); } });
// etc.
Run Code Online (Sandbox Code Playgroud)
这就是匿名内部类的完成方式; lambdas本质上是匿名方法,不带参数(),而后面的表达式->是要调用的代码(例如doMethod1()); 编译器看到这是传递给a的put方法Map<Integer, Runnable>并将匿名方法作为run方法Runnable,并使用该代码创建Runnable.