在使用String.valueOf()时,由于对该工具方法没有足够的了解,导致有一处代码出现了bug,在这里记录下来自己的采坑经历,出bug的业务代码跟下面代码中的case1和case2很相似。
public static void main(String[] args) {
Map<String, Object> extendMap = buildExtendMap();
//case1
String value1 = String.valueOf(extendMap.get("key1"));
System.out.println(value1);
//case2
String value2 = String.valueOf(extendMap.get("key3"));
System.out.println(value2);
//case3
String value3 = String.valueOf(null);
System.out.println(value3);
//calse 4
String value4 = (String) null;
System.out.println(null == value4);
}
public static Map<String, Object> buildExtendMap() {
Map<String, Object> extendMap = Maps.newHashMap();
extendMap.put("key1", "value1");
extendMap.put("key2", "value2");
return extendMap;
}
case1不用多说,大家应该都知道会返回”value1”。case2返回的值是”null”,当时就是在这里出的bug,看了源码之后恍然大悟,因为extendMap的value是Object类型,所以String.valueOf()自然而然的就会重载到对应的方法,方法的源码如下:
/**
* Returns the string representation of the {@code Object} argument.
*
* @param obj an {@code Object}.
* @return if the argument is {@code null}, then a string equal to
* {@code "null"}; otherwise, the value of
* {@code obj.toString()} is returned.
* @see java.lang.Object#toString()
*/
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
case3抛出空指针的异常,debug发现case3重载到String.value(char[] value)方法。为什么会重载到该方法,首先来看null属于什么类型,属于int\char\long\short\byte\boolean\double\float这八种基本类型吗?显然不是,那null就是对象,String.valueOf()提供了针对下面两种对象的重载,Java编译器会找到一个相近的方法去执行,首选valueOf(char data[])方法。
public static String valueOf(char data[]) {
return new String(data);
}
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
null可以转换为任何Java对象类型,所以(String)null也是ok的。