java8中一个超易踩的坑:方法引用与lambda表达式的区别

2018-06-24  本文已影响103人  agile4j

作者:刘仁鹏
参考资料:

  1. java.lang.NullPointerException is thrown using a method-reference but not a lambda expression
  2. Run-Time Evaluation of Method References
  3. Run-Time Evaluation of Lambda Expressions

1.IDEA在诱导我写bug

public class Test {

    @org.junit.Test
    public void test() throws InterruptedException {
        testNPEOfLambda(null);
        Thread.sleep(1000);
        testNPEOfMethodRef(null);
    }

    private static void testNPEOfLambda(MyPrinter printer) {
        testNPE(() -> printer.out());
    }

    private static void testNPEOfMethodRef(MyPrinter printer) {
        testNPE(printer::out);
    }

    private static void testNPE(Runnable runnable) {
        Thread t = new Thread(runnable);
        t.setUncaughtExceptionHandler((t1, e) ->
                System.out.println(t1.getName() + " Exception!"));
        t.start();
    }

    static class MyPrinter {
        void out() {
            System.out.println("hello world");
        }
    }

}

//输出:
Thread-0 Exception!
Thread-1 Exception!
//输出:
Thread-0 Exception!

java.lang.NullPointerException
    at com.lpcoder.agile.base.Test.testNPEOfMethodRef(Test.java:17)
    at com.lpcoder.agile.base.Test.test(Test.java:9)
    ...略

2.为什么方法引用与lambda表达式不同

First, if the method reference expression begins with an ExpressionName or a Primary, this subexpression is evaluated. If the subexpression evaluates to null, a NullPointerException is raised, and the method reference expression completes abruptly. If the subexpression completes abruptly, the method reference expression completes abruptly for the same reason.
首先,如果方法引用表达式以ExpressionName或Primary开头,那么将对这个子表达式进行求值。如果子表达式的计算值为null,就会引发NullPointerException,方法引用表达式就会突然结束。如果子表达式突然结束,那么方法引用表达式也会因为同样的原因突然结束。

Evaluation of a lambda expression is distinct from execution of the lambda body.
对lambda表达式的求值与执行lambda正文是不同的。

3.总结


end

上一篇 下一篇

猜你喜欢

热点阅读