我有一个问题。我在一个包中有多个类:假设包是
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 面向对象设计模式中的组合。
切勿随时使用方法名称字符串来执行方法。还有很多其他很酷的解决方案可以使用设计模式。