设计方法和使用反射在Java中运行方法

时间:2015-07-28 13:40:01

标签: java reflection process

我有一个问题。我在一个包中有多个类:假设包是

com.myPackage.first

此软件包包含以下类:

firstGood
secondGood
thirdBad
fourthGood

这些类中的每一个都有一个名称相同但实现不同的方法。所以说每个都有一个特定的函数叫做:

public void runMe(){

}

现在我想想出一个给出类名的方法,它会进入类中并运行该特定方法。

从概念上讲,我的方法看起来像那样:

ArrayList<Class> classList ; // where classList is a list of classes I want to run 

public void execute(){
 for(Class c : classList){
  // Go inside that class, (maybe create an intance of that class) and run     the method called run me
 }
}

public void execute(Class c, String methodToRun){
 for(Class c : classList){
  // Go inside that class, (maybe create an intance of that class) and    run     the method called run me
 }
}

现在。我能做的是得到我想要运行的类的名称

runMe() 

方法。所以我能够找到一种方法来获得我想要运行的类的arraylist。所以我需要帮助的是提出一个方法,它需要一个类名并运行我想要的方法。任何帮助表示赞赏。感谢

6 个答案:

答案 0 :(得分:3)

我建议看一下Class.forName ( ... )来获取类对象,Class.newInstance();如果你的类有一个默认的构造函数(否则为Class.getDeclaredConstructor(...))来创建一个新实例然后{{ 1}}找到方法并调用它。

所有这一切都没有考虑到你的想法是否真的很好,因为我真的不太明白为什么你想做你想做的事情......

答案 1 :(得分:3)

interface Me {
    void runMe();
}

然后让所有课程实现我。

并列出Me s

List<Class<Me>> ...

然后

void test(Class<Me> cl) {
    Me me = cl.newInstance();
    me.runMe();
}

答案 2 :(得分:2)

我的格言总是使用反射来解决问题 - 现在你有两个问题。鉴于此,你考虑过这样一个简单的模式:

interface Runner {

    public void runMe();
}

static abstract class BaseRunner implements Runner {

    public BaseRunner() {
        // Automagically register all runners in the RunThem class.
        RunThem.runners.add(this);
    }

}

class FirstGood extends BaseRunner implements Runner {

    @Override
    public void runMe() {
        System.out.println(this.getClass().getSimpleName() + ":runMe");
    }

}

class SecondGood extends BaseRunner implements Runner {

    @Override
    public void runMe() {
        System.out.println(this.getClass().getSimpleName() + ":runMe");
    }

}

static class RunThem {

    static final Set<Runner> runners = new HashSet<>();

    static void runThem() {
        for (Runner r : runners) {
            r.runMe();
        }
    }
}

public void test() {
    Runner f = new FirstGood();
    Runner s = new SecondGood();
    RunThem.runThem();
}

此处所有runMe个对象都扩展了一个基类,其构造函数将对象安装在调用其Set方法的类所持有的runMe中。

答案 3 :(得分:1)

内联

void execute() throws Exception{
    for (Class<?> c : classesList)
    {
        //If you don't already have an instance then you need one 
        //note if the method is static no need for any existing instance.
        Object obj = Class.forName(c.getName());
        // name of the method and list of arguments to pass
        Method m = c.getDeclaredMethod(methodName,null);
        //method accessibility check
        if(!m.isAccessible()) 
            m.setAccessible(true);
        //invoke method if method with arguements then pass them as new Object[]{arg0...} instead of null  
        //if method is static then m.innvoke(null,null)
        m.invoke(obj, null);

    }
}

答案 4 :(得分:0)

我建议使用定义runMe()方法的接口,然后让所有类实现该接口。然后你会得到一个这个接口的列表:

List<MyInterface> classes = new ArrayList<MyInterface>();

然后你可以轻松地迭代它并在所有这些上调用“runMe()”,或者如果你只想为某个类的实例调用它,你可以这样做:

public void execute(Class classForWhichToExecute) {
    for (MyInterface myInterface : classes) {
        if (classForWhichToExecute.isAssignableForm(myInterface)) {
            myInterface.runMe();
        }
    }
}

当然,如果您的方法是静态方法,这将无效 - 因此从您身边添加更多信息会有所帮助。

答案 5 :(得分:0)

我建议使用一个带有常用方法的接口来覆盖每个类。这样任何类都可以转换为接口并使用其方法来执行该方法。

interface GoodAndBad{
    public void runMe();
}

实施了班级

class FirstGood implements GoodAndBad{
    @override
    public void runMe(){
       // Code to be executed
    }
}

您可以使用execute()方法,如下所示

public void execute(List<GoodAndBad> classList){
    for(GoodAndBad c : classList){
        c.runMe();
     // Go inside that class, (maybe create an intance of that class) and  
       //  run the method called run me
    }
}

Class更改为GoodAndBad界面也可以更改其他方法。

这是松散耦合的对象,以支持Java面向对象设计模式中的组合。

永远不要使用方法名称的字符串来随时执行方法。使用设计模式还有很多其他很酷的解决方案。