Java中字符串和整数的空值
Posted
技术标签:
【中文标题】Java中字符串和整数的空值【英文标题】:Null values of Strings and Integers in Java 【发布时间】:2013-01-10 10:13:13 【问题描述】:public class Test
public static void main(String[] args)
String s = null;
String s1 = null;
Integer i = null;
Integer i1 = null;
System.out.println(s+i);
System.out.println(i+s);
System.out.println(s+s1);
try
System.out.println(i+i1);
catch (NullPointerException np)
System.out.print("NullPointerException");
问题很简单——为什么我只在最后一行收到NullPointerException
?
【问题讨论】:
java 中的空字符串连接:***.com/questions/4260723/… 这样一个很好的观察性问题加 1 【参考方案1】:您的代码使用了两个不同的additive operators。前三行使用string concatenation,而最后一行使用numeric addition。
字符串连接是well-defined to turn null
into "null"
:
如果引用为null
,则转换为字符串"null"
(四个ASCII字符n
、u
、l
、l
)。
因此没有 NPE。
将两个Integer
对象加在一起需要它们是unboxed。这会导致 null
引用被取消引用,从而导致 NPE:
如果r
为空,拆箱转换会抛出NullPointerException
【讨论】:
+1 用于引用 JLS,而不是深入研究实现细节(请参阅我的回答 ;-))。 @TomaszNurkiewicz:我觉得有必要插嘴回答一个关于 NPE 的问题。 :) @NPE 为什么添加两个 Integer 对象需要拆箱? @Geek:因为 JLS 这么说:docs.oracle.com/javase/specs/jls/se7/html/…【参考方案2】:请注意,前三个+
运算符用法涉及字符串连接。只有最后一个是实际的数字sum。当涉及字符串连接时(涉及s
变量),Java 编译器使用一些巧妙的技巧来提高性能。它将+
运算符替换为StringBuilder
。例如,您的第一行被翻译为:
StringBuilder tmp = new StringBuilder();
tmp.append(s);
tmp.append(i);
System.out.println(tmp);
StringBuilder
是 null
友好的,所以无论你作为参数传递什么,它都会很好地用 "null"
字符串替换它。
最后一行的情况有所不同。在那里你引用了两个Integer
对象。 JVM 在这里唯一能做的就是将它们拆箱 (i.intValue()
) 并进行实际计算。 null
的拆箱导致NullPointerException
。
【讨论】:
【参考方案3】:任何与String
的连接(+
运算符)会产生String
。每个操作数首先转换为字符串(使用toString()
,或使用值"null"
),然后连接。
但是最后一个操作只涉及Integer
s,所以前面的规则不适用。它不是串联,而是加法。但是要添加两个Integer
s,它将对象(Integer
s)转换为原始值(int),如果Integer
为空,则这是不可能的。这就是您收到NullPointerException
的原因。
【讨论】:
1. 每个操作数首先转换为字符串 - 不,null.toString()
仍然抛出。 2.System.out.println()
接受Object
并处理null
很好,不需要toString()
。
我没有说应用了toString()
,而是将空值转换为包含“空”的字符串。也许我不够清楚,我同意:) 答案已更新。【参考方案4】:
似乎是自动拆箱的情况。如果您有两个Integer
s first
和second
,那么它们相加的结果将是first.intValue() + second.intValue()
。由于它们都为空,因此会导致 NPE。
【讨论】:
【参考方案5】:看看你的程序的字节码。您会注意到您的 null 对象作为参数传递给 PrintStream.print() 方法。 print()方法的源码使用了String.valueOf(),如下所示:
public static String valueOf(Object obj)
return (obj == null) ? "null" : obj.toString();
【讨论】:
【参考方案6】:需要注意的是,这个问题的答案应该已经从输出中显而易见了:
C:\Temp>java Test
nullnull
nullnull
nullnull
NullPointerException
【讨论】:
以上是关于Java中字符串和整数的空值的主要内容,如果未能解决你的问题,请参考以下文章
在 MySql 中,如何将 csv 文件中的 sql 字符串中的空值导出为双引号(“”)?