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字符null)。

因此没有 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);

StringBuildernull 友好的,所以无论你作为参数传递什么,它都会很好地用 "null" 字符串替换它。

最后一行的情况有所不同。在那里你引用了两个Integer 对象。 JVM 在这里唯一能做的就是将它们拆箱 (i.intValue()) 并进行实际计算。 null 的拆箱导致NullPointerException

【讨论】:

【参考方案3】:

任何与String 的连接(+ 运算符)会产生String。每个操作数首先转换为字符串(使用toString(),或使用值"null"),然后连接。

但是最后一个操作只涉及Integers,所以前面的规则不适用。它不是串联,而是加法。但是要添加两个Integers,它将对象(Integers)转换为原始值(int),如果Integer 为空,则这是不可能的。这就是您收到NullPointerException 的原因。

【讨论】:

1. 每个操作数首先转换为字符串 - 不,null.toString() 仍然抛出。 2.System.out.println() 接受Object 并处理null 很好,不需要toString() 我没有说应用了toString(),而是将空值转换为包含“空”的字符串。也许我不够清楚,我同意:) 答案已更新。【参考方案4】:

似乎是自动拆箱的情况。如果您有两个Integers firstsecond,那么它们相加的结果将是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中字符串和整数的空值的主要内容,如果未能解决你的问题,请参考以下文章

c语言中怎样给整型和字符型赋空值(NULL)

在 MySql 中,如何将 csv 文件中的 sql 字符串中的空值导出为双引号(“”)?

std::string 可以包含嵌入的空值吗?

如何使用NSwag防止查询字符串中的空值

如何从列类型列表中删除 pandas DataFrame 中的空值

ES11中的空值合并运算符