261
String x = (String) null;

为什么这个说法没有例外?

String x = null;
System.out.println(x);

它打印null。但是.toString()方法应该抛出一个空指针异常。

4

10 回答 10

363

您可以强制null转换为任何引用类型而不会出现任何异常。

println方法不会抛出空指针,因为它首先检查对象是否为空。如果为 null 那么它只是打印字符串"null"。否则它将调用该toString对象的方法。

添加更多细节:内部打印方法调用String.valueOf(object)输入对象的方法。在valueOf方法中,这个检查有助于避免空指针异常:

return (obj == null) ? "null" : obj.toString();

对于其余的混淆,如果不是特殊情况,对空对象调用任何方法都应该引发空指针异常。

于 2013-09-10T15:57:23.803 回答
156

您可以null转换为任何引用类型。您还可以调用将 anull作为参数处理的方法,例如System.out.println(Object)确实如此,但您不能引用一个null值并在其上调用一个方法。

顺便说一句,有一种棘手的情况,您可以在null值上调用静态方法。

Thread t = null;
t.yield(); // Calls static method Thread.yield() so this runs fine.
于 2013-09-10T15:58:47.450 回答
41

这是设计使然。您可以null转换为任何引用类型。否则,您将无法将其分配给引用变量。

于 2013-09-10T15:57:04.610 回答
24

在方法重载的以下构造中需要强制转换 null 值,如果将 null 传递给这些重载的方法,则编译器不知道如何消除歧义,因此在这些情况下我们需要对 null 进行类型转换:

class A {
  public void foo(Long l) {
    // do something with l
  }
  public void foo(String s) {
    // do something with s      
  }
}
new A().foo((String)null);
new A().foo((Long)null);

否则你不能调用你需要的方法。

于 2015-01-23T19:16:44.170 回答
8

Println(Object)用途String.valueOf()

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

Print(String)做空检查。

public void print(String s) {
    if (s == null) {
        s = "null";
    }
    write(s);
}
于 2013-09-10T15:56:36.893 回答
7

这里的很多答案已经提到

您可以将 null 转换为任何引用类型

如果参数为 null,则字符串等于“null”

我想知道它是在哪里指定的,并查看了 Java 规范:

空引用始终可以分配或强制转换为任何引用类型(§5.2、§5.3、§5.5)。

如果引用为 null,则将其转换为字符串“null”(四个 ASCII 字符 n、u、l、l)。

于 2017-08-17T09:19:00.047 回答
3

正如其他人所写,您可以将 null 转换为所有内容。通常,你不需要那个,你可以写:

String nullString = null;

没有把演员表放在那里。

但在某些情况下,这样的演员表是有意义的:

a)如果您想确保调用特定方法,例如:

void foo(String bar) {  ... }
void foo(Object bar) {  ... }

那么如果你输入它会有所不同

foo((String) null) vs. foo(null)

b) 如果您打算使用您的 IDE 来生成代码;例如,我通常编写单元测试,例如:

@Test(expected=NullPointerException.class)
public testCtorWithNullWhatever() {
    new MyClassUnderTest((Whatever) null);
}

我正在做 TDD;这意味着“MyClassUnderTest”类可能还不存在。通过写下该代码,我可以使用我的 IDE 首先生成新类;然后生成一个接受“开箱即用”的“Whatever”参数的构造函数 - IDE 可以从我的测试中得出结论,构造函数应该只采用一个类型为“Whatever”的参数。

于 2016-04-13T08:01:41.877 回答
3

这种语言特性在这种情况下很方便。

public String getName() {
  return (String) memberHashMap.get("Name");
}

如果 memberHashMap.get("Name") 返回 null,您仍然希望上面的方法返回 null 而不会引发异常。无论是什么类,null 都是 null。

于 2019-02-01T01:02:21.150 回答
2

打印

打印一个对象。String.valueOf(Object) 方法产生的字符串被翻译成字节

价值

如果参数为空,则字符串等于“空”;否则,返回 obj.toString() 的值。

当对象为null.

于 2013-09-10T15:57:30.323 回答
2

这在使用否则会模棱两可的方法时非常方便。例如: JDialog 的构造函数具有以下签名:

JDialog(Frame, String, boolean, GraphicsConfiguration)
JDialog(Dialog, String, boolean, GraphicsConfiguration)

我需要使用这个构造函数,因为我想设置 GraphicsConfiguration,但是我没有这个对话框的父级,所以第一个参数应该为 null。使用

JDialog(null, String, boolean, Graphicsconfiguration) 

是模棱两可的,所以在这种情况下,我可以通过将 null 转换为支持的类型之一来缩小调用范围:

JDialog((Frame) null, String, boolean, GraphicsConfiguration)
于 2015-07-23T07:22:03.823 回答