假设我有这样的代码片段:
try {
// code I need to wrap to be a helper
long t0 = System.nanoTime();
obj.doSomething(); // a void function
long t1 = System.nanoTime();
Logger.info("doSomthing takes {} nanoseconds", t1-t0);
} catch (IOException ex) {
Logger.error("something wrong happened");
}
// another code
try {
long t0 = System.nanoTime();
obj.doAnotherThing(); // void function
long t1 = System.nanoTime();
Logger.info("doSomthing takes {} nanoseconds", t1-t0);
} catch (IOException ex) {
Logger.error("something wrong happened");
}
所以我的问题实际上是如何将该void函数作为参数传递给辅助函数,以便我可以避免使用冗余代码来测量函数的执行时间。
跟进:如果doSomething可以抛出IOException
,该怎么办?在这种情况下,如果我不想在labmda中捕获异常,我应该如何调用lambda世界中的函数。
由于
答案 0 :(得分:6)
您可以使用Runnable
:
public void timeThis(Runnable runnable) {
long t0 = System.nanoTime();
runnable.run();
long t1 = System.nanoTime();
Logger.info("Execution took {} nanoseconds", t1 - t0);
}
然后,您可以将要作为参数运行的函数传递给timeThis
:
timeThis(() -> obj.doSomething());
如果obj.doSomething()
碰巧抛出了下面提到的IOException
,您可以在Runnable
的正文中抓住它:
timeThis(() -> {
try {
obj.doSomething();
} catch (IOException e) {
e.printStackTrace();
}
});
注意:这不是一个合适的基准。请参阅:How do I write a correct micro-benchmark in Java?
答案 1 :(得分:0)
虽然您已获得异常处理部分的相关答案,但我建议您使用JOOL
中的JOOQ
库。它提供了一组方便的FunctionaInterface
最多16个参数。 它还提供CheckedRunnable
,允许将已检查和未检查的异常抛出运行方法,可以根据您的要求进行处理。
所以,
public void timeThis(Runnable runnable) {
long t0 = System.nanoTime();
runnable.run();
long t1 = System.nanoTime();
Logger.info("Execution took {} nanoseconds", t1 - t0);
}
将成为: -
public void timeThis(CheckedRunnable runnable) {
long t0 = System.nanoTime();
runnable.run();
long t1 = System.nanoTime();
Logger.info("Execution took {} nanoseconds", t1 - t0);
}
现在你使用它如下: -
try {
timeThis(() -> {
obj.doSomething();
});
} catch (IOException e) {
e.printStackTrace();
}
注意您不必处理异常两次,因为能够在lambda表达式之外抛出异常。
希望它有所帮助!
答案 2 :(得分:-3)
尝试使用Java Reflection方法。 https://docs.oracle.com/javase/tutorial/reflect/member/methodInvocation.html 包装函数可以将Method作为输入,其中Method值在调用者中初始化。在包装函数中使用invoke来调用传递的方法。