这个问题很有意思
第一句可以打印出null,但是第二句报空指针异常。
造成这种区别的原因在于两者选取了不同的重载方法。
Java的重载过程分两个阶段。
第一阶段选取所有可获得并且可应用的方法或构造器。看一下String.valueOf()源码,有以下几个重载方法可供选择:
因为基本类型不能赋于null,所以可供选择的方法只有valueOf(char data[])和 valueOf(Object obj)。
第二阶段在第一阶段选取的方法或构造器中选取最精确的一个,如果一个方法或构造器可以接受传递给另一个方法或构造器的任何参数,那么我们就说第一个方法比第二个方法缺乏精确性。方法valueOf(Object obj)可以接收任何传给valueOf(char data[])的参数,我们说方法valueOf(Object obj)相对方法valueOf(char data[])缺乏精确性,所以在重载时会选择方法valueOf(char data[])。
对于方法①
显然会直接返回“null”
对于方法②
再看对应的String构造方法:
运行到※处时,会抛出空指针异常。
如果将调用代码修改如下:
重载时将会选择valueOf(Object obj)方法,就能回避这个异常。
另一方面想说一下obj是一个引用,不过赋值为null之后就不引用任何东西了。
但毕竟与null不同,null是一个特殊的变量,它什么都不是既不是0,也不是空对象,就是什么都没有。
Object obj = null;
System.out.println(String.valueOf(obj));
System.out.println(String.valueOf(null));
第一句可以打印出null,但是第二句报空指针异常。
造成这种区别的原因在于两者选取了不同的重载方法。
Java的重载过程分两个阶段。
第一阶段选取所有可获得并且可应用的方法或构造器。看一下String.valueOf()源码,有以下几个重载方法可供选择:
String valueOf(Object obj) //①
String valueOf(char data[]) //②
String valueOf(boolean b)
String valueOf(char c)
...
因为基本类型不能赋于null,所以可供选择的方法只有valueOf(char data[])和 valueOf(Object obj)。
第二阶段在第一阶段选取的方法或构造器中选取最精确的一个,如果一个方法或构造器可以接受传递给另一个方法或构造器的任何参数,那么我们就说第一个方法比第二个方法缺乏精确性。方法valueOf(Object obj)可以接收任何传给valueOf(char data[])的参数,我们说方法valueOf(Object obj)相对方法valueOf(char data[])缺乏精确性,所以在重载时会选择方法valueOf(char data[])。
对于方法①
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
显然会直接返回“null”
对于方法②
public static String valueOf(char data[]) {
return new String(data);
}
再看对应的String构造方法:
public String(char value[]) {
this.offset = 0;
this.count = value.length; //※
this.value = StringValue.from(value);
}
运行到※处时,会抛出空指针异常。
如果将调用代码修改如下:
value = String.valueOf((Object)null);
重载时将会选择valueOf(Object obj)方法,就能回避这个异常。
另一方面想说一下obj是一个引用,不过赋值为null之后就不引用任何东西了。
但毕竟与null不同,null是一个特殊的变量,它什么都不是既不是0,也不是空对象,就是什么都没有。