为什么Java将空引用转换为String“null”?

时间:2016-09-08 22:50:01

标签: java string

在Java中,如果我写:
function Cat(name) { this.Name = name || "Cat"; } var x = new Cat("kitty"); function PetTheCat(cat) { /// <param name='cat' type='Cat' /> console.log(cat.Name + " is purring!"); } ,我得System.out.println((String) null);

这看起来很奇怪。有谁知道为什么设计师选择这种方法?在我看来,这是一个“无中生有”的案例。我读过JLS entry on cast operators,并说:

  

强制转换表达式的类型是将捕获转换(第5.1.10节)应用于其名称出现在括号内的类型的结果。
  即使操作数表达式的结果是变量,转换表达式的结果也不是变量,而是值。

跳转到entry on capture conversion,我看到为泛型类型定义的捕获转换,但该条目添加:

  

除参数化类型(第4.5节)以外的任何类型的捕获转换都充当身份转换(第5.1.1节)。

好!在entry on identity conversion上,就是这个:

  

任何类型都允许从类型转换为相同类型。

在这种情况下,类型为"null",但要转换的内容为String,这让我感到困惑。但是,事实证明Java实际上正在为null使用字符串转换。 JLS entry on String conversion说:

  

任何类型都可以通过字符串转换转换为String类型...
  如果引用为null,则将其转换为字符串“null”(四个ASCII字符n,u,l,l)。

这引起的一个问题是:

(String) null

该程序打印HashMap map = new HashMap(); System.out.println((String)map.get("something")); 。我如何知道是否因为条目"null"而不是HashMap中的字符串值为“null”(四个ASCII字符'n','u','l','l')?现在我知道有人会说Java不鼓励使用raw types,并且类型null应该参数化但是解决方案是什么?

3 个答案:

答案 0 :(得分:-1)

你正在思考这个问题。 Java没有将(值)null转换为(字符串)"null"。正确的答案是,这只是PrintStream.println(String)方法的明确行为:

  

打印字符串然后终止该行。此方法的行为就像调用print(String)然后调用println()

接下来,我们会咨询PrintStream.print(String)所说的内容:

  

打印一个字符串。如果参数为null,则打印字符串"null"。否则,字符串的字符将根据平台的默认字符编码转换为字节,并且这些字节的编写方式与write(int)方法完全相同。

(请注意,System.out的类型为PrintStream。)

答案 1 :(得分:-1)

HashMap map = new HashMap();
System.out.println((String)map.get("something"));
     

该程序打印"null"。我怎么知道是不是因为   entry为null,而HashMap中的String值为&#34; null&#34;   (四个ASCII字符&#39; n&#39;,&#39; u&#39;,&#39; l&#39;,&#39; l&#39;)?

null"null"之间仍然存在差异,当您使用System.out.println打印出来时,您无法看到它们。他们的价值观不同,他们的确有不同的比较:

HashMap map = new HashMap();
map.put("foo", "null");
String something = (String) map.get("something");
String foo = (String) map.get("foo");
System.out.println(something == null); // true
System.out.println(foo == null); // false
System.out.println("null".equals(something)); // false
System.out.println("null".equals(foo)); // true

答案 2 :(得分:-1)

它与转换无关,但与打印无关:如果将null转换为String,它仍然是null

String s=(String)null;
if (s==null)
{
    System.out.println("It is still a null");
}
else
{
    throw new RuntimeException("This won't happen");
}

因此,检查Map,Collection或任何API返回的值是否为空,您应该没有任何困难,只需按程序执行直接比较

另一方面,永远不要相信PrintStream(作为System.out)直接打印到标准输出的结果。请参阅PrintStream.print(String)的文档。

此外:打印数字或布尔值时会出现同样的歧义:如果在标准输出“123”上看到,它是数字值还是字符串值?我坚持认为:要检查值,永远不要相信打印到PrintStream的字符串的外观。