ThrowableCaptor适用于Eclipse,但不适用于Netbeans

时间:2015-01-22 20:45:56

标签: java eclipse netbeans lambda java-8

为了在我的测试中优雅地捕获异常(甚至在构造函数上),我在博客中找到了以下解决方案并在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

我不确定它是否相关,但根据我的理解,这表明日食存在问题。因此我的代码确实应该是问题。

我认为问题是new LinkedList<Object>void act() throws Throwable匹配。我会尝试使用泛型作为解决方案。

更新2 功能界面中没有泛型......

2 个答案:

答案 0 :(得分:1)

你做了不必要的工作;没有必要创建两个接口和captureThrowable方法。您所需要的只是理解Java Expressions Expression 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
  • 如果您最初使用标记了您的问题,那么您之前收到的回答是

答案 1 :(得分:0)

当调用返回类型为void的方法时,只能匹配Actor。将返回类型更改为Object将允许之外的所有方法返回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;
    }
}