如何以动态顺序调用java方法?
Posted
技术标签:
【中文标题】如何以动态顺序调用java方法?【英文标题】:How to call java methods in a dynamic order? 【发布时间】:2016-01-02 04:52:47 【问题描述】:好的,我会尽量具体一点。
我有一个主类 InputHandler 和它下面大约五个方法。然后我有六个其他类,每个类下都有大约十个方法。每个类都有自己的 main 方法,它按顺序调用那个特定的类中的方法。请注意,除了 inputHandler 之外的每个类都有一个名为 priority 的变量,它存储一个从 0 到 10 的整数。
例如,
class helloWorld
String name; int age;
int priority = 2;
public static void main()
setName("John");
setAge(32);
public static void setName(String n)
name = n;
public static void setAge(int a)
age = a;
和其他类似的类。
但是主类是所有其他类的扩展。 所以订单看起来类似于: helloWorld > helloCountry > helloTown > inputHandler (其中 a > b 表示 b 扩展 a)
这样可以保证之前类的所有方法都继承在inputHandler中。
现在,正如我所说,inputHandler 类本身有自己的 main 方法。因此,如果我想调用属于某个上层类的方法,我可以使用类似的方法:
...
public static void main()
helloTown.main();
helloWorld.main();
helloCountry.main();
...
现在这是我的问题:如何使用 inputHandler 按优先级顺序调用各个主要方法。例如,如果 helloWorld 的优先级为 2,helloTown 的优先级为 1,helloCountry 为 3,则应首先调用 helloTown.main(),然后调用 helloWorld.main(),最后调用 helloCountry.main()。
我知道这听起来有点令人困惑,但我确信可以做到。我对此的看法是,首先提取变量的优先级值并按升序排列,并根据需要进行方法调用。任何帮助表示赞赏!请随时向我询问更多详细信息!提前谢谢你。
【问题讨论】:
什么?你想先打电话给 helloTown 然后你已经做了。 Java按顺序运行代码......并且除非您将其线程化,否则它会阻塞。而这一个程序是为什么你有这么多主要方法......如果你想动态加载类使用类加载器 当你编写的代码以特定的顺序调用方法时,这就是它们被调用的顺序。这就是你所做的。你能澄清一下你想做什么不同的事情吗? 旁注:你的设计看起来很奇怪。您有实例变量,例如name
但 static 设置器?不会那样工作的。您正在调用main()
而不是构造函数?为什么?
其实这个程序真的很大,我只是发布了一个较小的版本。我知道Java按顺序执行程序,但这就是我想要改变的。如果 a 扩展 b,b 扩展 c,我想更改调用各自主要方法的方式。我不想逐行隐式键入它们,而是希望它自动优先排序并执行。与@Thomas 的回答非常相似。
【参考方案1】:
我不太确定我是否正确地回答了您的问题,但我会尝试:
继承
如果您有一个层次结构,其中 C 扩展 B 和 B 扩展 A,您可以使用实例方法执行以下操作:
class A
void someMethod() ...
class B extends A
void someMethod()
super.someMethod(); //calls the method from A
//do whatever B needs to do here
class C extends B
void someMethod()
//let's change order and first do what C needs to do
super.someMethod(); //calls the method from B
如您所见,使用super
,您可以调用正在扩展的类的方法,并且您可以(几乎)执行任何您喜欢的顺序(在这种情况下,它是 C 然后 A 然后 B 的逻辑)。
优先级
由于您提到了优先级,我假设您希望拥有不同的对象,所有对象都具有可能不同的优先级。
在这种情况下,您可以将优先级存储在外部或对象本身中(通过方法、字段、注释等)。
此外,您可能希望提供一个带有可调用方法的通用接口,例如像这样(我会添加一个获取优先级的方法):
interface CommonInterface
void someMethod();
//one way you could do this
int getPriority();
class A implements CommonInterface
void someMethod() ...
int getPriority() return 1;
//same for B and C
然后你会得到一些集合,例如一个列表,对其进行排序和迭代:
List<CommonInterface> list = ...;
list.add( new A() );
list.add( new B() );
list.add( new C() );
//sort the list, I'll leave the implementation of the comparator for you
Collections.sort(list, new Comparator<CommonInterface>()
public int compare( CommonInterface o1, CommonInterface o2)
//compare both objects' priority as needed
//for more information have a look at the JavaDoc (https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html)
);
//iterate and call the method
for( CommonInterface instance : list )
instance.someMethod();
【讨论】:
我不太喜欢继承;如果有一个setPopulation(...)
方法,并且您想要世界/国家/州/城市的不同人口数怎么办?
@yshavit 当然继承不是城市、国家、世界等的合乎逻辑的选择,但InputHandler
也不适合在那里。这就是为什么我保持我的答案抽象,这就是我在第二部分中提到接口的原因。
helloWorld 和 helloCountry 只是示例名称。我完全理解super
的使用,但你能详细说明优先级部分吗?我不是 java 专家...所以我需要Comparator<CommonInterface>()
部分的帮助。非常感谢!我想你已经解决了大部分问题!
@AekanshDixit 我为相关方法添加了一个存根,实现并不难,阅读JavaDoc后您应该可以完成它。这意味着作为一个学习练习:)
另外,我将把列表的代码放在哪里... 在你刚刚定义的接口或 inputHandler 中?我很抱歉命名约定,这只是自发的。【参考方案2】:
如果直到运行时才知道优先级,这将成为一个非常古怪的问题......但是您可以尝试使用反射,也许是 Map
假设 World=0,Country=1,Town=2
// Initialize the map
Map<Integer, Class<?>> callPrio = new HashMap<Integer, Class<?>>();
callPrio.put(helloWorld.value, helloWorld.class);
callPrio.put(helloCountry.value, helloCountry.class);
callPrio.put(helloTown.value, helloTown.class);
// Invoke "main" methods in order of priority
for (int i = 0; i < callPrio.size(); i++)
callPrio.get(i).getMethod("main").invoke(null);
此代码将在运行时按此顺序调用主要方法:
helloWorld.main()
helloCountry.main()
helloTown.main()
【讨论】:
我觉得这个方法也很有用!感谢您的回答!【参考方案3】:在inputHandler的main方法中,
获取其他实例的优先级,如helloCountry.getPriority()
和
然后将所有优先级保存在哈希、列表或其他一些 DS 中。
然后对DS进行排序,就可以调用相应的主要方法了!
Thomas 的方法更好,除非在运行时定义了优先级。
【讨论】:
以上是关于如何以动态顺序调用java方法?的主要内容,如果未能解决你的问题,请参考以下文章