美文网首页
记一次遇到Optional的ifpersent的空指针异常

记一次遇到Optional的ifpersent的空指针异常

作者: wangpeng123 | 来源:发表于2020-06-23 15:57 被阅读0次

在使用Optional时发现一个场景如下代码所示:(简化后的代码)

 public static class Content {
        private String a;

        public void setA(String a) {
            this.a = a;
        }
    }

    public static void main(String[] args) {
        Content c = null;
        String str = null;
        Optional.ofNullable(str).ifPresent(c::setA);
    }

这段代码本意是要在str为空的时候不要调用c.setA()方法,那么此时即使c为null也不会产生异常。但是在实际运行过程中却发现会抛出NullPointerException异常。

Exception in thread "main" java.lang.NullPointerException
    at com.test.Test.main(Test.java:18)

代码已经简化的很简单了基本找不到什么问题,初步猜测应该是Java语法糖在编译成字节码的过程中加入了一些其他指令。接下来使用javap命令反解析class文件得到最终生成的指令内容,内容如下:

public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=3, args_size=1
         0: aconst_null
         1: astore_1
         2: aconst_null
         3: astore_2
         4: aload_2
         5: invokestatic  #21                 // Method java/util/Optional.ofNullable:(Ljava/lang/Object;)Ljava/util/Optional;
         8: aload_1
         9: dup
        10: invokevirtual #22                 // Method java/lang/Object.getClass:()Ljava/lang/Class;
        13: pop
        14: invokedynamic #23,  0             // InvokeDynamic #0:accept:(Lcom/test/Test$Content;)Ljava/util/function/Consumer;
        19: invokevirtual #24                 // Method java/util/Optional.ifPresent:(Ljava/util/function/Consumer;)V
        22: return
      LineNumberTable:
        line 71: 0
        line 72: 2
        line 73: 4
        line 74: 22
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      23     0  args   [Ljava/lang/String;
            2      21     1     c   Lcom/test/Test$Content;
            4      19     2   str   Ljava/lang/String;

果不其然在10:行执行Optional.ofNullable()方法后,ifPresent之前,对变量c执行了一个c.getClass()的方法调用。由于在此处c为null,所以抛出了空指针异常。程序报错的原因就在这里,那么这里为什么要执行getClass操作呢?
有意思的是小伙伴在Java11执行的结果是:

Exception in thread "main" java.lang.NullPointerException
    at java.util.Objects.requireNonNull(Objects.java:203)
        at com.test.Test.main(Test.java:18)

解析字节码得到的内容发现10:行由
【invokevirtual #22 // Method java/lang/Object.getClass:()Ljava/lang/Class;】
变成了
【 invokestatic #27 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;】,
那么也就是说这里可能是要进行一个非空校验。
在openjdk的记录里变更原因也证实了这个猜想
https://bugs.openjdk.java.net/browse/JDK-8073479#】

所以在使用方法引用的时候一定要注意这个问题,在代码没有执行到的情况下也会抛出空指针异常呦

相关文章

  • 记一次遇到Optional的ifpersent的空指针异常

    在使用Optional时发现一个场景如下代码所示:(简化后的代码) 这段代码本意是要在str为空的时候不要调用c....

  • Java 9 改进的 Optional 类

    Optional 类在 Java 8 中引入,Optional 类的引入很好的解决空指针异常。 Optional ...

  • Java8新特性7--使用Optional解决空指针问题

    使用Optional解决空指针问题 空指针是我们最常见也最讨厌的异常,为了防止空指针异常,你不得在代码里写大量的非...

  • Optional简单应用

    最近看核心卷注意到了Java8新增的Optional类,对于经常遇到的空指针异常(NullPointExcepti...

  • java8 -Optional

    厌倦了空指针异常? 考虑使用Java SE 8的Optional!使代码更具可读性并使得免受空指针异常的影响。有人...

  • Java-8-Optional类

    Java-8-Optional类 java8新特性之Optional类 空指针异常是一个运行时异常,对于这一类异常...

  • JDK8新特性:使用Optional

    空指针异Optional常是导致Java应用程序失败的最常见原因。以前,为了解决空指针异常,Google公司著名的...

  • 使用Java 8 Optional类

    从 Java 8 引入的一个很有趣的特性是 Optional 类。Optional 类主要解决的问题是空指针异常...

  • Java8的Optional类

    今天讲解一下java8的Optional类:以前只知道Optional类是用来解决空指针异常的,并且只知道isPr...

  • 利用Optional解决空指针异常

    Java 8 引入了一个十分实用的 Optional 类,它主要是为了解决空指针异常(NullPointerExc...

网友评论

      本文标题:记一次遇到Optional的ifpersent的空指针异常

      本文链接:https://www.haomeiwen.com/subject/zeehfktx.html