这可能看起来与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 1
和Line 2
没有错误,则会隐式输入String
。但是,Line 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.z
为null
。
在Java 5之前,如果您想对Integer
个对象进行计算,那么您必须自己编写。
答案 2 :(得分:0)
在java中,引用默认值为null
。当您声明z
但未初始化时,它将默认值设为null
,因为z
是参考变量。因此,您获得了NullPointerException
。
有两种方法可以避免NullPointerException
。
初始化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));
}
}
重新分配时使用valueOf(int i)。
w.z = (null == w.z) ? 0 : Integer.valueOf(w.z.intValue() + w.z.intValue());