取消装箱空盒装对象会引发意外的NullPointerException

mre*_*mre 5 java eclipse unboxing nullpointerexception

如果您运行以下代码,

public class Foo{
    public static void main(String[] args){
        int id = new Bar().getId(); // throws unexpected NullPointerException
    }

    private static class Bar{
        private final Integer id;

        public Bar(){
            this(null);
        }

        public Bar(Integer id){
            this.id = id;
        }

        public Integer getId(){
            return id;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您将获得以下堆栈跟踪,

Exception in thread "main" java.lang.NullPointerException
    at Foo.main(Foo.java:3)
Run Code Online (Sandbox Code Playgroud)

为什么没有编译器警告或任何东西?恕我直言,这是一个非常讨厌的微妙与拆箱,或者也许我只是天真.


添加@Javier提供的答案,如果您使用的是Eclipse,则需要执行以下操作来启用此功能:

  1. 导航到Window> Preferences> Java> Compiler>Errors/Warnings
  2. 展开潜在的编程问题
  3. Boxing和拆箱转换切换为"警告"或"错误"
  4. 点按"确定"

Jav*_*ier 5

我不知道您使用的是什么IDE,但Eclipse可以选择在装箱和拆箱转换时启用警告.无法将其检测为空指针访问,因为null不是立即取消装箱,而是通过Bar.getId().

Integer类型的表达式被取消装入int
Foo.java第3行

  • 令人讨厌的是,没有拳击,日食无法打开取消装箱警告!https://bugs.eclipse.org/bugs/show_bug.cgi?id=163065 (2认同)

ame*_*eed 5

如果你试图在a上使用任何方法null或做任何对a 没有意义的事情null,它会抛出一个NullPointerException.

Autounboxing是使用[Integer object].intValue()方法(或类似方法)实现的,因此它会抛出一个NullPointerException因为您无法null调用方法.

希望这可以帮助!

  • 对于幕后的`intValue` +1,谢谢 (2认同)

mre*_*mre 5

这种行为似乎记录在JDK™ 5.0 文档中

..你可以在很大程度上忽略的区别intInteger,有几个注意事项。一个Integer表达式可以有一个空值。如果您的程序尝试自动拆箱 null,它将抛出一个NullPointerException.