ThrowableCaptor 适用于 Eclipse 但不适用于 Netbeans

ThrowableCaptor works in Eclipse but not Netbeans

为了在我的测试中优雅地捕获异常(甚至在构造函数上),我在博客中找到了以下解决方案并将其用于我在 eclipse 上的所有项目:

Throwable t= ThrowableCaptor.captureThrowable(() -> (new LinkedList<Object>()));

ThrowableCaptor 由功能接口和一些额外的小代码实现:

public class ThrowableCaptor {

    @FunctionalInterface
    public interface Actor {
        void act() throws Throwable;
    }

    public static Throwable captureThrowable(final Actor actor) {
        Throwable result = null;
        try {
            actor.act();
        }
        catch (final Throwable throwable) {
            result = throwable;
        }
        return result;
    }
}

现在,正如我所说,在 Eclipse 中,这件事就像一个魅力。但是在 Netbeans 下,我总是收到以下错误消息:

incompatible types: bad return type in lambda expression
LinkedList<Object> cannot be converted to void

嗯,我不知道,怎么了...

更新 1 经过一些研究,我偶然发现了这个:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=398734

我不确定它是否相关,但据我了解,它表明 eclipse 存在问题。因此我的代码确实应该是问题所在。

我假设问题是匹配 new LinkedList<Object>void act() throws Throwable。我将尝试使用仿制药作为解决方案。

更新 2 函数式接口中没有泛型...

只有在调用 return 类型 void 的方法时,才能匹配到 Actor。将 return 类型更改为 Object 将允许所有方法 除了 那些 returning void。因此,ThrowableCaptor 需要一个小的升级,通过使用两个不同的功能接口来处理这两种情况。在我看来像是代码重复,但我没有找到解决它的好方法:

public class ThrowableCaptor {

    @FunctionalInterface
    public interface Actor {
        Object act() throws Throwable;
    }

    @FunctionalInterface
    public interface VoidActor {
        void act() throws Throwable;
    }

    public static Throwable captureThrowable(final Actor actor) {
        Throwable result = null;
        try {
            actor.act();
        }
        catch (final Throwable throwable) {
            result = throwable;
        }
        return result;
    }

    public static Throwable captureThrowable(final VoidActor actor) {
        Throwable result = null;
        try {
            actor.act();
        }
        catch (final Throwable throwable) {
            result = throwable;
        }
        return result;
    }
}

你做了不必要的工作;没有必要创建两个接口和 captureThrowable 方法。您所需要的只是了解 Java ExpressionsExpression Statements 之间的关系。后者是一个表达式,在需要 Statement 的情况下也是允许的。 new 表达式属于 表达式语句 类别,而放在大括号中的表达式则不是。

换句话说,您对原始陈述所做的一切:

Throwable t= ThrowableCaptor.captureThrowable(() -> (new LinkedList<Object>()));

是去掉new表达式两边的大括号:

Throwable t= ThrowableCaptor.captureThrowable(() -> new LinkedList<Object>());

请注意,您可以在此处进一步删除不必要的类型参数:

Throwable t= ThrowableCaptor.captureThrowable(() -> (new LinkedList<>()));

或使用方法参考:

Throwable t= ThrowableCaptor.captureThrowable(LinkedList::new);

旁注:

  • javac 的早期版本也有在错误上下文中接受大括号表达式的错误,请参阅 this question
  • 如果您最初用 标记了您的问题,那么您会更早收到答案