我可以将一个方法作为java中另一个方法的参数传递吗?

时间:2011-05-19 15:26:54

标签: java methods execution-time

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

这是我的代码:

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的执行时间?

6 个答案:

答案 0 :(得分:6)

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

这样的东西
public interface CommonFuncs {

   public void execute();
   ... more functions

}

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

答案 1 :(得分:6)

方法不是Java中的第一类对象,因此它们不能作为参数传递。你可以在一个烦人的类中使用你的方法调用,例如Runnable界面:

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

...


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

答案 2 :(得分:2)

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

答案 3 :(得分:2)

您处于正确的路径中,您需要传递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.");
}

答案 4 :(得分:1)

我有一个对象调用计数器,基本上看起来像这样:

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暴露并注入我需要的任何地方。你可以用反思做你所问过的事,但我认为那会很混乱(恕我直言)。

答案 5 :(得分:1)

你可以这样做:

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.");
}