cev*_*ing 53 java null nullpointerexception
看一下下面的例子:
class nul
{
public static void main (String[] args)
{
System.out.println (String.valueOf((Object)null));
System.out.println (String.valueOf(null));
}
}
Run Code Online (Sandbox Code Playgroud)
第一次println写,null但第二次抛出a NullPointerException.
为什么只有第二行值得例外?那两个nulls有什么区别?Java中是真的 null还是假 null的?
Roh*_*ain 56
第一次调用将调用该String.valueOf(Object)方法,因为您已明确地进行了类型化null的Object引用.相反地,第二个将调用重载String.valueOf(char[])方法中,作为char[]比更具体Object为一个null参数.
此方法的其他重载版本接受原始参数,但这些参数不是参数的有效匹配null.
来自JLS§15.12.2:
可能存在多于一种这样的方法,在这种情况下,选择最具体的方法.最具体方法的描述符(签名加返回类型)是在运行时用于执行方法分派的方法.
如果方法适用于子类型(第15.12.2.2节),适用于方法调用转换(第15.12.2.3节),或者它是适用的变量方法(第15.12.2.4节),则该方法适用.
[...]
如果在适用性测试的三个阶段之一中确定了几种适用的方法,则选择最具体的方法,如第15.12.2.5节所述.
现在检查两种方法的源代码:
// This won't throw NPE for `obj == null`
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
// This will throw `NPE` for `data == null`
public static String valueOf(char data[]) {
return new String(data);
}
Run Code Online (Sandbox Code Playgroud)
Bor*_*der 16
String.valueOfJava中有很多重载方法.此外,在Java中null有任何和所有类型,以便任何东西(不是原始的)都可以null.
因此,当您调用时(String.valueOf((Object)null),调用将显式强制转换为使用的valueOf方法.ObjectnullObject
在第二个示例中,您没有显式地转换null为任何特定类型,因此实际上您valueOf使用char[]抛出NPE 的方法调用该方法.
第二步搜索上一步中为成员方法确定的类型.此步骤使用方法的名称和参数表达式的类型来定位可访问和适用的方法,即可以在给定参数上正确调用的声明.
可能存在多于一种这样的方法,在这种情况下,选择最具体的方法.最具体方法的描述符(签名加返回类型)是在运行时用于执行方法分派的方法.
在这种情况下char[]是更具体的比Object,所以当没有明确投它被称为null而成.
虽然我已经接受了一个答案,但我想补充问题的确切答案,因为这两个答案集中在解释我走进的陷阱.
(Object)null和之间的区别null是第一个的类型被强制,Object但第二个的类型不是,正如人们所能想到的那样,被迫Object.相反,它也可以是数组而不是对象.
所以结论是:传递(Object)null而不是null作为方法的参数,以确保完全获得处理对象的方法而不是任何其他处理数组的方法.