zoukankan      html  css  js  c++  java
  • 说说JDK中的String.valueOf()传null的诡异处理

    都说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.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中的奇葩实现比较多,大家用的时候养成多看源码实现的好习惯,可以避免踩坑...

    如果大家还有见到什么奇葩实现,热烈欢迎留言讨论,哈哈。

  • 相关阅读:
    微信支付:redirect-uri参数错误 的解决办法
    PHP计划任务之关闭浏览器后仍然继续执行的函数
    windows7安装phpnow Apache非管理员权限不能操作Windows NT服务的解决方法
    php 本周开始时间和结束时间;本月开始时间结束时间;上月开始时间结束时间
    图片预览
    生成随机验证码(记得下载字体文件啊)
    git ,github实际操作指南
    git,github初识命令
    博客园项目(BBS)
    django之分页器
  • 原文地址:https://www.cnblogs.com/lingiu/p/3224431.html
Copyright © 2011-2022 走看看