Java中的null行为

时间:2015-06-11 11:06:20

标签: java nullpointerexception null concatenation

这可能看起来与SO上的其他问题重复。但是,我想知道Java如何处理null

例如:

public class Work {
    String x = null;
    String y;
    Integer z;

    public static void main(String arg[]) {
        Work w = new Work();
        w.x = w.x + w.y; // work Line 1
        w.x = w.x + w.y + w.z; // work Line 2
        w.z = w.z + w.z; // NullPointerException Line 3
        System.out.println(w.x.charAt(4));
    }
}

评论Line 3会打印n,而会取消注释NullPointerException。如果我对Line 1Line 2没有错误,则会隐式输入String。但是,Line 3会发生什么?

3 个答案:

答案 0 :(得分:5)

发生拆箱。整数没有+运算符。它必须被取消装箱到int(原始)。

答案 1 :(得分:2)

String在Java中有很多特殊的限制,无论好坏。规范要求null在转换为字符串时转换为字符串"null",例如通过字符串连接(在其他操作数上隐式调用toString())。因此,将null添加到字符串可以通过语言规范来实现。

基于此,您的前两行将导致

w.x = "null" + "null";
w.x = "nullnull" + "null" + "null";

在第3行,你会得到一个不同的现象,在这种情况下,自动装箱和开箱。为了简化原始类型与它们各自的包装类之间的脱节,您可以将算术运算符应用于包装类,这会提示它们的值被取消装箱,操作,并且结果再次被装箱。这就是NullReferenceException发生的地方,因为w.z仍然是null,因此无法取消装箱。实质上:

w.z = w.z + w.z

由编译器转换为:

w.z = Integer.valueOf(w.z.intValue() + w.z.intValue());

并且对intValue()的调用失败了,因为此处w.znull

在Java 5之前,如果您想对Integer个对象进行计算,那么您必须自己编写。

答案 2 :(得分:0)

在java中,引用默认值为null。当您声明z但未初始化时,它将默认值设为null,因为z是参考变量。因此,您获得了NullPointerException

有两种方法可以避免NullPointerException

  1. 初始化z。

    public class Work {
        String x = null;
        String y;
        Integer z = 0;   
    
        public static void main(String arg[]) {
            Work w = new Work();
            w.x = w.x + w.y; // work Line 1
            w.x = w.x + w.y + w.z; // work Line 2
            w.z = w.z + w.z; // work Line 3 
            System.out.println(w.x.charAt(4));
        }
    }
    
  2. 重新分配时使用valueOf(int i)。

    w.z = (null == w.z) ? 0 : Integer.valueOf(w.z.intValue() + w.z.intValue());