示例代码如下:
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“字符串.程序不会报错
第二种情况,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异常