为什么Java将null引用转换为字符串“null”?

为什么Java将null引用转换为字符串“null”?,java,string,Java,String,在Java中,如果我写: System.out.printlnString null;,我得到空值 这似乎很奇怪。有人知道设计师为什么选择这种方法吗?在我看来,这是一个无中生有的例子。我读过这本书,上面写着: 强制转换表达式的类型是将捕获转换§5.1.10应用于名称出现在括号内的类型的结果。 强制转换表达式的结果不是变量,而是值,即使操作数表达式的结果是变量也是如此 跳转到,我看到为泛型类型定义了捕获转换,但条目添加了: 除参数化类型§4.5外的任何类型上的捕获转换作为身份转换§5.1.1 好的

在Java中,如果我写: System.out.printlnString null;,我得到空值

这似乎很奇怪。有人知道设计师为什么选择这种方法吗?在我看来,这是一个无中生有的例子。我读过这本书,上面写着:

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

跳转到,我看到为泛型类型定义了捕获转换,但条目添加了:

除参数化类型§4.5外的任何类型上的捕获转换作为身份转换§5.1.1

好的!在地图上,有这样一个:

任何类型都允许从一个类型转换为同一类型

在本例中,类型是String,但要转换的东西是null,这让我感到困惑。然而,事实证明Java实际上使用字符串转换来表示字符串null。联合联络小组说:

任何类型都可以通过字符串转换转换为字符串类型。。。 如果引用为null,则将其转换为null字符串—四个ASCII字符n、u、l、l

这引起的一个问题是:

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

程序打印空值。我怎么知道是不是因为条目为null,而HashMap中的字符串的值为null四个ASCII字符'n','u','l','l'?现在我知道有人会说Java不鼓励使用,类型HashMap应该参数化,但这就是解决方案吗

你想得太多了。Java没有将值null转换为字符串null。正确的答案是,这只是该方法的一个显式行为:

打印一个字符串,然后终止该行。此方法的行为就像调用printString,然后调用println一样

下一步,我们要讨论的是:

打印字符串。如果参数为null,则打印字符串null。否则,字符串的字符将根据平台的默认字符编码转换为字节,并且这些字节完全按照writeint方法的方式写入

记住,System.out的类型是

程序打印空值。我怎么知道是不是因为 条目为null,而HashMap中的字符串的值为null 四个ASCII字符“n”、“u”、“l”、“l”

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

它与强制转换无关,但与打印有关:如果将null强制转换为字符串,它仍然是null:

所以,只要通过程序执行直接比较,就可以轻松地检查映射、集合或任何API返回的值是否为null

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


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

你希望它做什么呢?可能抛出NullPointerExceptionEverybody使用System.out.println进行调试;如果一个用于调试的主要工具本身抛出异常,那么它就不会运行良好。“这是一个务实的选择,让实际的事情不那么令人惊讶,而不是完全合乎逻辑的事情。”路易斯瓦瑟曼我甚至可以说,一般来说,推出NPE是没有意义的。调用.print的目的是通常在CLI或文件中以文本形式显示某些内容。它可以是一个数字,可以是一个字符串,可以是一个自定义对象。值null与概念视图中的任何值都没有什么不同——它只是一些值。它表示没有值这一事实与此无关——就打印功能而言,这不是一个错误。这是一个将被放置在某处的符号。让一个符号引发一个错误条件是很奇怪的。我认为他希望在没有
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
String s=(String)null;
if (s==null)
{
    System.out.println("It is still a null");
}
else
{
    throw new RuntimeException("This won't happen");
}