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



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

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() 

方法。因此,我已经能够找到一种方法来获取我想要运行的类的数组列表。所以我需要帮助的是想出一种方法,这样它需要一个类名并运行我想要的方法。任何帮助,不胜感激。谢谢

我建议查看Class.forName ( ... )以获取类对象,Class.newInstance();您的类是否有默认构造函数(或其他Class.getDeclaredConstructor(...)(来创建新实例,然后Class.getDeclaredMethod( ... )找到该方法并调用它。

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

interface Me {
    void runMe();
}

然后让所有类实现 Me。

并列出Me

List<Class<Me>> ...

然后

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

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

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对象都扩展了一个基类,基类的构造函数将对象安装在调用其 runMe 方法的类持有的Set中。

内联

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);
    }
}

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

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

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

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

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

我建议使用带有通用方法的接口在每个类中覆盖。以便可以将任何类强制转换为接口并使用其方法来执行该方法。

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 面向对象设计模式中的组合。

切勿随时使用方法名称字符串来执行方法。还有很多其他很酷的解决方案可以使用设计模式。

相关内容

  • 没有找到相关文章

最新更新