我可以将一个方法作为java中另一个方法的参数传递吗?
我试图测量几种方法的执行时间。 所以我想要制作一个方法,而不是多次复制相同的代码。
这是我的代码:
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中的第一类对象,因此它们不能作为参数传递。 你可以在一个烦人的类中使用wrap你的方法调用,例如Runnable
接口:
private void MeasureExecutionTime(Runnable r) { r.run(); } ... MeasureExecutionTime(new Runnable() { public void run() { m(); } });
最简单的方法是传递一个接口。 所以像
public interface CommonFuncs { public void execute(); ... more functions }
然后在你可以拥有将CommonFuncs作为参数的方法。 这些方法的实现可以调用execute
方法。
我同意@hvgotcodes,但是,有可能,虽然你没有像m()
那样调用它,但是使用invoke (这意味着你可能应该传递另一个或两个参数……)。
您处于正确的路径中,您需要传递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."); }
我有一个对象调用计数器,基本上看起来像这样:
private long count; private long errors; private long duration; private long errorDuration;
有两个“时间”方法用于返回某些方法和其他无效方法。
public T time(ReturningRunnable 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)); }
我选择将exception重新抛出为运行时exception(因为我不是检查exception的粉丝),但你也可以使自定义MyRunnable接口抛出exception,然后捕获并重新抛出它们。 以下是上述用法:
counter.time(new Runnable() { @Override public void run() { // Do something });
或者,在返回值的情况下:
return counter.time(new ReturningRunnable() { @Override public Integer run() { return 1; // You get the idea });
我喜欢这个,因为我的计数器对象可以通过JMX暴露并注入我需要的任何地方。 你可以用反思做你所问的,但我认为那会很混乱(恕我直言)。
你可以这样做:
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."); }