问题背景

我的天,最近做 Code Review 看到一个同事的骚操作,他写了一个工具类,大概是这样的:

public static boolean isNull(Object object){
return null == object || object.equals(null);
}

判断空,一般不是 null == object 就够了,object.equals(null) 是什么骚操作?

写程序这么多年,第一次看这样的写法,当时我就提出质疑了,同事拍着胸脯和我说,有个银行的请求参数必须得这么写,不然就验证不了。

我当时还在想,这是 JDK 出的什么新类型么,觉得还是不科学,考虑去跟下同事写的代码,然后用他所说的情况我亲自去验证一下。

看了下,这是个老业务系统,同事用了 json-lib 这个包,历史的江湖确实有这个包的存在,栈长之前也用过,不过后来这玩意就没怎么用了,现在都是 GsonJackson 的天下了。

如下面 json-lib 例子所示:

public static void main(String[] args) {
String jsonString = "{\"name\": \"hi\",\"sex\": \"boy\", \"age\": null}"; JSONObject jsonObject = net.sf.json.JSONObject.fromObject(jsonString);
Object age = jsonObject.get("age"); // 输出:null
System.out.println("age: " + age); // 输出:false
System.out.println("age == null: " + (age == null)); // 输出:true
System.out.println("age.equals(null): " + (age.equals(null)));
}

我天!大家看到结果了吧,问题确实也如同事所说,一定要用 object.equals(null) 写法才行,不相信结果的大家也可以亲自验证一下。

纳了闷了,这样写,我传一个 null 值过去不是报空指针了么?这样写肯定有问题,继续深挖!

问题分析

fromObject 方法加载 JSON 串开始源码深入分析,找到了这个神奇解析 null 值的源码:

原来,JSON 串中的 null 值被解析成了它内部的 JSONNull 对象,然后再看下这个 JSONNull 的 equals 方法源码:

public boolean equals(Object object) {
return object == null ||
object == this ||
object == instance ||
object instanceof JSONObject &&
((JSONObject)object).isNullObject() ||
"null".equals(object);
}

问题就出在他所用的 JSON 工具类了!!!

equals 方法被重写了……终于揭开了 object.equals(null) 的神秘面纱……

再来看下是否有新的更新包:

最新的版本停留在 2010 年 12 月,已经是被淘汰的东西了。

另外,json-lib 在 JDK 1.7+ 有性能影响。

推荐阅读:请不要在 JDK 7+ 中使用这个 JSON 包了

解决方案

方法1:

换掉 object.equals(null),用 JSONNull 的实例去判断:

public static boolean isNull(Object object){
return null == object || JSONNull.getInstance().equals(object);
}

方法2:

换掉 json-lib 库,用主流的 GsonJackson

具体看下这篇:Java常用的几个Json库,性能强势对比,另外 FastJson 也不建议用了,漏洞比较多。

这个由于是老系统,太多业务使用了这个库,换掉的开发、测试成本和风险比较大,暂时考虑先用方案1先解决这个问题。

关注Java技术栈微信公众号,栈长将继续分享好玩的 Java 技术,公众号第一时间推送,在公众号后台回复:Java,可以获取历史 Java 教程,都是干货。

推荐去我的博客阅读更多:

1.Java JVM、集合、多线程、新特性系列教程

2.Spring MVC、Spring Boot、Spring Cloud 系列教程

3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程

4.Java、后端、架构、阿里巴巴等大厂最新面试题

觉得不错,别忘了点赞+转发哦!

我天!xx.equals(null) 是什么骚操作??的更多相关文章

  1. xxx==null和xxx.equals(null)的区别

    如果xxx不是null的话,xxx==null将返回false,如果xxx是null的话,xxx将返回ture 而对xxx.equals(null)而言,他将永远返回false,因为如果xxx不是nu ...

  2. Redis 数据结构之字符串的那些骚操作

    Redis 字符串底层用的是 sds 结构,该结构同 c 语言的字符串相比,其优点是可以节省内存分配的次数,还可以... 这样写是不是读起来很无聊?这些都是别人咀嚼过后,经过一轮两轮三轮的再次咀嚼,吐 ...

  3. Guava中这些Map的骚操作,让我的代码量减少了50%

    原创:微信公众号 码农参上,欢迎分享,转载请保留出处. Guava是google公司开发的一款Java类库扩展工具包,内含了丰富的API,涵盖了集合.缓存.并发.I/O等多个方面.使用这些API一方面 ...

  4. 闪电侠 Netty 小册里的骚操作

    前言 即使这是一本小册,但基于"不提笔不读书"的理念,仍然有必要总结一下.此小册对于那些"硬杠 Netty 源码 却不曾在千万级生产环境上使用实操"的用户非常有 ...

  5. Equal Sums (map的基本应用) 多学骚操作

    C. Equal Sums time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  6. 关于MySQL的一些骚操作——提升正确性,抠点性能

    概要 回顾以前写的项目,发现在规范的时候,还是可以做点骚操作的. 假使以后还有新的项目用到了MySQL,那么肯定是要实践一番的. 为了准备,创建测试数据表(建表语句中默认使用utf8mb4以及utf8 ...

  7. 聊聊redis实际运用及骚操作

    前言 聊起 redis 咱们大部分后端猿应该都不陌生,或多或少都用过.甚至大部分前端猿都知道. 数据结构: string. hash. list. set (无序集合). setsorted(有序集合 ...

  8. C#中的9个“黑魔法”与“骚操作”

    C#中的9个"黑魔法"与"骚操作" 我们知道C#是非常先进的语言,因为是它很有远见的"语法糖".这些"语法糖"有时过于好 ...

  9. [C#.NET 拾遗补漏]05:操作符的几个骚操作

    阅读本文大概需要 1.5 分钟. 大家好,这是极客精神[C#.NET 拾遗补漏]专辑的第 5 篇文章,今天要讲的内容是操作符. 操作符的英文是 Operator,在数值计算中习惯性的被叫作运算符,所以 ...

随机推荐

  1. TestNG测试用例重跑详解及实践优化

    测试用例运行稳定性是自动化质量的一个重要指标,在运行中需要尽可能的剔除非bug造成的测试用例执行失败,对于失败用例进行重跑是常用策略之一.一种重跑策略是所有用例运行结束后对失败用例重跑,另一种重跑策略 ...

  2. Android 开发技术周报 Issue#278

    新闻 Pixel 4a渲染图曝光:或能成新款iPhone SE有力竞争者 Google Play商店为预注册的游戏和应用提供自动安装功能 Android最强单摄Pixel 4a样张曝光:1200万像素 ...

  3. HashMap 底层探索

    其实HashMap就是一个Node数组,只是这个数组很奇怪它的每一个Node节点都有自己的下一个Node;这个是hashMap的Node的源码: static class Node<K,V> ...

  4. 第3章:关系数据库标准语言 SQL

    目录 第3章:关系数据库标准语言 SQL 3.1.SQL概述 3.1.1.历史 3.3.2.SQL语言的功能 3.3.3.SQL的特点 3.3.4.基本概念 3.2.学生-课程数据库 3.3.数据定义 ...

  5. CC2530入门

    一.简介 单片机(MCU)就是一个将微型计算机系统制作到里面的集成电路芯片. 微控制器的基本结构:内核+外设.内核通过寄存器控制外设:外设通过中断系统通知内核:内核与外设之间通过总线传输数据.地址及控 ...

  6. java读源码 之 list源码分析(LinkedList)

    文章目录 LinkedList: 继承关系分析: 字段分析: 构造函数分析: 方法分析: LinkedList: 继承关系分析: public class LinkedList<E> ex ...

  7. 记录一下关于在工具类中更新UI使用RunOnUiThread犯的极其愚蠢的错误

    由于Android中不能在子线程中更新ui,所以平时在子线程中需要更新ui时可以使用Android提供的RunOnUiThread接口,但是最近在写联网工具类的时候,有时候会出现联网异常,这个时候为了 ...

  8. 第十章:Python高级编程-多线程、多进程和线程池编程

    第十章:Python高级编程-多线程.多进程和线程池编程 Python3高级核心技术97讲 笔记 目录 第十章:Python高级编程-多线程.多进程和线程池编程 10.1 Python中的GIL 10 ...

  9. Java UDP小结

    UDP: * 发送端                                                                                           ...

  10. Mysql 常用函数(7)- length 函数

    Mysql常用函数的汇总,可看下面系列文章 https://www.cnblogs.com/poloyy/category/1765164.html length 的作用 返回字符串的字节长度 注意: ...