在使用String.valueOf()时,由于对该工具方法没有足够的了解,导致有一处代码出现了bug,在这里记录下来自己的采坑经历,出bug的业务代码跟下面代码中的case1和case2很相似。
public static void main(String[] args) {Map<String, Object> extendMap = buildExtendMap();//case1String value1 = String.valueOf(extendMap.get("key1"));System.out.println(value1);//case2String value2 = String.valueOf(extendMap.get("key3"));System.out.println(value2);//case3String value3 = String.valueOf(null);System.out.println(value3);//calse 4String 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的。
