Moim zdaniem przydatny ficzer. W wcześniejszych wersjach Java „NullPointerException” zwracał tylko linię w której wystąpił błąd, przez co nie zawsze można było dokładnie stwierdzić którą zmienną jest on spowodowany. Szczególnie widać to w tworzeniu kodu w formie „pociągu” np. „class.value.nextValue….” lub „value.method().nextMethod()…”

W nowym NullPointerException dostaniemy informację która zmienna spowodowała błąd. Jest to na pewno przydatny feature dla tych którzy nie używają Optional w Java.

Przykład:

    
class Dome{
        private String mome = "Moooom";
    }

    class Some{
        private Dome dome = new Dome();
    }

    class Ome{
        private Some some;
    }

    @Test
    public void nullInSome(){

        Ome ome = new Ome();

        System.out.println("ome = " + ome);
        System.out.println("dome = " + ome.some.dome);
    }

W rezultacie po uruchomieniu dostajemy błąd:


java.lang.NullPointerException
    at com.example.java14.HelpfulNullPointerExceptions.nullInSome(HelpfulNullPointerExceptions.java:25)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:436)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambdainvokeTestMethod6(TestMethodTestDescriptor.java:170)
    at org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:166)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:113)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:58)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutorNodeExecutor.lambdaexecuteRecursively3(HierarchicalTestExecutor.java:112)
    at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutorNodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutorNodeExecutor.execute(HierarchicalTestExecutor.java:79)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutorNodeExecutor.lambdaexecuteRecursively2(HierarchicalTestExecutor.java:120)
    at java.base/java.util.stream.ForEachOpsForEachOpOfRef.accept(ForEachOps.java:183)
    at java.base/java.util.stream.ReferencePipeline21.accept(ReferencePipeline.java:177)
    at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)...