示例代码如下:
TreeMap<String,Object> ttt = new TreeMap<String,Object>();
if(ttt.get("xxxx") == null){
System.out.println(String.valueOf(ttt.get("xxxx"))); //程序运行这里没报错
}
System.out.println(String.valueOf(null)); //程序运行这里报错了NPE异常
可以先思考下
对于第一种情况:String.valueOf(ttt.get(“xxxx”)) 这个比较好解释,ttt.get(“xxxx”)返回的是一个map中存放的object对象。所以最后走的是如下这个方法:空对象,会返回一个”null“字符串.程序不会报错
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
第二种情况,String.valueOf(null),这个valueOf我们可以用开发工具如IDEA点进去看,走的是:
// 第1步
public static String valueOf(char data[]) {
return new String(data);
}
// 第1步
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
// 第1步
public static char[] copyOf(char[] original, int newLength) {
char[] copy = new char[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength)); // 出错
return copy;
}
为什么会走到这里,而不是走String valueOf(Object obj) ?
翻看String的类库,可以看到String.valueOf有如下几种方法:
这其中,红框以内的方法都是接受基本类型,null不是基本类型,所以最后能接受String.valueOf(null)的只有,String valueOf(Object obj) 和 String valueOf(char data[]) (注意参数是char数组,不是char),因为char [] 比object更加精确,所以会选择走String valueOf(char data[])
这两个都能接受null入参,这种情况下,java的重载会选取其中更精确的一个,所谓精确就是,重载方法A和B,如果方法A的入参是B的入参的子集,则,A比B更精确,重载就会选择A。换成上面这两个就是,char[]入参的比object的更精确,因为object包含char[],所以String.valueOf(null)是用char[]入参这个重载方法。
最后进入String valueOf(char data[]) 方法中,会发现如下代码:
这里会出现NPE异常