Java: How to check for null pointers efficiently

前端 未结 14 1759
清歌不尽
清歌不尽 2020-12-03 01:17

There are some patterns for checking whether a parameter to a method has been given a null value.

First, the classic one. It is common in self-made code

14条回答
  •  一生所求
    2020-12-03 01:52

    While I agree with the general consensus of preferring to avoid the getClass() hack, it is worth noting that, as of OpenJDK version 1.8.0_121, javac will use the getClass() hack to insert null checks prior to creating lambda expressions. For example, consider:

    public class NullCheck {
      public static void main(String[] args) {
        Object o = null;
        Runnable r = o::hashCode;
      }
    }
    

    After compiling this with javac, you can use javap to see the bytecode by running javap -c NullCheck. The output is (in part):

    Compiled from "NullCheck.java"
    public class NullCheck {
      public NullCheck();
        Code:
           0: aload_0
           1: invokespecial #1    // Method java/lang/Object."":()V
           4: return
    
      public static void main(java.lang.String[]);
        Code:
           0: aconst_null
           1: astore_1
           2: aload_1
           3: dup
           4: invokevirtual #2    // Method java/lang/Object.getClass:()Ljava/lang/Class;
           7: pop
           8: invokedynamic #3, 0 // InvokeDynamic #0:run:(Ljava/lang/Object;)Ljava/lang/Runnable;
          13: astore_2
          14: return
    }
    

    The instruction set at "lines" 3, 4 and 7 are basically invoking o.getClass(), and discarding the result. If you run NullCheck, you'll get a NullPointerException thrown from line 4.

    Whether this is something that the Java folks concluded was a necessary optimization, or it is just a cheap hack, I don't know. However, based on John Rose's comment at https://bugs.openjdk.java.net/browse/JDK-8042127?focusedCommentId=13612451&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-13612451, I suspect that it may indeed be the case that the getClass() hack, which produces an implicit null check, may be ever so slightly more performant than its explicit counterpart. That said, I would avoid using it unless careful benchmarking showed that it made any appreciable difference.

    (Interestingly, the Eclipse Compiler For Java (ECJ) does not include this null check, and running NullCheck as compiled by ECJ will not throw a n NPE.)

提交回复
热议问题