说说JDK中的String.valueOf()传null的诡异处理惩罚

    添加时间:2013-7-30 点击量:

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


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



     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的字符串...


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


    第二个输出,咋一看没差别,然则,第二个输出,抛空指针异常了。


    下面来解析解析原因。


    先说第一个:


    看第一个的源码实现:



     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办法。


    再来说第二个:


    第二个和第一个的不合,是java对重载的不合处理惩罚导致的。


    根蒂根基类型不克不及接管null入参,所以接管入参的是对象类型,如下两个:


    String valueOf(Object obj)


    String valueOf(char data[])


    这两个都能接管null入参,这种景象下,java的重载会拔取此中更正确的一个,所谓正确就是,重载办法A和B,若是办法A的入参是B的入参的子集,则,A比B更正确,重载就会选择A。换成上方这两个就是,char[]入参的比object的更正确,因为object包含char[],所以String.valueOfnull)是用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.(value);
    14 }


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


    JDK中的奇葩实现斗劲多,大师用的时辰养成多看源码实现的好习惯,可以避免踩坑...


    若是大师还有见到什么奇葩实现,热烈迎接留言评论辩论,哈哈。

    原来,再大的房子,再大的床,没有相爱的人陪伴,都只是冰冷的物质。而如果身边有爱人陪伴,即使房子小,床小,也觉得无关紧要,因为这些物质上面有了爱的温度,成了家的元素。—— 何珞《婚房》#书摘#
    分享到: