在比较两个类时,常见有两种做法,一种是x.getClass() == y; 一种是x instanceof y,下面我们来比较这两种做法的区别。

getClass()返回一个对象所属的类

  1. public static void main(String[] args) {
  2. Hero h1 = new Hero(null,10,2);
  3. Hero h2 = new Hero("zhang",10,2);
         Superman s1 = new Superman("zhang");
  4. 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());

  1. }
    返回:
      class source.Hero

  true
  false
  false

  1.  

可以看到,getClass返回的是一个类名,也就是说只会在类名相同时返回true,不会判断子类与父类的继承关系。

instanceof比较一个对象是否是该类的实例

  1. public static void main(String[] args) {
  2. Hero h1 = new Hero(null,10,2);
  3. Hero h2 = new Hero("zhang",10,2);
  4. Superman s1 = new Superman("zhang");
  5.  
  6. System.out.println((h1 instanceof Hero));
  7. System.out.println(h2 instanceof Superman);
  8. System.out.println(s1 instanceof Hero);
  9. System.out.println(h1 instanceof Superman);
  10. }
    返回:

  true
  false
  true
  false

可以看到,instanceof会判断继承关系,子对象 instanceof 父类 会返回true,父对象 instanceof 子类会返回 false。 可以理解为判断两个问题:你是这个类吗? 你是这个类的派生类吗?

equals方法:

  1. public boolean equals(Object otherObject) {
  2. if(this == otherObject) return true;
  3.  
  4. if(otherObject == null) return false;
  5.  
  6. if(getClass() != otherObject.getClass()) return false;
  7.  
  8. Hero other = (Hero)otherObject;
  9.  
  10. return name.equals(other.name)
  11. && hp == other.hp
  12. &&damage == other.damage;
  13. }

equals方法具有下面特性:

1,自反性

2,对称性

3,传递性

4,一致性

5,对于任意非空引用x,x.equals(null)应该返回false。

下面我们首先结合上面的内容讨论对称性

  1. father.equals(child)

这里的father与child具有相同的姓氏,血型,家族。如果在Father.equals中用instanceof检测,会得到true。这意味着如果反过来调用:

  1. child.equals(father)

也需要返回true。

应该这样说:

1,如果子类拥有自己的相等概念,则对称性需求将强制采用getClass进行检测。 例如雇员和经理,对应的域相等就认为两个对象相等;如果两个经历对应的名字薪水雇佣日期都相等,而奖金不相等,就认为他们不相同。

2,如果由超类决定相等的概念,那么可以用instanceof进行检测,就可以在不同的子类对象之间进行相等的比较。例如经理是雇员的儿子类,假设使用雇员的ID作为相等的检测条件,那么这个相等概念也适用于经理,此时可以用instanceof进行检测,并且应该将Employee.equals方法声明为final。

 编写完美equals方法的建议(来自CoreJava):

  1,显式参数命名为otherObject,稍后需要将它转换成另一个叫做other的变量 这里参数一定是Object类型 否则不会产生Override

  2,检测this和otherObject是否引用同一个对象

    

  1. if(this == otherObject) return true;

  3,检测otherObject是否为null。如果是null,则返回false

  4,比较this和otherObject是否属于同一个类。按照上面红字的总结:如果equals的语义在每个子类中有所改变,就用getClass检测:

  1. if (getClass() != otherObject.getClass()) return false;

  如果所有的子类都拥有统一的语义,就是用instanceof检测

  

  1. if (!(otherObject instanceof ClassName)) return false;

  5,将otherObject转换为相应的类类型变量:

  1. ClassName other = (ClassName) otherObject;

  6,现在开始对所有需要比较的域进行比较。使用 == 比较基本类型域, 使用equals比较对象域。 

  

  1. return field 1 == field2
  2. && Objects.equals(field2,other.field2)
  3. &&....... ;

  这里需要注意: 如果在两个参数都为null时需要返回true,那么应该使用Objects.equals(1,2)

         如果不能接受有参数为null,或者两个参数不会为null,则使用a.equals(b) (当有一个参数为null时,a.equals(b)将会抛出NullPointerException)

  如果在子类中重新定义equals,就要在其中包含调用super.equals(other)

getClass()和instanceof以及类的equals方法的更多相关文章

  1. Object类的toString和Equals方法,以及Objects类的Equals方法

    Object类 toString()方法 public class Person { private String name; private int age; public Person() { } ...

  2. object类的equals方法简介 & String类重写equals方法

    object类中equals方法源码如下所示 public boolean equals(Object obj) { return this == obj; } Object中的equals方法是直接 ...

  3. Java Object类及其equals方法

    基本概念: Object类位于java.lang包中,java.lang包包含着Java最基础和核心的类,在编译时会自动导入: Object类是所有Java类的祖先.每个类都使用 Object 作为超 ...

  4. Object类及其equals()方法

    ==  : 1.基本数据类型:根据基本数据类型的值判断是否相等,相等返回true,反之返回false 注意:两端数据类型可以不同, 在不同的情况下,也可以返回true 2.引用数据类型:Object ...

  5. Object 类的equals方法

    Object 类中定义有: public boolean equals (Object obj)方法 提供对象是否“相等”的逻辑 Object 的equals方法定义为:x.equals(y)当x和y ...

  6. Java Object类的equals()方法

    所有类都从Object类中继承了equals方法,Object类中equals方法源代码如下: public boolean equals(Object obj)     {         retu ...

  7. Java:Object类的equals()方法 如何编写一个完美的equals()方法

    一  代码实例: package freewill.objectequals;  /** * @author freewill * @see Core Java page161 * @desc get ...

  8. Object类—复写equals方法,hashCode方法,toString方法

    Object:所有类的根类. Object是不断抽取而来,具备着所有对象都具备的共性内容. class Person extends Object { private int age; Person( ...

  9. 注意重写类的equals()方法

    注意在java中在比较引用类型时==和原生的equals()方法比较的都是看它们否是同一个对象(说的更直白一点就是他们在内存的位置是否是一样的),但我们在真实世界中关注的往往只是其中的某个属性是否相等 ...

随机推荐

  1. Python_函数传参

    关于函数中传递参数的相关知识 其中 万能参数 第一次听说 但感觉用处不大 后面用到再详细整理

  2. Lombok中关于@Data的使用

    当你在使用 Lombok 的 @Data 注解时,其实会有一些坑需要关注,今天就让我们来见识一下. Lombok 先来简单介绍一下 Lombok ,其官方介绍如下: Project Lombok ma ...

  3. MySQL常用sql语句-----数据表的查询操作

    常用的sql语句如下,应对工作足以 1.查询指定字段 select c_id,c_age,c_name from t_student; select c_id as 编号,c_name as 姓名,c ...

  4. MySQL常用sql语句-----数据表的增删改操作

    常用sql操作如下: 1.查看当前数据库的所有表 show tables; 2.创建表 create table stu(sid int,sname char(20),sage int default ...

  5. 关于到美国学习cs的亲身感受,希望对你们有所帮助

    1.能否向各位寄托天下的朋友们简单介绍一下你自己?比如你国内的学校(或者什么档次),哪年申请出国的,什么专业,硕士还是博士,在美国的学校(或者什么档次),以及留学经历(毕业时间),现在状态(学生?博后 ...

  6. 【强烈推荐】可能是最适合你的 Java 学习路线和方法

    如遇链接无法打开,建议使用 https://github.com/Snailclimb/JavaGuide/blob/master/docs/questions/java-learning-path- ...

  7. spring boot 整合JPA多数据源

    上个文章介绍了spring boot在使用Mybatis持久化技术的时候如何使用多数据源,今天再补充一个使用spring data jpa实现多数据源的使用情况,JPA是一套数据库持久化规范,或者称之 ...

  8. 数据结构(二十七)Huffman树和Huffman编码

    Huffman树是一种在编码技术方面得到广泛应用的二叉树,它也是一种最优二叉树. 一.霍夫曼树的基本概念 1.结点的路径和结点的路径长度:结点间的路径是指从一个结点到另一个结点所经历的结点和分支序列. ...

  9. day3,用户交互,input的应用

    1.与用户交互 输入:input() python2.x版本 input后面家的东西要声明输入的类型       >>> input(">>:")   ...

  10. django-数据库之连接数据库

    1.连接数据库出现的一些问题 基本目录如下: 首先我们pip install pymysql 然后在项目中,进行配置settings.py: 然后在__init__.py中进行输入: 启动服务器: 报 ...