我有一个问题。我在一个包中有多个类:假设包是
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。所以我需要帮助的是提出一个方法,它需要一个类名并运行我想要的方法。任何帮助表示赞赏。感谢
答案 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面向对象设计模式中的组合。
永远不要使用方法名称的字符串来随时执行方法。使用设计模式还有很多其他很酷的解决方案。