【问题标题】:How can I wrap this as a helper function?如何将其包装为辅助函数?
【发布时间】:2018-04-05 21:54:45
【问题描述】:

假设我有这样的代码 sn-ps:

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 世界中的函数。

谢谢

【问题讨论】:

  • 你试过什么?你知道如何使用 lambda,因为你标记了它们?那就试试吧。
  • 看Runnable功能界面。

标签: java function lambda java-8


【解决方案1】:

您可以使用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?

【讨论】:

  • 或timeThis(obj::doSomething);
  • 刚刚得到一个后续问题,如果doSomthing会抛出IOException,我该如何使用这个helper?
【解决方案2】:

虽然您已经获得了异常处理部分的相关答案,但我建议您使用来自JOOQ 的JOOL 库。它提供了一组方便的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 表达式之外抛出异常。

希望对你有帮助!

【讨论】:

    【解决方案3】:

    尝试使用 Java 反射方法。 https://docs.oracle.com/javase/tutorial/reflect/member/methodInvocation.html 包装函数可以将 Method 作为输入,其中 Method 值在调用者中初始化。在包装器函数中使用调用来调用传递的方法。

    【讨论】:

    • 为此使用反射是糟糕的软件设计。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 2014-01-23
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多