A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© zhiguoguo 中级黑马   /  2015-12-22 23:35  /  406 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

// 先看Object类中的equals方法
class Object {
        public boolean equals(Object obj) {
                // 比较当前对象(即调用equals方法的那个对象)和方法参数接收的obj对象是否相等。
                // 默认认比较的是地址值,也就是说比较的是两个引用是否指向同一个对象。
                return (this == obj);
        }
}

// 所有类都直接或者间接继承自Object,我们分析String类的equals
class String extends Object { // 此处的extends Object写与不写都有
       
        // 此处的equals是重写父类Object的
        public boolean equals(Object obj) {
                // 重写之后比较的是当前字符串(即调用equals方法的那个字符串对象)和方法参数接收的obj对象是否相等。
                // 但不再比较地址值,比较的是两个字符串的实际字符是否一样。
                /*
                        通过分析源码我们发现字符串重写equals方法实现的比较过程如下:
                                为了提高效率:
                                        先判断两个对象地址值是否一样。如果一样,直接返回true,它们的字符值肯定一样。因为引用指向了同一个对象。
                                为了程序的健壮性:
                                        再判断传递过来的obj参数是否是String类型的参数,如果不是,没必要比较了,肯定是false。
                                判断实际字符值:
                                        然后,将两个字符串都转化成字符数组。依次比较数组相同索引处的两个字符是否相同。
                                        一旦发现有一个不同,返回false。全部相同才返回true。
                */
                return xxx;
               
                // 简而言之,String类重写equals方法实现了两个字符串真正字符值的比较。
               
        }
}

// 然后再看我们自定义的类
class Student { // 此处也包含一个默认的 extends Object
        private String name;
        private int age;
       
        // getters and setters
       
        // 我们也想重写equals方法实现两个Student对象的实际属性值的比较。所以我们也模仿String类的三步。
        public boolean equals(Object obj) {
                // 为了提高效率,如果两个Student对象的地址值一样,肯定true
                if (this == obj) {
                        return true;
                }
               
                // 为了程序的健壮性,判断参数obj是否是Student类的对象(或实例)
                if (!(obj instanceof Student)) {
                        // 参数obj不是Student类型的,没必要再比较了,并且也不能把obj向下转型成Student类型了。
                        return false;
                }
               
                // 上述两个条件都不满足,向下转型(因为父类引用不能使用子类特有的属性和行为),比较两个对象具体的属性值
                Student stu = (Student) obj;
               
                return this.age == stu.age && this.name.equals(stu.name);
                /*
                        解释 this.name.equals(stu.name)
                                this.name -- 表示调用方法的Student对象的name属性,它返回的是一个字符串类型。
                                stu.name -- 表示参数接收的Student对象的name属性,它返回的也是一个字符串类型。
                               
                                是String类型,那么它就可以调用String类的功能,而String的equals方法恰好已经实现了两个字符串具体值的比较。
                               
                                所以this.name.equals(stu.name),就是在比较两个对象的name属性值是否一样。
                               
                                这的equals与我们重写的Student类的equals没有关系,只不过我们重写的时候用到了String类的这个方法而已。
                               
                        如果仍有疑惑,看下面:
                                String s1 = this.name; -- 将字符串类型的this.name赋值给引用s1
                                String s2 = stu.name; -- 将字符串类型的stu.name赋值给引用s2
                                boolean b = s1.equals(s2); -- 调用String类的equals方法比较s1和s2这两个字符串的真正值
                               
                                将上面三行代码合并为一行不就是 this.name.equals(stu.name)
                */
        }
       
}

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马