【问题标题】:Can I pass a Method as parameter of another method in java?我可以将一个方法作为 java 中另一个方法的参数传递吗?
【发布时间】:2011-05-19 15:26:54
【问题描述】:

我正在尝试测量几种方法的执行时间。所以我想创建一个方法而不是多次重复相同的代码。

这是我的代码:

private void MeasureExecutionTime(Method m)
{
    startTime = System.nanoTime();
    try
    {
        m();
    }
    finally
    {
        endTime = System.nanoTime();
    }
    elapsedTime = endTime - startTime;
    System.out.println("This takes " + elapsedTime + " ns.");
}

假设我有myMethod(),如何使用MeasureExecutionTime()来测量myMethod的执行时间?

【问题讨论】:

    标签: java methods execution-time


    【解决方案1】:

    方法不是 Java 中的一等对象,因此它们不能作为参数传递。您可以使用将您的方法调用包装在一个扩展的类中,例如Runnable 接口:

    private void MeasureExecutionTime(Runnable r) {
        r.run();
    }
    
    ...
    
    
    MeasureExecutionTime(new Runnable() { public void run() { m(); } });
    

    【讨论】:

    • 参见 java.lang.reflect.Method.
    【解决方案2】:

    最简单的方法是传递一个接口。所以像

    public interface CommonFuncs {
    
       public void execute();
       ... more functions
    
    }
    

    然后你可以拥有将 CommonFuncs 作为参数的方法。这些方法的实现可以调用execute方法。

    【讨论】:

      【解决方案3】:

      我同意@hvgotcodes,但是是的,有可能,虽然你不像m() 那样称呼它,而是使用invoke(这意味着你可能应该传递另一个或两个参数...... )。

      【讨论】:

        【解决方案4】:

        您在正确的路径中,您需要传递 Method 对象、执行该方法的目标对象以及它所采用的参数,然后将其调用到您的 try catch 中,例如:

        private void MeasureExecutionTime(Method m, Object target, Object args) 
                                    throws IllegalArgumentException, 
                                           IllegalAccessException, 
                                           InvocationTargetException
        {
            long startTime = System.nanoTime();
            long endTime;
            try
            {
                m.invoke(target, args);
            }
            finally
            {
                endTime = System.nanoTime();
            }
            long elapsedTime = endTime - startTime;
            System.out.println("This takes " + elapsedTime + " ns.");
        }
        

        【讨论】:

          【解决方案5】:

          我有一个对象调用 Counter,它基本上看起来像这样:

          private long count;
          private long errors;
          private long duration;
          private long errorDuration;
          

          有两个“时间”方法用于计时返回某些东西的方法和其他无效的方法。

          public <T> T time(ReturningRunnable<T> runnable) {
              long start = currentTimeMillis();
              T result = null;
              try {
                  result = runnable.run();
              } catch (Throwable ex) {
                  errorDuration += currentTimeMillis() - start;
                  errors++;
                  throw runtime(ex);
              }
              duration += currentTimeMillis() - start;
              count++;
              return result;
          }
          
          public void time(Runnable runnable) {
              time(new RunnableRunner(runnable));
          }
          

          我选择将异常重新抛出为运行时异常(因为我不喜欢检查异常),但您也可以让您的自定义 MyRunnable 接口抛出异常,然后捕获并重新抛出它们。这是上面的用法:

          counter.time(new Runnable() {
              @Override
              public void run() {
                  // Do something
              });
          

          或者这个,在返回值的情况下:

          return counter.time(new ReturningRunnable<Integer>() {
              @Override
              public Integer run() {
                  return 1; // You get the idea
              });
          

          我喜欢这样,因为我的计数器对象可以通过 JMX 公开并注入到我需要它们的任何地方。您可以通过反思来做您所要求的事情,但我认为那会很混乱(恕我直言)。

          【讨论】:

            【解决方案6】:

            你可以这样做:

            private void MeasureExecutionTime(Method m)
            {
            
                startTime = System.nanoTime();
                try
                {
                    m.invoke(classObj, args);
                }
                finally
                {
                    int endTime = System.nanoTime();
                }
                elapsedTime = endTime - startTime;
                System.out.println("This takes " + elapsedTime + " ns.");
            }
            

            【讨论】:

              猜你喜欢
              • 2018-08-08
              • 1970-01-01
              • 2013-07-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-12-29
              相关资源
              最近更新 更多