说说JDK中的String.valueOf()传null的诡异处理
都说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中的奇葩实现比较多,大家用的时候养成多看源码实现的好习惯,可以避免踩坑...
如果大家还有见到什么奇葩实现,热烈欢迎留言讨论,哈哈。
说说JDK中的String.valueOf()传null的诡异处理的更多相关文章
- Java中String字符串toString()、String.valueOf()、String强转、+ ""的区别
Object#toString(): Object object = getObject(); System.out.println(object.toString()); 在这种使用方法中,因为ja ...
- String.valueOf(null)
public static String valueOf(Object obj) { return (obj == null) ? "null" : obj.toString(); ...
- 关于String.valueOf()和.toString的问题
以下是String.valueOf()的源代码 public static String valueOf(Object obj) { return (obj == null) ? " ...
- Java中区别.toString() ,(String),valueOf()方法
在java项目的实际开发和应用中,常常需要用到将对象转为String这一基本功能.本文将对常用的转换方法进行一个总结.常用的方法有Object.toString(),(String)要转换的对象,St ...
- java中String.valueOf(obj)、(String)obj与obj.toString()有什么区别
方法1:采用 Object.toString()方法 在这种使用方法中,因为java.lang.Object类里已有public方法.toString(),所以对任何严格意义上的java对象都可以调用 ...
- java 基于JDK中的源码总结下String二
申明:转载请注明出处,如有商用目的请务必知会本人,感谢. 上一篇文章:http://blog.csdn.net/ts1122/article/details/8738336,介绍了String一些易错 ...
- JAVA中Integer.valueOf, parsetInt() String.valueOf的区别和结果
先来看段代码 public class IntegerDemo { public static void main(String[] args) { String num = null; System ...
- 从String.valueOf(null)说起
同学在群问String.valueOf(null)返回啥,我看了下源码,返回"null"啊, public static String valueOf(Object obj) ...
- Java中String.valueOf、toString、(String)的区别
原文地址http://blog.csdn.net/yangzhaomuma/article/details/51173138 原文地址https://www.cnblogs.com/xhyouyou/ ...
随机推荐
- vue-router(一)
vue路由再vue开发的项目中可以说是一个必用的组件,而这个部分的水却依旧很深,今天我们深入分析其内部的东西,先看这样一个效果: 大家 可以看到上图中,我们通过两种方式实现了一个vue路由跳转的过度动 ...
- vuex(一)mutations
前言:vuex的使用,想必大家也都知道,类似于状态库的东西,存储某种状态,共互不相干的两个组件之间数据的共享传递等.我会分开给大家讲解vuex的使用,了解并掌握vuex的核心(state,mutati ...
- Python timedelta
datetime.timedelta对象代表两个时间之间的的时间差,两个date或datetime对象相减时可以返回一个timedelta对象. 构造函数: class datetime.time ...
- MySQL中的锁理解
1.目的:解决客户端并发访问的冲突问题 2.锁的分类 1.锁类型 1.读锁(共享锁) 查询(select):加读锁之后,别人不能更改表记录,但是可以进行查询. 2.写锁(互斥锁,排他锁) 更新(upd ...
- 启动和连接MySQL服务
1.服务端启动 1.查看MySQL状态 sudo /etc/init.d/mysql status sudo /etc/init.d/mysql start | stop | restart sudo ...
- Django项目部署(阿里云)(2)--扩展
新博客地址:http://muker.net/django-server-two.html 前面的只是最简单的部署,真实情况总是更复杂一点实际流程大概是这么操作的(我这种菜鸟的想法):本地写代码-&g ...
- Appium 定位方法例子(4)
有朋友留言反应定位不到元素,没错,船长也为这个一直在头疼,我用的App是原生安卓+webService+h5类型的,定位虽然没问题,但是在进行操作的时候各种不通过……真的很头疼啊……我这里说的“操作” ...
- LG3690 【模板】Link Cut Tree (动态树)
题意 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联通的 ...
- ecmall 2.3.0 最新补丁20140618
特别提示:补丁下载地址为:http://download.ecshop.com开头,该地址为ecmall下载站,如果非以http://download.ecshop.com开头,请勿下载,同时请反馈给 ...
- phpMyAdmin“缺少 mcrypt 扩展。请检查 PHP 配置。”解决办法
在ecmall二次开发中因php版本要求低于5.3,而如下更新要求升级PHP,所以以下方式不适合于ecmall商城项目. 解决办法:安装php-mcrypt libmcrypt libmcrypt-d ...