【Java】重写equals方法详细解析

equals方法用于比较两个引用数据类型是否相等,如String或者自己定义的类都属于引用数据类型。“==”则用于比较基本数据类型是否相等。

下边通过一个测试例逐行解析下equals方法原理。

首先直接看下面代码:( equals方法重写部分在67-74)

 1 import jdk.swing.interop.SwingInterOpUtils;
 2 
 3 public class Test01   {
 4     public static void main(String[] args) {
 5     Mytime m1 = new Mytime(2020,12,14);
 6     //调用toString(),
 7     String t = m1.toString();
 8     System.out.println(t);
 9     // 输出引用的时候,会自动调用该引用的toString方法。//ctrl + 鼠标左键打开源码
10         System.out.println(m1);
11     //调用equals()
12     Mytime m2 = new Mytime(2020,12,14);
13    // Mytime mytime = (Mytime)m1;
14     boolean f = m1.equals(m2);
15         System.out.println(f);
16         System.out.println(m1.day == m2.day);
17     Test m3 = new Mytime(2020,12,14);
18         System.out.println(m3.getClass());
19     }
20 }
21 class Mytime extends Test{
22     int year;
23     int month;
24     int day;
25     public Mytime(int year, int month, int day) {
26         this.year = year;
27         this.month = month;
28         this.day = day;
29     }
30     public void setYear(int year) {
31         this.year = year;
32     }
33     public void setMoonth(int month) {
34         this.month = month;
35     }
36     public void setDay(int day) {
37         this.day = day;
38     }
39     public int getYear() {
40         return year;
41     }
42     public int getMoonth() {
43         return month;
44     }
45     public int getDay() {
46         return day;
47     }
48     @Override
49     public String toString() {
50         return "Mytime{" +
51                 "year=" + year +
52                 ", month=" + month +
53                 ", day=" + day +
54                 '}'+"--"+getClass()+"--"+this.getClass();
55     }
56 /*    @Override
57     public boolean equals(Object o) {//这里的Object是基类,所有的类型都能通过这里调用,object o = m2,(或object o =new Mytime()
58         if (this == o) return true;//
59         if (o == null || getClass() != o.getClass()) return false;//o.getClass() =Mytime,
60         Mytime mytime = (Mytime) o;
61         //Mytime mytime = (Mytime) o;
62         return year == mytime.year &&
63                 month == mytime.month &&
64                 day == mytime.day;
65     }*/
66     @Override
67     public boolean equals(Object o) {
68         if (this == o) return true;
69         if (o == null || getClass() != o.getClass()) return false;
70         Mytime mytime = (Mytime) o;
71         return year == mytime.year &&
72                 month == mytime.month &&
73                 day == mytime.day;
74     }
75 }
76 class Test{
77     
78 }

 如上面equals部分(67-74)所示(由IDEA自动生成)。下面是逐行解释:

67行:

在本Test例中:首先以下代码(14行)调用equals方法,

14 boolean f = m1.equals(m2);

 在67行中的equals(Object o),可这样理解:Object o = m2或者可以理解成Object o = new Mytime(),因为m2 =new Mytime()。Object为基类。

 68行:

this存放了本对象(此处为m1)的内存地址,o存放了m2的内存地址。如果内存地址一样,肯定表示同一个对象;返回true。

69行:

o为null 返回false很好理解;getClass()返回本对象即m1的类名,o.getClass()返回o的类名不是Object,而是m2的类型名,原因在于:Object o = m2 (Object o =new Mytime()),返回的类名就是m2的。

在上面测试例中对此进行了测试,如下:

17     Test m3 = new Mytime(2020,12,14);
18     System.out.println(m3.getClass());

 

返回的m3.getClass()为Mytime,而不是Test。

m1的类名和m2的类名不同的话肯定不是同一个对象,返回false。

70行:

还是由于67行方法入口的Object o = new Mytime(),

Object类中肯定没有Mytime类中的属性,所以o作为内存地址虽然指向了一个Mytime对象,但是由于Object类中没有相应的属性,就无法通过o.来获取Mytime中的属性。

于是,就需要70行,把Object类型的o强转为Mytime类型的,之后就可以进行下一步的类中属性的比较。注:能执行到这一步,说明m1和m2是同一类了,但由于Object o的存在不能直接获取m2的内部属性。

71~74行就不需要解释了。

 

上一篇:js-txt文本处理,Java后台如何处理


下一篇:javascript中document.form[formName][]的意思