【问题标题】:Difference between null and empty ("") Java Stringnull 和空 ("") Java 字符串之间的区别
【发布时间】:2011-06-15 16:18:04
【问题描述】:

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

我写了一些简单的代码:

String a = "";
String b = null;

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

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

【问题讨论】:

  • b.equals(a)比较——但不要使用==进行字符串比较,因为在其他方面“它不起作用”。 null 值(与空字符串 "" 不同,它是一个有效的 String 实例)可以永远在其上调用方法。将“已知的非空值”(通常是常量值或文字)放在等式的左侧是“尤达条件”或类似的东西。

标签: java string null equals referenceequals


【解决方案1】:

你也可以这样理解 null 和空字符串的区别:

Original image by R. Sato (@raysato)

【讨论】:

  • 这太棒了!我正在向某人解释 null vs empty 并且发生在您的回答中。这个概念立即引起了他们的注意。
  • 我在左边看到一篇论文(没用):)
  • @Michal-wereda-net 这将少于一点:-) 但是在内存使用情况下我注意到图像实际上说明了另一个(但依赖于实现)信息,即 null 和空字符串需要相同的(内存)空间,由其指针占用:32 位为 4 个字节,64 位为 8 个字节。
  • 被点亮 :-O
【解决方案2】:

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

然而,null 意味着 String 变量不指向任何内容。

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

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

不同之处在于,由于 "" 是一个实际的字符串,您仍然可以像调用它一样调用方法或函数

a.length()

a.substring(0, 1)

等等。

如果 String 等于 null,比如 b,如果你尝试调用,Java 会抛出 NullPointerException,比如:

b.length()


如果你想知道的区别是 == 与 equals,那就是:

== 比较参考,就像我去了

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

那会输出 false,因为我分配了两个不同的对象,并且 a 和 b 指向不同的对象。

但是,在这种情况下,a.equals(b) 将返回 true,因为字符串的 equals 将返回 true if and only if the argument String is not null and represents the same sequence of characters.

但请注意,Java 确实有字符串的特殊情况。

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

你会认为输出是false,因为它应该分配两个不同的字符串。实际上,Java 将 intern 文字字符串(在我们的示例中初始化为 a 和 b)。所以要小心,因为这会对 == 的工作方式产生一些误报。

【讨论】:

  • 这是否也适用于 C#?如""的数组是{'\0'},一个null
  • intern 的链接已过期。你可以参考另一个网站来阅读它:weblogs.java.net/blog/enicholas/archive/2006/06/…
  • 所以,如果我有一个空字符串String a = null,然后我附加它是一个像a+= "example" 这样的字符串,当我打印它时,为什么会显示nullexample if null 不是字符串?
  • @PinaGamer JavaScript 允许向字符串添加非字符串。 "num: " + 20 为您提供字符串 "num: 20"。这是否意味着20 是一个字符串? (不是,20 是一个数字)。 null 的情况相同:它不是一个字符串,但如果你尝试添加它,它可以转换为一个。
  • @Zach L : 当 String s = null+"a";它给出了输出 nulla 但 null.concat("a") 它给出了空指针异常。在我的第一种情况下 null+"a" 的原因是什么?正在工作。
【解决方案3】:

String 是一个 Object,可以为 null

null 表示字符串对象没有被实例化

"" 是实例化对象字符串的实际值,如 "aaa"

这里有一个链接可以澄清这一点http://download.oracle.com/javase/tutorial/java/concepts/object.html

【讨论】:

  • "null 表示未实例化字符串对象" - 谢谢!这有助于我理解很多事情。我曾经能够在 MediaPlayer 对象上使用 if 语句,并且它可以使用 null 来检查它是否正在运行(如果运行,则使用执行方法),但我不明白它为什么会起作用,但现在我明白它在说什么,我正在检查 MediaPlayer 是否已被实例化,通过使用 null...例如if (mp==null){do something}
【解决方案4】:

您的陈述告诉您的是,"" 与 null 不同——这是真的。 "" 是一个空字符串; null 表示没有赋值。

尝试一下可能更有启发性:

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

"" 仍然是一个字符串,这意味着您可以调用它的方法并获取有意义的信息。 null 是一个空变量——那里实际上什么都没有。

【讨论】:

    【解决方案5】:

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

    【讨论】:

      【解决方案6】:

      这里是a is an Objectb(null) 不是一个对象,它是一个空引用

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

      here is我的类似回答

      【讨论】:

      • ab 都是引用。 a 是带有实例化对象的引用。 b 是没有实例化对象的引用(因此称为“空引用”)。
      • 我反驳了 -1 ;-) 但这将有助于澄清这个答案并讨论“对象”和 null 值之间的区别以及对象和变量之间的区别。
      • @pst 谢谢 :) 我用心回答,因为这是我的另一个答案,类似于这个问题stackoverflow.com/questions/4459623/…
      【解决方案7】:

      null 表示该名称未引用任何实例化对象。 "" 表示空字符串。

      这里 a 正在引用一些恰好是空字符串的对象。 b 没有引用任何对象,因为它是空的。

      【讨论】:

        【解决方案8】:

        在 Java 中,分配给 null 的引用类型根本没有价值。分配给"" 的字符串有一个值:一个空字符串,也就是说一个没有字符的字符串。当一个变量被赋值为null 时,这意味着没有任何类型的底层对象,字符串或其他。

        【讨论】:

          【解决方案9】:

          ""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());
              }
          }
          

          }

          【讨论】:

            【解决方案10】:
            String s = "";
            s.length();
            
            String s = null;
            s.length();
            

            对空字符串"" 的引用指向堆中的一个对象——因此您可以在其上调用方法。

            但是指向null 的引用没有指向堆中的对象,因此您将获得NullPointerException

            【讨论】:

              【解决方案11】:

              这张图片可能会帮助您了解这些差异。

              图片来自ProgrammerHumor

              【讨论】:

                【解决方案12】:

                空字符串不同于a 在那个中的空引用 面向对象的程序设计语言 对字符串类型的空引用 不指向字符串对象并且 将导致错误是一个尝试 对其进行任何操作。空的 字符串仍然是一个字符串 可以尝试字符串操作。

                来自empty string 上的维基百科文章。

                【讨论】:

                  【解决方案13】:

                  String s=null;

                  字符串未初始化为 null。如果尝试了任何字符串操作,它可能会抛出空指针异常

                  String t="null";

                  它是一个字符串字面量,其值为字符串 "null",与 t = "xyz" 相同。它不会抛出空指针。

                  String u="";

                  为空字符串,不会抛出空指针。

                  【讨论】:

                    【解决方案14】:

                    字符串可以为空或具有null 值。如果一个字符串是null,它并不是指内存中的任何东西。试试s.length()>0。这是因为如果字符串为空,它仍然返回长度 0。因此,如果您没有输入相同的内容,那么它仍然会继续循环,因为它没有将字符串注册为null。而如果您检查长度,那么它将退出它的循环。

                    【讨论】:

                      【解决方案15】:

                      这个概念可以从数学中更好地理解。您是否曾尝试使用计算器(例如 7/0)将数字(非零)除以 0?您将得到如下所示的结果:undefinednot a numbernull 等。这意味着由于某些原因,该操作是不可能的(让我们改天讨论这些原因)。

                      现在,执行此操作:0/7。您将得到输出 0。这意味着该操作是可能的并且可以执行,但您的答案只是 0,因为除法之后什么都没有。有一个有效的输出并且该输出为零。

                      在第一个示例中,不仅输出无效,操作也无法执行。这类似于 java 中的null 字符串。第二个示例类似于empty 字符串。

                      【讨论】:

                        【解决方案16】:

                        当你写作时

                        String a = "";

                        这意味着有一个字符串类型的变量'a'指向字符串池中的对象引用,其值为“”。由于变量a 持有一个有效的字符串对象引用,所有字符串的方法都可以在这里应用。

                        而当你写作时

                        String b = null;

                        这意味着有一个字符串类型的变量b 指向一个未知引用。并且对未知引用的任何操作都会导致NullPointerException

                        现在,让我们评估以下表达式。

                        System.out.println(a == b); // false. because a and b both points to different object reference
                        
                        System.out.println(a.equals(b)); // false, because the values at object reference pointed by a and b do not match.
                        
                        System.out.println(b.equals(a)); // NullPointerException, because b is pointing to unknown reference and no operation is allowed
                        

                        【讨论】:

                          【解决方案17】:

                          简单来说,

                          • "" 是一个空的字符串

                          • null 是一个空的字符串变量

                          【讨论】:

                            【解决方案18】:

                            空字符串和空字符串的区别。例如:您有一个名为 x 的变量。如果你用JS写,

                            var x = "";

                            这意味着您分配了一个空字符串(长度为 0)的值。实际上,这就像某种东西,但毫无意义:)另一方面,

                            var y = null;

                            这意味着您没有为 y 分配一个值,这在声明时通过将 null 写入 y 来明确表示。如果你写 y.length;它将抛出一个错误,表明没有为 y 分配值,因此无法读取 y 的长度。

                            【讨论】:

                            • 问题是针对 Java 的
                            【解决方案19】:

                            “我称之为十亿美元的错误。它是 1965 年空引用的发明” - https://en.wikipedia.org/wiki/Tony_Hoare

                            对于现实世界,两者都可以假设为相同。它只是一种编程语言的语法,它在两者之间产生了差异,正如其他人在此处所解释的那样。这只会产生开销,例如在检查/比较字符串变量是否具有某些内容时,您必须首先检查它是否不为空,然后进行实际字符串比较,即两次比较。这对于每个字符串比较来说都是一种处理能力的浪费。

                            Objects.equals() 在调用 .equals() 之前检查 null。

                            【讨论】:

                              【解决方案20】:

                              出于好奇

                                  String s1 = null;
                                  String s2 = "hello";
                              
                                   s1 = s1 + s2;
                                 
                              
                                  System.out.println((s); // nullhello
                              

                              【讨论】:

                                【解决方案21】:

                                null 没有任何意义;这意味着您从未为变量设置值,但为空意味着您已将“”值设置为 String,例如,请参见以下示例:

                                String str1;
                                String str2 = "";
                                

                                这里str1null 意味着您已经定义了它但尚未为其设置任何值,但是您已经定义了str2 并为其设置了空值,因此即使该值为“”,它也有一个值;

                                但是

                                【讨论】:

                                  【解决方案22】:

                                  惊人的答案,但我想从不同的角度给出。

                                  String a = "StackOverflow";
                                  String a1 = "StackOverflow" + "";
                                  String a2 = "StackOverflow" + null;
                                  
                                  System.out.println(a == a1); // true
                                  System.out.println(a == a2); // false
                                  
                                  

                                  所以这可以告诉我们 "" 和 null 指向不同的对象引用。

                                  【讨论】:

                                    猜你喜欢
                                    • 2020-06-14
                                    • 2017-01-29
                                    • 1970-01-01
                                    • 2014-06-17
                                    • 2023-03-14
                                    • 2013-05-26
                                    • 1970-01-01
                                    • 2016-08-16
                                    • 1970-01-01
                                    相关资源
                                    最近更新 更多