getClass()和instanceof以及类的equals方法
在比较两个类时,常见有两种做法,一种是x.getClass() == y; 一种是x instanceof y,下面我们来比较这两种做法的区别。
getClass()返回一个对象所属的类
public static void main(String[] args) {
Hero h1 = new Hero(null,10,2);
Hero h2 = new Hero("zhang",10,2);
Superman s1 = new Superman("zhang");
System.out.println(h1.getClass());
System.out.println(h1.getClass() == h2.getClass());
System.out.println(h1.getClass() == s1.getClass());
System.out.println(s1.getClass() == h1.getClass());
}
返回:
class source.Hero
true
false
false
可以看到,getClass返回的是一个类名,也就是说只会在类名相同时返回true,不会判断子类与父类的继承关系。
instanceof比较一个对象是否是该类的实例
public static void main(String[] args) {
Hero h1 = new Hero(null,10,2);
Hero h2 = new Hero("zhang",10,2);
Superman s1 = new Superman("zhang");
System.out.println((h1 instanceof Hero));
System.out.println(h2 instanceof Superman);
System.out.println(s1 instanceof Hero);
System.out.println(h1 instanceof Superman);
}
返回:
true
false
true
false
可以看到,instanceof会判断继承关系,子对象 instanceof 父类 会返回true,父对象 instanceof 子类会返回 false。 可以理解为判断两个问题:你是这个类吗? 你是这个类的派生类吗?
equals方法:
public boolean equals(Object otherObject) {
if(this == otherObject) return true;
if(otherObject == null) return false;
if(getClass() != otherObject.getClass()) return false;
Hero other = (Hero)otherObject;
return name.equals(other.name)
&& hp == other.hp
&&damage == other.damage;
}
equals方法具有下面特性:
1,自反性
2,对称性
3,传递性
4,一致性
5,对于任意非空引用x,x.equals(null)应该返回false。
下面我们首先结合上面的内容讨论对称性。
father.equals(child)
这里的father与child具有相同的姓氏,血型,家族。如果在Father.equals中用instanceof检测,会得到true。这意味着如果反过来调用:
child.equals(father)
也需要返回true。
应该这样说:
1,如果子类拥有自己的相等概念,则对称性需求将强制采用getClass进行检测。 例如雇员和经理,对应的域相等就认为两个对象相等;如果两个经历对应的名字薪水雇佣日期都相等,而奖金不相等,就认为他们不相同。
2,如果由超类决定相等的概念,那么可以用instanceof进行检测,就可以在不同的子类对象之间进行相等的比较。例如经理是雇员的儿子类,假设使用雇员的ID作为相等的检测条件,那么这个相等概念也适用于经理,此时可以用instanceof进行检测,并且应该将Employee.equals方法声明为final。
编写完美equals方法的建议(来自CoreJava):
1,显式参数命名为otherObject,稍后需要将它转换成另一个叫做other的变量 这里参数一定是Object类型 否则不会产生Override
2,检测this和otherObject是否引用同一个对象
if(this == otherObject) return true;
3,检测otherObject是否为null。如果是null,则返回false
4,比较this和otherObject是否属于同一个类。按照上面红字的总结:如果equals的语义在每个子类中有所改变,就用getClass检测:
if (getClass() != otherObject.getClass()) return false;
如果所有的子类都拥有统一的语义,就是用instanceof检测
if (!(otherObject instanceof ClassName)) return false;
5,将otherObject转换为相应的类类型变量:
ClassName other = (ClassName) otherObject;
6,现在开始对所有需要比较的域进行比较。使用 == 比较基本类型域, 使用equals比较对象域。
return field 1 == field2
&& Objects.equals(field2,other.field2)
&&....... ;
这里需要注意: 如果在两个参数都为null时需要返回true,那么应该使用Objects.equals(1,2)
如果不能接受有参数为null,或者两个参数不会为null,则使用a.equals(b) (当有一个参数为null时,a.equals(b)将会抛出NullPointerException)
如果在子类中重新定义equals,就要在其中包含调用super.equals(other)
getClass()和instanceof以及类的equals方法的更多相关文章
- Object类的toString和Equals方法,以及Objects类的Equals方法
Object类 toString()方法 public class Person { private String name; private int age; public Person() { } ...
- object类的equals方法简介 & String类重写equals方法
object类中equals方法源码如下所示 public boolean equals(Object obj) { return this == obj; } Object中的equals方法是直接 ...
- Java Object类及其equals方法
基本概念: Object类位于java.lang包中,java.lang包包含着Java最基础和核心的类,在编译时会自动导入: Object类是所有Java类的祖先.每个类都使用 Object 作为超 ...
- Object类及其equals()方法
== : 1.基本数据类型:根据基本数据类型的值判断是否相等,相等返回true,反之返回false 注意:两端数据类型可以不同, 在不同的情况下,也可以返回true 2.引用数据类型:Object ...
- Object 类的equals方法
Object 类中定义有: public boolean equals (Object obj)方法 提供对象是否“相等”的逻辑 Object 的equals方法定义为:x.equals(y)当x和y ...
- Java Object类的equals()方法
所有类都从Object类中继承了equals方法,Object类中equals方法源代码如下: public boolean equals(Object obj) { retu ...
- Java:Object类的equals()方法 如何编写一个完美的equals()方法
一 代码实例: package freewill.objectequals; /** * @author freewill * @see Core Java page161 * @desc get ...
- Object类—复写equals方法,hashCode方法,toString方法
Object:所有类的根类. Object是不断抽取而来,具备着所有对象都具备的共性内容. class Person extends Object { private int age; Person( ...
- 注意重写类的equals()方法
注意在java中在比较引用类型时==和原生的equals()方法比较的都是看它们否是同一个对象(说的更直白一点就是他们在内存的位置是否是一样的),但我们在真实世界中关注的往往只是其中的某个属性是否相等 ...
随机推荐
- 本人亲测-SSM环境搭建(使用eclipse作为示例,过程挺全的,可作为参考)
本人亲测-SSM环境搭建(使用eclipse作为示例,过程挺全的,可作为参考) 本人亲测-SSM环境搭建(使用eclipse作为示例,过程挺全的,可作为参考) 本人亲测-SSM环境搭建(使用eclip ...
- Flask的路由解读以及其配置
from flask import Flask app =Flask(__name__) 一.配置 配置一共有四中方式 方法一: 只能设置以下两种属性 app.debug=True app.secre ...
- phpstorm 新加入项目的文件--全局搜索不到 ctrl + shift + R
通过文件名查找文件 ,能搜到其他的现有文件,只是新加入的文件,无法出现在搜索到的结果中 . 总不可能在搜索的关键词一直拼写错误吧 , 那能想到的只有缓存出问题了. 新加入的文件,新加入的文件.... ...
- 【Java必修课】ArrayList与HashSet的contains方法性能比较(JMH性能测试)
1 简介 在日常开发中,ArrayList和HashSet都是Java中很常用的集合类. ArrayList是List接口最常用的实现类: HashSet则是保存唯一元素Set的实现. 本文主要对两者 ...
- Linux必备工具与软件包
yum -y update(所有都升级和改变) 升级所有包,系统版本和内核,改变软件设置和系统设置 ----------------------------------------------- yu ...
- Kafka权威指南阅读笔记(第八章)
跨集群数据镜像 使用场景: 区域集群和中心集群 这种场景下,每个区域的应用程序只访问相应的区域内的集群.而有些情况下,需要将各个集群的信息汇总到中心集群,就可以用中心集群分析业务数据了. 冗余 一个K ...
- Redis(四)Jedis客户端
一.客户端通信协议 二.Java客户端Jedis 1.获取Jedis Jedis属于Java的第三方开发包,在Java中获取第三方开发包通常有两种方式: 直接下载目标版本的Jedis-${versio ...
- day3,用户交互,input的应用
1.与用户交互 输入:input() python2.x版本 input后面家的东西要声明输入的类型 >>> input(">>:") ...
- 蓝桥杯基础练习 Huffuman树
基础练习 Huffuman树 问题描述 Huffman树在编码中有着广泛的应用.在这里,我们只关心Huffman树的构造过程. 给出一列数{pi}={p0, p1, -, pn-1},用这列数构造Hu ...
- leetcode算法小题(2)
题目描述: 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. package Simple;import java.util.Scanner;public class Prac ...