在Java中使用null进行类型转换时没有异常


Answers:


323

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

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

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

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

为了避免混淆,如果不是特殊情况,则在null对象上调用任何方法都应引发null指针异常。


1
@JunedAhsan什么特殊情况会导致它不抛出NPE?
Holloway 2014年

@Trengot检查下面彼得回答中提到的一项。
Juned Ahsan 2014年

144

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

顺便说一句,在一个棘手的情况下,您似乎可以对null值调用静态方法。

Thread t = null;
t.yield(); // Calls static method Thread.yield() so this runs fine.

12
哇。如果被问到,我将百分百确定它将引发异常。确实是一个棘手的案例。
Magnilex

2
@Magnilex:绝对!这是一个典型的OCPJP考试技巧。
ccpizza

3
这不是因为编译器用字节码“优化” t.yield() -> Thread.yeld() 了吗?类似于如何final int i = 1; while (i == 1)优化while(true)
SGal '18年

@SGal更好,因为第二个优化不是强制性的AFAIK,而第一个则是强制性的。
Paul Stelian

36

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


谢谢!关于为引用变量分配null的这一说明确实很有帮助!
最多

22

对于以下重载方法的构造,需要重载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);

否则,您将无法调用所需的方法。


在大多数情况下,转换是隐式的,例如String bar = null;null值转换为String。到目前为止,我只需要在重载方法的测试中显式地转换为null,而我想使用null输入来测试其行为。不过,很高兴知道,在找到您之前,我将写一个类似的答案。
Vlasec

有趣的事实:l instanceof Longs instanceof String将返回false在这些情况下。
Attila Tanyi

7

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


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的参数。


2

打印

打印对象。String.valueOf(Object)方法产生的字符串转换为字节

ValueOf

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

当对象为时,它将仅返回一个值为“ null”的字符串null


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)

0

在这种情况下,此语言功能很方便。

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.