如何以动态顺序调用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按顺序运行代码......并且除非您将其线程化,否则它会阻塞。而这一个程序是为什么你有这么多主要方法......如果你想动态加载类使用类加载器 当你编写的代码以特定的顺序调用方法时,这就是它们被调用的顺序。这就是你所做的。你能澄清一下你想做什么不同的事情吗? 旁注:你的设计看起来很奇怪。您有实例变量,例如namestatic 设置器?不会那样工作的。您正在调用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&lt;CommonInterface&gt;() 部分的帮助。非常感谢!我想你已经解决了大部分问题! @AekanshDixit 我为相关方法添加了一个存根,实现并不难,阅读JavaDoc后您应该可以完成它。这意味着作为一个学习练习:) 另外,我将把列表的代码放在哪里... 在你刚刚定义的接口或 inputHandler 中?我很抱歉命名约定,这只是自发的。【参考方案2】:

如果直到运行时才知道优先级,这将成为一个非常古怪的问题......但是您可以尝试使用反射,也许是 Map ,它将保存优先级值到 Class 的映射。

假设 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方法?的主要内容,如果未能解决你的问题,请参考以下文章

Java代码执行顺序及多态体现

Java 继承中构造方法的执行顺序问题

鉴于所有调用都是异步的,您如何在 lambda 中构建顺序 AWS 服务调用?

Java 设计问题:强制方法调用顺序

java笔记

在这种方法调用和传入参数的情况下,Java 评估顺序是不是得到保证