通过键调用特定方法的最有效方法 重构方法调用switch语句

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)

对我的问题或其他解决方案可能有更好的方法吗?如果你能给我一点提示,我会很高兴的.

Dav*_*rad 5

第三种选择是从数字构建地图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.

  • @Phil匿名类很好,这个想法在Java 7中仍然有用. (2认同)