使用字符串值作为调用方法的className

时间:2014-10-31 10:08:29

标签: java class

对我来说这对我来说很难(主要是因为我甚至不确定我正在寻找什么样的病,试着解释我能做的最好的事情)。 我想要一些Engine类文件(所有文件都有相同的方法,但会在其中使用不同的计算)。然后我希望我的主类获取我选择的类的名称,并在正确的类中调用该方法。 把漂亮的代码放到这样的东西:

Engine1.java:

public static class Engine1{
    doCoolStuff(){
        //coolStuff happening
    }
}

Engine2.java:

public static class Engine2{
    doCoolStuff(){
        //coolStuff happening in a different way
    }
}

Main.java:

String EngineType = "Engine1";

public class Main{
    public Main(){
        (Class.forName(EngineType)).doCoolStuff();
    }
}

这几乎就是这个想法,我甚至不确定这是否是最好的方法,但这就是我现在已经走了多远,如果有更好的方法,我也会提出建议Java中的一些东西,因为我有点新手。 显然在当前状态下这段代码没有编译(因为这行: 的Class.forName(...)doCoolStuff()。 "无法解决方法"

编辑:

这个问题已经得到了回答,但我觉得重要的是要注意我的代码有另一个问题:方法Class.forName()需要类的FULL路径名,即不仅仅是#34; Engine1"但是" com.packageName.Engine1"。可能会节省一些人30分钟:P

2 个答案:

答案 0 :(得分:4)

接口代码,以便所有实现共享一个方法:

public interface Engine {
  public void doCoolStuff();
}

public class Engine1 implements Engine {
  @Override
  public void doCoolStuff() {
    // ...
  }
}

然后,您可以使用以下方法调用该方法:

((Engine) Class.forName("Engine1").newInstance()).doCoolStuff();

更好的方法是将实例放在Map中:

Map<String, Engine> engines = new HashMap<>();
engines.put("Engine1", new Engine1()); // etc...
// .... later
engines.get("Engine1").doCoolStuff();

答案 1 :(得分:0)

您可以使用getMethod(methodname, parameter types) Class方法从类中获取方法。因此你可以使用

(Class.forName(EngineType)).getMethod("doCoolStuff").invoke(null);

请注意,这只适用于doCoolStuff()是静态方法的情况,否则您必须将该类的实例传递给invoke

另一种方法(如Barry已经建议的那样)是为此使用接口并创建类的实例,例如通过调用

((Engine)(Class.forName(EngineType)).newInstance()).doCoolStuff();

这假设您有一个无参数构造函数,并且肯定需要按名称访问该类。如果您只是在编码时可以使用类本身,则不应该使用Class.forName()而只是创建类的新实例,或者如果真的必须是静态方法(尽管我目前无法想到为什么直接在该课程上调用getMethod()

所以最好的方法是(如果你可以采取这条路线):

interface Engine { void doCoolStuff(); }
class Engine1 implements Engine { void doCoolStuff() { ... } }
class Engine2 implements Engine { void doCoolStuff() { ... } }

然后这样称呼它:

Engine e = new Engine1(); //if you need to use the class name, call Class.forName(name).newInstance() here
e.doCoolStuff();