说说JDK中的String.valueOf()传null的诡异处理【转】

都说JDK的实现诡异多,今儿也算是被我踩到一个坑了。java

就来讲说关于String.valueOf的这个坑。this

复制代码
 1 public class TestString {
 2     
 3     public static void main(String[] args){
 4         
 5         Object obj = null;
 6         System.out.println(String.valueOf(obj));
 7         System.out.println(String.valueOf(null));
 8     }
 9 }
复制代码

这段代码,第一个输出“null”,没错,不是空对象null也不是空串“”,而是一个字符串!!包含四个字母n-u-l-l的字符串...spa

好吧,我只能说写这个逻辑的人估计是想逗咱们玩儿...指针

第二个输出,咋一看没差异,可是,第二个输出,抛空指针异常了。code

下面来分析分析缘由。对象

先说第一个:blog

看第一个的源码实现:字符串

复制代码
 1     /**
 2      * Returns the string representation of the <code>Object</code> argument.
 3      *
 4      * @param   obj   an <code>Object</code>.
 5      * @return  if the argument is <code>null</code>, then a string equal to
 6      *          <code>"null"</code>; otherwise, the value of
 7      *          <code>obj.toString()</code> is returned.
 8      * @see     java.lang.Object#toString()
 9      */
10     public static String valueOf(Object obj) {
11     return (obj == null) ? "null" : obj.toString();
12     }
复制代码

源码很简单,若是对象为空,就返回字符串的"null"...不为空就调用toString方法。源码

再来讲第二个:string

第二个和第一个的不一样,是java对重载的不一样处理致使的。

基本类型不能接受null入参,因此接受入参的是对象类型,以下两个:

String valueOf(Object obj)

String valueOf(char data[])

这两个都能接受null入参,这种状况下,java的重载会选取其中更精确的一个,所谓精确就是,重载方法A和B,若是方法A的入参是B的入参的子集,则,A比B更精确,重载就会选择A。换成上面这两个就是,char[]入参的比object的更精确,由于object包含char[],因此String.valueOf(null)是用char[]入参这个重载方法。

看看这个方法的实现:

复制代码
 1     /**
 2      * Returns the string representation of the <code>char</code> array
 3      * argument. The contents of the character array are copied; subsequent
 4      * modification of the character array does not affect the newly
 5      * created string.
 6      *
 7      * @param   data   a <code>char</code> array.
 8      * @return  a newly allocated string representing the same sequence of
 9      *          characters contained in the character array argument.
10      */
11     public static String valueOf(char data[]) {
12     return new String(data);
13     }
复制代码

直接new String的,再看new String的实现:

复制代码
 1     /**
 2      * Allocates a new {@code String} so that it represents the sequence of
 3      * characters currently contained in the character array argument. The
 4      * contents of the character array are copied; subsequent modification of
 5      * the character array does not affect the newly created string.
 6      *
 7      * @param  value
 8      *         The initial value of the string
 9      */
10     public String(char value[]) {
11     this.offset = 0;
12     this.count = value.length;
13     this.value = StringValue.from(value);
14     }
复制代码

第12行,入参为null就报NPE了。

JDK中的奇葩实现比较多,你们用的时候养成多看源码实现的好习惯,能够避免踩坑...

若是你们还有见到什么奇葩实现,热烈欢迎留言讨论,哈哈。

相关文章
相关标签/搜索