Java和拳击(自动装箱)

当你已经开发了15年Java却被同事问到如何debug一个null pointer exception(NPE 空指针异常)时, 可别太意外。通常情况下什么东西指向了“空”非常明显,而唯一要做的就是找到它。

这有时候会更加困难一些,因为有些人创建了一系列的间接引用对象。有天我见识到了一些新鲜的东西,并且困惑了一阵子。从短暂的迷惑到最终发现问题根源是debug Java程序最有意思的体验之一。

看看下面一段代码并找出NPE出现在哪儿:

return value;

是的,一个简单的return语句抛出了NPE。

这是为什么呢?这里并没有显式的间接引用。也没有空值的引用。那个语句就像它看上去那么简单。让我来把这段代码扩展一点好让你更好的理解:

public int getValue(){
        return value;
}

又一次,我们看到一段非常简单的代码。通过这段代码和我们文章标题的暗示,你可能已经明白是怎么回事,也可能更加困惑了。再重申一次,这里没有被显式间接引用的东西。我们甚至不是在处理一个引用,这个语句返回的是一个元始型变量。

通过这些线索,你想明白怎么回事儿了吗?好了,给你看看完整的代码和解释吧:

package Example;
public class Example {
    Integer value;
    public int getValue(){
        return value;
    }
}

注意value这个变量是Integer类型的,但是getValue的返回值为int型。

在Java 5 出现之前,上面这段代码会出现编译错误。但是Java 5 引进了自动装箱(Autoboxing). 这个新特性伴随了我一半的Java生涯并从未困扰过我。它一直是一个非常便利的特性。

自动装箱使得基本类型和他们的第一类对象之间实现无缝转换。你可以直接给value赋值而不用通过调用value.intValue来得到基本类型。但实际上intValue还是会被调用。

这就是为什么会抛出NPE了。问题中的那行代码变成如下这样:

return value.intValue();

在这行里,哪里抛出了NPE就很明显了。

哦对了, 提醒一下,拳击运动叫做甜蜜的科学(The Sweet Science)。我觉得自己被自动装箱狠狠打了一拳,所以想到了这个题目。

(译注:英文中The Sweet Science代指拳击Boxing,与Java的装箱技术名字相同)

原文链接: javacodegeeks 翻译: ImportNew.com - fanchao
译文链接: http://www.importnew.com/13650.html
[ 转载请保留原文出处、译者和译文链接。]

关于作者: fanchao

(新浪微博:@小肥朴

查看fanchao的更多文章 >>



相关文章

发表评论

Comment form

(*) 表示必填项

3 条评论

  1. Paul 说道:

    学习了…可是把Integer value作为参数传递给getValue()方法的话,为什么没有抛出异常呢?本人接触Java不久,还望指教啊,没想明白

    Thumb up 3 Thumb down 0

    • 小波 说道:

      nuu作为参数传递不会报空指针异常,只有在使用的时候才会
      也就是编译的时候是发现不了空指针的,运行的时候才能发现

      Thumb up 2 Thumb down 0

    • JP 说道:

      getValue() 的返回值为 int, Integer value = null; 的时候 java自动拆箱, null无法转换为int就控制帧了.

      Thumb up 0 Thumb down 0

跳到底部
返回顶部