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

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

说说JDK中的String.valueOf()传null的诡异处理的更多相关文章

  1. Java中String字符串toString()、String.valueOf()、String强转、+ ""的区别

    Object#toString(): Object object = getObject(); System.out.println(object.toString()); 在这种使用方法中,因为ja ...

  2. String.valueOf(null)

    public static String valueOf(Object obj) { return (obj == null) ? "null" : obj.toString(); ...

  3. 关于String.valueOf()和.toString的问题

    以下是String.valueOf()的源代码 public static String valueOf(Object obj) {     return (obj == null) ? " ...

  4. Java中区别.toString() ,(String),valueOf()方法

    在java项目的实际开发和应用中,常常需要用到将对象转为String这一基本功能.本文将对常用的转换方法进行一个总结.常用的方法有Object.toString(),(String)要转换的对象,St ...

  5. java中String.valueOf(obj)、(String)obj与obj.toString()有什么区别

    方法1:采用 Object.toString()方法 在这种使用方法中,因为java.lang.Object类里已有public方法.toString(),所以对任何严格意义上的java对象都可以调用 ...

  6. java 基于JDK中的源码总结下String二

    申明:转载请注明出处,如有商用目的请务必知会本人,感谢. 上一篇文章:http://blog.csdn.net/ts1122/article/details/8738336,介绍了String一些易错 ...

  7. JAVA中Integer.valueOf, parsetInt() String.valueOf的区别和结果

    先来看段代码 public class IntegerDemo { public static void main(String[] args) { String num = null; System ...

  8. 从String.valueOf(null)说起

    同学在群问String.valueOf(null)返回啥,我看了下源码,返回"null"啊,   public static String valueOf(Object obj) ...

  9. Java中String.valueOf、toString、(String)的区别

    原文地址http://blog.csdn.net/yangzhaomuma/article/details/51173138 原文地址https://www.cnblogs.com/xhyouyou/ ...

随机推荐

  1. vue-router(一)

    vue路由再vue开发的项目中可以说是一个必用的组件,而这个部分的水却依旧很深,今天我们深入分析其内部的东西,先看这样一个效果: 大家 可以看到上图中,我们通过两种方式实现了一个vue路由跳转的过度动 ...

  2. vuex(一)mutations

    前言:vuex的使用,想必大家也都知道,类似于状态库的东西,存储某种状态,共互不相干的两个组件之间数据的共享传递等.我会分开给大家讲解vuex的使用,了解并掌握vuex的核心(state,mutati ...

  3. Python timedelta

    datetime.timedelta对象代表两个时间之间的的时间差,两个date或datetime对象相减时可以返回一个timedelta对象.   构造函数: class datetime.time ...

  4. MySQL中的锁理解

    1.目的:解决客户端并发访问的冲突问题 2.锁的分类 1.锁类型 1.读锁(共享锁) 查询(select):加读锁之后,别人不能更改表记录,但是可以进行查询. 2.写锁(互斥锁,排他锁) 更新(upd ...

  5. 启动和连接MySQL服务

    1.服务端启动 1.查看MySQL状态 sudo /etc/init.d/mysql status sudo /etc/init.d/mysql start | stop | restart sudo ...

  6. Django项目部署(阿里云)(2)--扩展

    新博客地址:http://muker.net/django-server-two.html 前面的只是最简单的部署,真实情况总是更复杂一点实际流程大概是这么操作的(我这种菜鸟的想法):本地写代码-&g ...

  7. Appium 定位方法例子(4)

    有朋友留言反应定位不到元素,没错,船长也为这个一直在头疼,我用的App是原生安卓+webService+h5类型的,定位虽然没问题,但是在进行操作的时候各种不通过……真的很头疼啊……我这里说的“操作” ...

  8. LG3690 【模板】Link Cut Tree (动态树)

    题意 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联通的 ...

  9. ecmall 2.3.0 最新补丁20140618

    特别提示:补丁下载地址为:http://download.ecshop.com开头,该地址为ecmall下载站,如果非以http://download.ecshop.com开头,请勿下载,同时请反馈给 ...

  10. phpMyAdmin“缺少 mcrypt 扩展。请检查 PHP 配置。”解决办法

    在ecmall二次开发中因php版本要求低于5.3,而如下更新要求升级PHP,所以以下方式不适合于ecmall商城项目. 解决办法:安装php-mcrypt libmcrypt libmcrypt-d ...