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

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

 public class TestString {

     public static void main(String[] args){

         Object obj = null;
System.out.println(String.valueOf(obj));
System.out.println(String.valueOf(null));
}
}

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

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

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

下面来分析分析原因。

先说第一个:

看第一个的源码实现:

     /**
* Returns the string representation of the <code>Object</code> argument.
*
* @param obj an <code>Object</code>.
* @return if the argument is <code>null</code>, then a string equal to
* <code>"null"</code>; otherwise, the value of
* <code>obj.toString()</code> is returned.
* @see java.lang.Object#toString()
*/
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}

源码很简单,如果对象为空,就返回字符串的"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[]入参这个重载方法。

看看这个方法的实现:

     /**
* Returns the string representation of the <code>char</code> array
* argument. The contents of the character array are copied; subsequent
* modification of the character array does not affect the newly
* created string.
*
* @param data a <code>char</code> array.
* @return a newly allocated string representing the same sequence of
* characters contained in the character array argument.
*/
public static String valueOf(char data[]) {
return new String(data);
}

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

     /**
* Allocates a new {@code String} so that it represents the sequence of
* characters currently contained in the character array argument. The
* contents of the character array are copied; subsequent modification of
* the character array does not affect the newly created string.
*
* @param value
* The initial value of the string
*/
public String(char value[]) {
this.offset = 0;
this.count = value.length;
this.value = StringValue.from(value);
}

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

JDK中的奇葩实现比较多,大家用的时候养成多看源码实现的好习惯,可以避免踩坑...

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

最新文章

  1. 问题解决——MFC Ribbon 响应函数 错乱 执行其他函数
  2. myBatis,Spring,SpringMVC三大框架ssm整合模板
  3. Linux新建用户无法使用tab补全的修改办法
  4. 对于JAVA课程的期望
  5. 【linux】/dev/null与/dev/zero详解【转】
  6. urlrewrite 地址重写
  7. 第一部分实现功能:使用一个TabControl和一个Memo和TDictionary类实现文本临时存储
  8. Linux前传——今天的学习
  9. j2ee爬坑行之一:web容器
  10. C语言-运算符与表达式
  11. [转]如何从MySQL官方Yum仓库安装MySQL5.6
  12. (转)Python爬虫利器一之Requests库的用法
  13. AspnetCore 缓存篇
  14. soul
  15. DDD领域模型实现依赖注入(六)
  16. vue 笔记二
  17. CentOS7 使用tab建补全命令
  18. WordPress翻译更新失败解决方法
  19. NTP原理初步与配置
  20. object类型对象 ref参数如何理解?

热门文章

  1. js之简易计算器
  2. MySQL 实用技巧
  3. Windows中cmd操作mysql
  4. Buy Tickets(线段树单点更新,逆向思维)
  5. css 2D动画
  6. gradle 项目构建以及发布maven 私服&amp;&amp; docker 私服构建发布
  7. maven-assembly-plugin 打包简单案例
  8. 1G1核1M选择 Centos 32位 还是 Centos 64位?
  9. [LeetCode系列]翻转链表问题II
  10. Arrays--codility