Java字符串中null和空字符串("")之间的区别

187

空值(null)和空字符串("")有什么区别?

我写了一些简单的代码:

String a = "";
String b = null;

System.out.println(a == b); // false
System.out.println(a.equals(b)); // false

这两个语句都返回false。看来,我找不到它们之间的实际区别。


7
b.equals(a)相比较--但不要使用==进行字符串比较,因为在其他方面"它不起作用"。null值(与空字符串 "" 不同,后者是有效的 String 实例)永远不能调用方法。将“已知非空”的值(通常是常量或文字)放在等式的左侧被称为“Yoda 条件语句”或类似的东西。 - user166390
22个回答

390

15
太好了!我正在向某人解释null和empty的区别,然后偶然发现了你的答案。这个概念立刻被他们理解了。 - mfcallahan
我看到左边有一张纸(没用的)。 - Michal - wereda-net
1
@Michal-wereda-net 这只是少于一个比特的大小 :-) 但是在挖掘内存使用情况时,我注意到该图实际上说明了另一种(尚且依赖于实现的)信息,即 null 和空字符串都需要相同的(内存)空间,由其指针占用:32 位为 4 字节,64 位为 8 字节。 - mikiqex
那太棒了 :-O - Parthan_akon

247

""是一个实际的字符串,虽然是空的。

null表示String变量指向了空值。

a==b返回false,因为""和null在内存中占据的空间不同--换句话说,它们的变量没有指向相同的对象。

a.equals(b)返回false,因为""显然不等于null。

区别在于,由于""是一个实际的字符串,您仍然可以对其调用方法或函数。

a.length()

a.substring(0, 1)

等等。

如果字符串为null,比如b,如果您尝试调用以下代码,Java将抛出NullPointerException:

NullPointerException

b.length()


如果你想知道的区别是 "==" 和 "equals",那么它们的区别在于:
"==" 比较引用,就像我这样做:

if (obj1 == obj2) {

String a = new String("");
String b = new String("");
System.out.println(a==b);

那会输出false,因为我分配了两个不同的对象,a和b指向不同的对象。
但是,在这种情况下a.equals(b)将返回true,因为字符串的equals方法只有在参数字符串不为空且表示相同字符序列 时才返回true
不过要注意的是,Java 对字符串有一个特殊情况。
String a = "abc";
String b = "abc";
System.out.println(a==b);

你会认为输出应该是false,因为它应该分配两个不同的字符串。实际上,Java会intern字面字符串(像我们示例中的a和b一样初始化的字符串)。所以要小心,因为这可能会导致==的一些误报。

这是否也适用于 C#?就像 "" 的数组是 {'\0'},表示空。 - Cole Tobin
3
关于“实习生”的链接已经失效。您可以参考另一个网站阅读相关内容:https://weblogs.java.net/blog/enicholas/archive/2006/06/all_about_inter.html。 - Alston
那么,如果我有一个空字符串 String a = null,然后我用 a+= "example" 追加 一个字符串,当我打印它时,为什么会显示 nullexample,因为 null 不是一个字符串? - cpinamtz
JavaScript 允许将非字符串添加到字符串中。"num: " + 20 将给出字符串 "num: 20"。这是否意味着 20 是一个字符串?(不是的,20 是一个数字)。对于 null 也是同样的情况:它不是一个字符串,但如果你尝试添加它,它可以被转换为一个字符串。 - daboross
@Zach L: 当String s = null+"a";时,它会输出nulla,但是null.concat("a")会抛出null指针异常。为什么在我第一个例子中null+"a";能正常工作呢? - Onic Team
null == "" = false(预期)但在语言的一些奇怪特性中,0 == "" = true(嗯嗯)。 - pstanton

18

1
"null表示String对象没有被实例化" - 谢谢!这帮助我更好地理解事物。有一次,我能够对MediaPlayer对象使用if语句,并且通过使用null来检查它是否正在运行(如果是,则执行相应的方法),但我从未理解为什么它起作用,现在我明白了,我是通过使用null来检查MediaPlayer是否已经被实例化或者没有被实例化...例如:if (mp==null){做某事} - Azurespot

14

你的语句告诉你的是 "" 不等于 null,这是正确的。"" 是一个空字符串;null意味着未分配任何值。

也许尝试以下代码会更有启发性:

System.out.println(a.length()); // 0
System.out.println(b.length()); // error; b is not an object

""仍然是一个字符串,这意味着你可以调用它的方法并获取有意义的信息。null是一个空变量 - 没有任何东西。


11

这两者之间有相当大的区别。空字符串""是“没有任何字符的字符串”。它是一个实际的字符串,具有明确定义的长度。所有标准的字符串操作都可以在空字符串上进行 - 您可以将其转换为小写,查找其中某个字符的索引等。而null字符串null是“根本没有字符串”。它没有长度,因为它根本不是一个字符串。尝试对null字符串应用任何标准的字符串操作都会在运行时导致NullPointerException


10
这里,a是一个对象,但b(null)不是一个对象,它是一个空引用。
System.out.println(a instanceof Object); // true

System.out.println(b instanceof Object); // false

这是我的类似答案,请点击这里

1
ab都是引用类型。a是一个具有实例化对象的引用,而b是一个没有实例化对象的引用(因此称为“空引用”)。 - JUST MY correct OPINION
我抵消了-1的影响;-) 但是更好的做法是澄清这个答案,讨论“对象”和null值之间的区别以及对象和变量之间的区别。 - user166390
@pst 谢谢 :) 我是凭心而答,因为这里有我另一个类似于这个问题的回答 https://dev59.com/RG855IYBdhLWcg3wPBtx#4459652 - user467871

9

null 表示名称没有引用任何已实例化的对象。 "" 表示空字符串。

这里 a 引用了一个对象,该对象恰好是一个空字符串。 b 不引用任何对象,因为它是 null。


8

6

在Java中,赋值为null的引用类型根本没有任何值。 赋值为""的字符串具有一个值:一个空字符串,也就是说,一个没有任何字符的字符串。 当变量赋值为null时,它意味着不存在任何基础对象,无论是字符串还是其他类型的对象。


5

""null是不同的。前者表示作为字符串变量声明的字符串常量已经在字符串池中创建,并且分配了一些内存。

但是,当我们使用null进行声明时,它只是被实例化到了JVM中,但没有为其分配任何内存。因此,如果您尝试通过检查具有""(空白)变量的对象来访问该对象,则可能会出现NullPointerException。请查看下面的一个用例。

public class StringCheck {

public static void main(String[] args) {
    // TODO Auto-generated method stub

    String s1 = "siddhartha";
    String s2 = "";
    String s3 = null;

    System.out.println("length s1 ="+s1.length());
    System.out.println("length s2 ="+s2.length());

    //this piece of code will still throw nullpointerexception . 
    if(s3 != ""){
        System.out.println("length s3 ="+s3.length());
    }
}

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接