Java 中 null 的行为
Behaviour of null in Java
这可能看起来与 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
发生了什么?
开始拆箱。整数没有 + 运算符。它必须拆箱为 int(原始)。
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
个对象进行计算,这是您必须自己编写的内容。
在java中,参考默认值为null
。当您声明 z
但未初始化时,它将采用默认值 null
因为 z
是一个引用变量。因此你得到了 NullPointerException
.
有 2 种方法可以避免 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());
这可能看起来与 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
发生了什么?
开始拆箱。整数没有 + 运算符。它必须拆箱为 int(原始)。
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
个对象进行计算,这是您必须自己编写的内容。
在java中,参考默认值为null
。当您声明 z
但未初始化时,它将采用默认值 null
因为 z
是一个引用变量。因此你得到了 NullPointerException
.
有 2 种方法可以避免 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());