是否存在以下行为的逻辑语言设计类型解释(Java 7和我怀疑早期版本):
Object a = null;
String as = String.valueOf(a); // as is assigned "null"
System.out.println(as+":"+as.length()); // prints: "null:4"
System.out.println ( String.valueOf(null)); // NPE
Run Code Online (Sandbox Code Playgroud)
Tom*_*Tom 42
在语句中System.out.println(String.valueOf(null));
有一个方法调用public static String valueOf(char data[])
,源代码如下:
public static String valueOf(char data[]) {
return new String(data);
}
Run Code Online (Sandbox Code Playgroud)
这就是你获得NPE的原因
另一方面,在语句中Object a = null; String as = String.valueOf(a);
有一个方法调用public static String valueOf(Object obj)
,源代码如下:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
Run Code Online (Sandbox Code Playgroud)
这就是为什么你得到"null"而不是NPE
Java语言规范中的一点理论:15.12.2.5选择最具体的方法
如果多个成员方法都可访问并适用于方法调用,则必须选择一个为运行时方法调度提供描述符.Java编程语言使用选择最具体方法的规则.
A char[]
是类型Object
,但不是所有Object
类型char[]
.型char[]
是更具体的比对象和作为Java语言规范所描述的,String.valueOf(char[])
过载被选择在这种情况下.
编辑
值得一提的是Ian Roberts提到的内容(在下面的评论中):
需要注意的是这是一个编译错误,如果没有一个统一的超载比所有其他更具体的是很重要的-如果有一个
valueOf(String)
方法,以及valueOf(Object)
和valueOf(char[])
随后的非类型化的调用String.valueOf(null)
是不明确
Avi*_*gal 15
第一次调用是String#valueOf(Object)
,第二次调用是String#valueOf(char[])
根据参数的静态类型选择重载方法,这就是第一个工作而秒获得NPE的原因.
如果你调用System.out.println ( String.valueOf((Object)null));
它将工作
那是因为String
课堂上的这段代码:
public static String valueOf(char data[]) {
return new String(data);
}
Run Code Online (Sandbox Code Playgroud)
你的代码(抛出NullPointerException
)调用上面提到的方法,因此,data
字段是null
.实际上,这个调用是由String
类在构造函数上抛出的.
使用JDK 6,例外情况如下:
java.lang.NullPointerException
at java.lang.String.<init>(String.java:177)
at java.lang.String.valueOf(String.java:2840)
at org.bfs.data.SQLTexter.main(SQLTexter.java:364)
Run Code Online (Sandbox Code Playgroud)
至于你的行:
System.out.println(as+":"+as.length()); // prints: "null:4"
Run Code Online (Sandbox Code Playgroud)
这适用于以下方法:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
Run Code Online (Sandbox Code Playgroud)
显然,a
类型是Object
这样的String.valueOf(Object)
方法被调用.
如果您特别想调用String.valueOf(Object obj)
方法,请按如下方式对null进行类型转换:
System.out.println (String.valueOf((Object)null));
Run Code Online (Sandbox Code Playgroud)
您遇到了方法重载(其中有多个方法具有相同的名称和方法签名,但具有不同的方法参数).在您的情况下(发生NPE),JVM根据最具体的静态类型确定调用哪个方法.如果声明了类型,则最具体的方法是具有相同参数类型的声明变量的方法,否则,JVM使用最具体的方法规则来查找要调用的方法.
我希望这有帮助.
归档时间: |
|
查看次数: |
8158 次 |
最近记录: |