美文网首页技术首页投稿(暂停使用,暂停投稿)程序员
【你可能不知道的java小知识】--String.valueOf

【你可能不知道的java小知识】--String.valueOf

作者: 破东风CAFEBABY | 来源:发表于2016-04-22 18:42 被阅读570次

    今天在排查问题的时候发现String.valueOf 的一个有意思的问题,第一种情况:

    String.valueOf(null);
    

    第一种情况:

    Map<String, Object> map = new HashMap<String, Object>();  
    String a = String.valueOf(map.get("a")); 
    

    乍看上去,肯定会是一样的结果,要么都得到"null"字符串,要么都报错,但是,结果是这样的:第一种情况会报空指针异常,第二种情况不会报异常,只是得到一个null。

    一开始觉得难以置信,无论String.valueOf方法有没有对参数进行判空,都一定是相同的:如果进行了判空,null安全,应该会返回一个null,如果没有,那么都会报错。

    网上查找了一些相关资料,又去看了下String.valueOf的源码,真相终于水落石出:String.valueOf方法有好几个重载方法,但是由于null不可能赋值给基本数据类型,所以只剩下2个备选的方法:String valueOf(char data[]) 和 String valueOf(Object obj)。

    String valueOf(char data[]) 源码

        /**
         * Returns the string representation of the {@code char} array
         * argument. The contents of the character array are copied; subsequent
         * modification of the character array does not affect the returned
         * string.
         *
         * @param   data     the character array.
         * @return  a {@code String} that contains the characters of the
         *          character array.
         */
        public static String valueOf(char data[]) {
            return new String(data);
        }
    

    String valueOf(Object obj) 源码

        /**
         * 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();
        }
    

    查看代码可以看到String valueOf(Object obj)进行了判空,而String valueOf(char data[])没有。所以很明显,第一种情况调用了String valueOf(char data[]),所以是报了空指针异常;而第二种情况下,调用了String valueOf(char data[]),所以没有报。

    String valueOf(Object obj)源码示意图

    null对于String valueOf(char data[]) 和 String valueOf(Object obj)的参数都是使用的,那么java如何选择:首先,对于第二种情况,很容易理解,由于map指定了泛型,所以从这个map取出来的肯定是一个Object 类型的参数,肯定会调用String valueOf(Object obj)方法。对于第一种情况,java会选取精确度最高的一种重载方法。如果对于某个参数,String valueOf(char data[])可以适用的话,String valueOf(Object obj)是肯定可以适用的,所以String valueOf(char data[])的精确度就比String valueOf(Obect obj)的精确度要高,null同时适用于这两个方法,所以java会选取精确度较高的一个来执行。

    相关文章

      网友评论

      • 斯云:嘿,boy,这个问题,我后来又思考了哈,写了一下总结:http://www.jianshu.com/p/47659b59ce17
        有时间帮我看看给有哪里错了。
      • bc94965002f1:查看代码可以看到String valueOf(Object obj)进行了判空,而String valueOf(char data[])没有。所以很明显,第一种情况调用了String valueOf(char data[]),所以是报了空指针异常;而第二种情况下,调用了String valueOf(char data[]),所以没有报。

        首先,对于第二种情况,很容易理解,由于map指定了泛型,所以从这个map取出来的肯定是一个Object 类型的参数,肯定会调用String valueOf(Object obj)方法。

        ??????
      • 斯云:谢谢分享。Java中的null通常用来声明一个空引用,引用时会抛出NullPointerException。单独的null不会被看作是Object对象,除非强制转化为Object(null),它是一个空引用,所以被看作null数组,被函数String valueOf(char data[]) 调用,抛出异常。所以我觉得并非是选择精度的问题,此处并没有这种机制
        斯云:@破东风CAFEBABY 嗯,貌似如此,“写一个接受Object方法传入null参数验证”的情况:可能是被自动转化了成Object对象了。“选择精度控制了调用哪个方法”?有点玄~~
        破东风CAFEBABY:@斯云 看了你的主页,还会写小说, :+1:
        破东风CAFEBABY:@斯云 谢谢你的回复。不太同意你的观点,null不是Object对象,但是对于Object参数是适用的,可以写一个接受Object方法传入null参数验证。此时null对于这2个重载的方法都适用,选择精度控制了调用哪个方法。

      本文标题:【你可能不知道的java小知识】--String.valueOf

      本文链接:https://www.haomeiwen.com/subject/wsqtrttx.html