【问题标题】:Is there a way to pass my Java function into a try-catch function?有没有办法将我的 Java 函数传递给 try-catch 函数?
【发布时间】:2017-11-02 19:11:53
【问题描述】:

所以我连续有 20 个二传手,所有这些二传手都可能失败。如果一个失败,而不是跳过它们,或者用一个 try catch 包围它们,有没有办法使用 Java 8s 的一些特性来做到这一点?

例如,我在想这样的事情:

public void mapElement(Function function) {
try the function
catch if something goes wrong
}

然后我可以这样使用:

mapElement(myObject.putA(a));
mapElement(myObject.putB(b));
mapElement(myObject.putC(c));
....

【问题讨论】:

  • 为什么要捕获异常?即使某些步骤失败,mapElement() 能否安全地继续并履行其整体合同?通常,我会让异常未经修改地传递给我的调用者,让他知道我的方法失败了,他也会这样做,直到捕获和记录异常的顶级。

标签: java java-8


【解决方案1】:

这样的事情怎么样:

public void tryTo(Runnable action) {
    try {
        action.run();
    } catch (Exception e) {
        // do something?
    }
}

tryTo(() -> myObject.putA(a));
tryTo(() -> myObject.putB(b));
tryTo(() -> myObject.putC(c));

请注意,myObjectabc 都需要为 effectively final 才能正常工作。

上面的一个转折是有一个单一的方法,它接受一个Runnables 的数组并在循环中执行它们:

public void tryAll(Runnable... actions) {
    for (Runnable action : actions) {
        try {
            action.run();
        } catch (Exception e) {
            // do something?
        }
    }
}

tryAll(() -> myObject.putA(a),
        () -> myObject.putB(b),
        () -> myObject.putC(c));

【讨论】:

  • 赶上RuntimeException
  • @AndyTurner 或Throwable?
【解决方案2】:

您可以使用Runnable 功能接口。
它的函数描述符是() -> void

它非常适合您的需要,因为映射操作不返回任何结果,您也不需要指定任何参数作为函数的输入。
确实在这里:myObject.putA(a),您不想将 a 参数传递给函数。
您宁愿将整个表达式 myObject.putA(a) 作为 lambda 主体传递:
() -> myObject.putA(a);

你可以这样写mapElement() 方法:

public static void mapElement(Runnable mapProcessor) {
  // Retry logic
  try {
    mapProcessor.run();
  } catch (Exception e) {
    // exception handling
  }
}

请注意,要捕获任何 Java 异常(已检查和运行时),您必须捕获 RuntimeException 而不是 Exception

你可以这样使用mapElement()

MyObject myObject = new MyObject();
...
mapElement(() -> myObject.putA(a));
mapElement(() -> myObject.putB(b));
mapElement(() -> myObject.putC(c));

Runnable 可能无法传达预期的含义,因为它主要是 专为线程执行而设计。
如果有意义,您也可以引入自己的功能接口。
通过这种方式,您还可以在函数中声明任何相关的特定检查异常。
Runnable 是不可能的。

例如:

@FunctionalInterface
public interface MapProcessor{
    void map() throws MappingException;
}

你可以这样使用它:

public static void mapElement(MapProcessor mapProcessor) {
  // Retry logic
  try {
    mapProcessor.map();
  }
  catch (MappingException e) {
    // Mapping exception handling
  }
  catch (Exception e) { // or RuntimeException if more relevant
    // other exception handling
  }
}

【讨论】:

  • FYI
  • @shmosel,是的,但是用Runnable 声明一个特定的例外是不可能的。
猜你喜欢
  • 1970-01-01
  • 2022-01-03
  • 1970-01-01
  • 2019-10-29
  • 2019-05-09
  • 1970-01-01
  • 2022-09-27
  • 2012-07-29
相关资源
最近更新 更多