听说,你也一直钟爱着equals。。。
脑补一下final
final 用于声明变量/参数/属性、方法和类。
- 修饰变量:如果变量是基本类型,其值不变;如果是对象,则引用不可再变(内容可变)。
- 修饰方法:方法不可重写(是否可继承取决于方法的访问修饰符)
- 修饰类:类不可被继承。

==与equals的区别
我想,大家常规的解释是:==是操作符,比较基本类型,则为其值;比较引用类型,则用以比较两个对象在内存中的哈希地址。 equals是方法,比较的是变量的内容。
---------------
equals是超类Object的方法。参数是一个object对象。本文我将重点借助JAVADOC和源码来阐释。
java.lang.Object里对equals方法的说明:
/** Indicates whether some other object is "equal to" this one.
The equals method implements an equivalence relation on non-null object references:
- It is reflexive: for any non-null reference value x, x.equals(x) should return true.
- It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
- It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
- It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
- For any non-null reference value x, x.equals(null) should return false.
The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).
Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.
Parameters:
obj - the reference object with which to compare.
Returns:
true if this object is the same as the obj argument; false otherwise.
See Also:
hashCode(), java.util.HashMap
*/
public boolean equals(Object obj) {
return (this == obj);
}
可见equals默认是比较对象的哈希值。
String、Integer这些包装类重写了equals方法。重写的逻辑都是先判断类型是否匹配,然后String是看字符串里每个char字符是否都相同,Integer是两个Integer实例的intValue。
//java.lang.String /**
* Compares this string to the specified object. The result is {@code
* true} if and only if the argument is not {@code null} and is a {@code
* String} object that represents the same sequence of characters as this
* object.
*/
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
} //java.lang.Integer /**
* Compares this object to the specified object. The result is
* {@code true} if and only if the argument is not
* {@code null} and is an {@code Integer} object that
* contains the same {@code int} value as this object.
*/
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
java.lang.String和java.lang.Integer对equals(Object)方法的定义
BTW,心细的同学可以注意一下java.lang.String中另一个方法equalsIgnoreCase(String anotherString),参数类型不是Object而是String。这一点足见java之美。
在做诸如String、Integer包装类型比较时,有的人一律用equals,这样会规避用==带来的比较错误的问题。这没错!不过使用equals也会带来一些隐性的bug,罪魁祸首就是它的参数类型是Object,当equals的两个对象类型不匹配时,编译器是识别不出来的。尤其当我们重构代码时,举个栗子,看下面的语句,如果我将bean的platformCode属性的类型由String改为int,而稍有不慎忘记改这条语句的话,那就出bug了。
if("6".equals(bean.getPlatformCode())
因此,个人认为。。。(此处见解见文末)

比较枚举类型能用==吗?
今天有同学在review代码时,发现如下用==来比较枚举,马上反问这么写没有bug么?是否测试过了?
if (ThirdPayPlatformEnums.TFB == _requestDTO.getThird_pay_platform()) {
_requestDTO.setOrder_no(_requestDTO.getOrder_no().replaceAll("[a-zA-Z]", ""));
}
他让改用equals。
于是,大家都开始思考枚举是不是基本类型,并了解枚举是否可以用==来比较。
经查,答案是肯定的。
java.lang.Enum类对equals的定义是这样的:
public final boolean equals(Object other) {
return this==other;
}
单看这个方法实现,可能认为比较的是哈希地址。
让我们来看看这个equals方法的注解,关注一些关键词:
/**
* Returns true if the specified object is equal to this
* enum constant.
*
* @param other the object to be compared for equality with this object.
* @return true if the specified object is equal to this
* enum constant.
*/
注意到了吧,它将枚举项称为枚举常量。
进一步了解到:在官方文档中也有明确的说明
JLS 8.9 Enums 一个枚举类型除了定义的那些枚举常量外没有其他实例了。 试图明确地说明一种枚举类型是会导致编译期异常。在枚举中final clone方法确保枚举常量从不会被克隆,而且序列化机制会确保从不会因为反序列化而创造复制的实例。枚举类型的反射实例化也是被禁止的。总之,以上内容确保了除了定义的枚举常量之外,没有枚举类型实例。
因为每个枚举常量只有一个实例,所以如果在比较两个参考值,至少有一个涉及到枚举常量时,允许使用“==”代替equals()。
顺便贴出来java.lang.Enum里的clone方法,它保证了枚举的“单例”状态:
/**
* Throws CloneNotSupportedException. This guarantees that enums are never cloned, which is necessary to preserve their "singleton" status.
*
* @return (never returns)
*/
protected final Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
csdn《 比较java枚举成员使用equal还是==》文中分析了分别用==和equals来比较枚举的场景。最终建议是最好用==,也是考虑到了上文中提到的equals的弊端。 同样,如果是数值比较,也最好用基本类型,因为用==来比较数值无争议。

听说,你也一直钟爱着equals。。。的更多相关文章
- C# 中的 == 和 equals()有什么区别?
如以下代码: 1 2 3 4 5 6 7 8 9 int age = 25; short newAge = 25; Console.WriteLine(age == newAge); //t ...
- 我的Android进阶之旅------>Android自定义View来实现解析lrc歌词并同步滚动、上下拖动、缩放歌词的功能
前言 一LRC歌词文件简介 1什么是LRC歌词文件 2LRC歌词文件的格式 LRC歌词文件的标签类型 1标识标签 2时间标签 二解析LRC歌词 1读取出歌词文件 2解析得到的歌词内容 1表示每行歌词内 ...
- 别了 oi——一篇高三狗的滚粗遗言
/* 开始于2015年12月 结束于2016年11月 一年的oi生涯有很多值得怀念的事 还记得去年旺哥找我学oi 当时是一脸的蒙逼 要知道 高二才开始搞是很晚了 然而 也就是那一晚之后 许多事情都变了 ...
- js带缩略图的图片切换效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 南邮ctf-web的writeup
WEB 签到题 nctf{flag_admiaanaaaaaaaaaaa} ctrl+u或右键查看源代码即可.在CTF比赛中,代码注释.页面隐藏元素.超链接指向的其他页面.HTTP响应头部都可能隐藏f ...
- JarvisOJ Basic 爱吃培根的出题人
听说你也喜欢吃培根?那我们一起来欣赏一段培根的介绍吧: bacoN is one of aMerICa'S sWEethEartS. it's A dARlinG, SuCCulEnt fOoD tH ...
- Jarvis OJ平台basic部分wirteup
Base64? 题目描述: GUYDIMZVGQ2DMN3CGRQTONJXGM3TINLGG42DGMZXGM3TINLGGY4DGNBXGYZTGNLGGY3DGNBWMU3WI=== Base3 ...
- 爬虫实战(二) 用Python爬取网易云歌单
最近,博主喜欢上了听歌,但是又苦于找不到好音乐,于是就打算到网易云的歌单中逛逛 本着 "用技术改变生活" 的想法,于是便想着写一个爬虫爬取网易云的歌单,并按播放量自动进行排序 这篇 ...
- Hexo的详细搭建过程——小白的血泪经历QAQ
Hexo的详细搭建过程 环境要求: node.js git 这里提供Centos8.2下的安装过程: dnf module list nodejs dnf module install nodejs: ...
随机推荐
- AutoFac Ioc依赖注入容器
本文原著:牛毅 原文路径 http://niuyi.github.io/blog/2012/04/06/autofac-by-unit-test/ 理解IOC容器请看下图: 没有使用IOC容器的情况 ...
- EM学习-思想和代码
EM算法的简明实现 当然是教学用的简明实现了,这份实现是针对双硬币模型的. 双硬币模型 假设有两枚硬币A.B,以相同的概率随机选择一个硬币,进行如下的抛硬币实验:共做5次实验,每次实验独立的抛十次,结 ...
- 多线程 ForkJoinPool
阅读目录 使用 背景:ForkJoinPool的优势在于,可以充分利用多cpu,多核cpu的优势,把一个任务拆分成多个“小任务”,把多个“小任务”放到多个处理器核心上并行执行:当多个“小任务”执行完成 ...
- HTTP协议之Transfer-Encoding
HTTP协议中的Transfer-Encoding 浏览器和服务器端支持持久连接 持久连接(Persist Connection) HTTP1.0默认不是持久连接的 HTTP1.1默认是持久连接的 在 ...
- 课程信息管理系统(javabean + Servlet + jsp)
此项目做的事一个课程管理系统,需要通过web做一个可以实现课程的增删改查的功能. 需要用到数据库,Servlet和jsp等(第一次使用Servlet和数据库连接,所以代码都比较低级,页面也比较粗糙,还 ...
- [DPDK] 转发 DPDK分析
前半部分,对于背景和需求的分析,写的相当好啊! 原文地址:https://www.jianshu.com/p/0ff8cb4deaef 背景分析 前10年中,网络程序性能优化的目标主要是为了解决C10 ...
- 搭建Kubernetes服务集群遇到的问题
kube-proxy问题: Apr 12 09:42:49 compute1 kube-proxy[12965]: E0412 09:42:49.602342 12965 reflector.go:2 ...
- openssl编译参数选项
执行Configure是常见参数选项如下: 安装参数: --openssldir=OPENSSLDIR 安装目录,默认是 /usr/local/ssl . --prefix=PREFIX 设置 lib ...
- install python in wine
wget http://www.kegel.com/wine/winetricks chmod +x winetricks ./winetricks 钩选msxml3就可以了. ___________ ...
- 转: js实现全角半角检测的方法
//全角半角校验 function issbccase(strTmp) { for (var i=0; i<strTmp.length; i++) { if (strTmp.charCodeAt ...