关于java核心技术(卷一)读后的思考(equals方法的讨论)

zzuzhouxiang      2022-04-27     612

关键词:

这是我反复看了两遍才理解的部分。其中也不乏参考了他人的微博内容,才大致对这个方法有所理解。

首先我们从Object类开始说起,

书中已经说了Object类是Java中所有类的始祖,在Java中的每个类都是由他扩展而来的,但在现实使用中并没有要求写出。如果一个类并没有明确指出超类,Object就是被认为是这个类的超类。

可以用Object类型的变量引用任何类型的对象:

Object obj = new Employee("Harry Hacker",35000);

正如昨天的博文所提到过的,Object只是用作各种值的通用持有者,是无法对其中的内容进行操作的,如果想要对其进行操作的话,需要弄清对象的原始类型,并对其进行类型转换。如:Employee e = (Employee)  obj;

 

 

 

知道这些我们就可以来提一提equals方法了;

在java中,对于基本数据类型,判断它们是否相等是通过“==”来进行判断的,而equals方法是用于检测一个对象是否等于另外一个对象的。在Object类中这个方法是判断两个对象是否具有相同的引用。但这种判断在大部分情况下是没有意义的,因为我们经常要检测的是两个对象状态的向邓姓,如果两个对象状态相等了,就表示相等了。

例如,若两个雇员对象的姓名、薪水和雇佣日期都一样,就认为它们是相等的。

其中equals代码实现如下:

public class Employee{

……

public boolean equals (Object otherObject){

  if(this==otherObject)                                                      //首先判断是否具有相同的引用

     return true;

if(othterObject==null)                                                    //判断显式参数是否为空

   return false;

if(getClass()!=otherObject.getClass())                         //判断二者是否属于相同的类

  return flase;

Employee other=(Employee)otherObject;                     //把显式参数类型转换成相同类型,这样可以对其进行操作

  return name.equals(other.name)&&salary==other.salary&&hireDay.equals(other.hireday);

    }

}

 

 

相等测试与继承

在上面的代码,我们会想到一个问腿,若隐式参数和显示参数不属于同一个类,equals方法将如何处理?

这时候我们就会引出另一个关键字instanceof,当时我看书的时候是不能理解书上想表达的意思。因为instanceof这个关键字可能是第一次出现在书本上,而我在前面的学习中并没有印象,所以我当时就是网上查阅资料,至于正确性我也不敢保证,但是我如果按照他的解释是可以解释的通的,所以我先在这里列出来:

java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。

了解这个关键字之后我们还要知道Java语言贵伐要求equals方法具有以下特性:

1)自反性:对于任何非空引用x,x.equals(x)都应返回true

2)对称性:对于任何引用x和y,当且仅当y.equals(x)返回true,x.equals(y)也应该返回true。

3)传递性:对于任意引用,x、y、z,如果x.equals(y)返回true,y.equals(z)返回true,则x.equals(z)也应返回true。

4)一致性:如果x和y引用的对象没有发生变化,反复调用x.equals(y)应该返回同样的结果。

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

了解这些之后,就会出现一个问题:

若出现e.equals(m),这里的e是一个Employee对象,m是一个Manager对象,并且两个对象具有相同的姓名,薪水和雇佣日期。

这样的话,如果在Employee.equals中用instanceof进行检测,则会返回出,而反过来调用因为对称性的原因,也应该返回true。所以我们就给出一个完美的equals方法的建议:

1)显式参数命名为otherObject,稍后需要将它转换成另一个叫做other的变量。

2)检测this和otherObject是否引用同一对象:

if(this==otherObject)

  return true;

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

4)比较this和otherObject是否属于同一个类。如果equals的语义在每个子类中有所改变,如果equals的语义在每个子类有所改变,就使用getClass()检测。

if(getClass()!=otherObject.getClass())

  return  false;

这里有必要解释一下getClass()方法的原理了:

技术分享图片

 

 即返回:

表示此对象的运行时类的类对象。

同时我还举了例子以此说明:

技术分享图片

 

技术分享图片

 

public class GetclassDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Employee e=new Employee();
        Manager m=new Manager();
        e.setId(1);
        m.setId(1);
        
    
        
        if(m.getClass()==e.getClass()) {
            System.out.println("yes");
        }else
        {
            System.out.println("no");
        }
        if(m.equals(e)) {
            System.out.println("yes");
        }else
        {
            System.out.println("no");
        }
        if(m instanceof Employee) {
            System.out.println("yes");
        }else {
            System.out.println("no");
        }


    }

}
结果:

class com.java.getclassDemo.Employee
++++++++++
class com.java.getclassDemo.Manager
++++++++++
class com.java.getclassDemo.Manager
no
no
yes

下面来分析一下,第一二行是初始化Employee时调用的getClas()方法

此时为Employee,

第三四排为调用子类Manager的构造函数时同时会调用其超类的构造函数,再调用自己的getClass();

而后面第二个no表示二者表示的状态并不一样,而第三个yes表示m确实为Employee的子类,也从侧面证明上文说到的方法是正确的。  

 

 

回到正文。接下来时如果所有子类拥有同一语义,则可以用instanceof检测。

5)将otherObject转换为相应的类类性变量。

这里的类型转换我觉得有个博主解释的特别好

https://blog.csdn.net/heidou369/article/details/80414904

但是对于getClass()我并不赞同他的看法,在这里我也不知道谁对谁错

6)接下来对所有的需要匹配的域进行匹配就可以了。

 













































关于java核心技术(卷一)读后的思考(内部类的讨论)

内部类内部类是定义在另一个类中的类。定义内部类的原因有:1)内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据。2)内部类可以对同一个包中的其他类隐藏起来。3)当想要定义一个回调函数且不想编写... 查看详情

关于java核心技术(卷一)读后的思考(泛型数组列表的讨论)

在C++中编译时是要确定数组大小的,而Java有所不同,它允许在运行时确定数组的大小。但是如果仅通过数组是无法改变运行时无法动态更改数组的问题。一旦确定了数组大小,就很难改变他了数组的大小了,要解决这个问题,... 查看详情

关于java核心技术(卷一)读后的思考(用户自定义类,静态域和静态方法的思考以及方法参数)

用户自定义类:这部分并没有太过于困难的部分,借由代码进行复习:Employee类的定义:packagecom.java.EmployeeTest;importjava.time.*;publicclassEmployee{   privateStringname;   privatedoublesalary;  &nb 查看详情

关于java核心技术(卷一)读后的思考(接口的基本知识的讨论)

接口接口技术:这种技术主要用来描述类具有什么功能,而并不给出每个功能的具体实现。一个类可以实现一个或多个接口,并在需要接口的地方,随时使用实现了相应接口对象。接口概念:接口不是类,而是对类的一组需求的... 查看详情

关于java核心技术(卷一)读后的思考(对象与类,日历的构造)

关于这本书,前三张都是基本内容,我觉得个人掌握的还可以,所以从第四章开始整理每日所学。第四章主要说的是对象和类。第一部分是面向对象程序设计的概述。其中面向对象程序设计简写OOP,接下来写的是类,即构造对象... 查看详情

关于java核心技术(卷一)读后的思考(lambda表达式的讨论)

lambda表达式lambda表达式是一个可传递的代码块。可以以后执行一次或者多次。在程序运行中我们经常会遇到传递代码段的情况,但是我们一般都是先构造一个对象,然后通过对象调用相应的代码块来实现传递代码块的目的,这个... 查看详情

《java核心技术卷一》随笔

1.静态常量:  静态变量使用得比较少,但静态常量使用得比较多,例如,在Math类中定义了一个静态常量:  publicstaticfinalPI=3.141592653;  在程序中,可以采用Math.PI的形式获得这个常量。  如果关键字static被省略,PI就变... 查看详情

java核心技术卷一笔记7

第九章集合9.1Java集合框架在Java类库中,集合类的基本接口是Collection接口。访问集合元素时,使用“foreach”循环编译器会将其翻译成带有迭代器的循环。元素被访问的数据取决于集合类型,对于ArrayList进行迭代就会按顺序得到... 查看详情

java核心技术卷一笔记8

第十四章并发多进程和多线程的区别:每个进程拥有自己的一套变量,而线程共享数据。14.1什么是线程不要调用Thread类或Runnable对象的run方法。直接调用run方法只会执行同一个线程中的任务,而不会启动新线程。应该调用start方... 查看详情

java核心技术卷一笔记六date类

在Java核心技术卷就行了一前期 date类出现的频率很高 所以就对date类进行了小小的整合Date类有两个date类表示特定时间的类 这个构造函数分配一个Date对象并初始化它代表指定的毫秒数,因为被称为“纪元”,即1970年1... 查看详情

《java核心技术(卷一)》读书笔记——第六章:内部类

1.      内部类的概念?类中类2.      为什么要用内部类?内部类的方法可以访问外部类的实例域内部类对外部类的同一个包中的类实现了隐藏匿名内部类在“想要定义一个回调函数却... 查看详情

go语言核心技术(卷一)之2.1-整数

第二章序 在计算机底层,一切都是比特位。然而计算机一般都操作固定大小的数,称之为字(word)。字会被解释为整数、浮点数、比特位数组、内存地址等,这些字又可以进一步聚合成数据包(packet)、像素点、作品集、是个或者... 查看详情

面霸篇:高频java基础问题(核心卷一)(代码片段)

从面试题作为切入点提升大家的Java内功,所谓根基不牢,地动山摇。只有扎实的基础,才是写出写好代码。拒绝知识碎片化码哥在《Redis系列》的开篇Redis为什么这么快中说过:学习一个技术,通常只接触了零... 查看详情

《大型网站技术架构:核心原理与案例分析》读后感

 李智慧的著作《大型网站技术架构:核心原理与案例分析》,写得非常好, 本着学习的态度,对于书中的关于性能优化的讲解做了一个思维导图,供大家梳理思路和学习之用。抛砖引玉。   查看详情

左耳朵耗子关于技术变现一文读后感

核心论点我完全没有必要通过打工听人安排而活着,而是反过来通过在公司工作提高自己的技能,让自己可以更为独立和只有地生活如何技术变现保持学习,掌握大多数人不能掌握的技能,先让周围的人有求于我关注有价值的东... 查看详情

《构建之法》第十六章读后感更正

第十六章IT行业的创新1.关于灵感。灵光闪现固然重要,很多伟大的发明依靠的就是灵光一现的基础,但是灵光闪现的前提是个人的思考,长时间的思考。完成这一灵光的基础是不断的尝试,提高自己的技术。这样才会将自己的... 查看详情

《java核心技术》读后感(java小虚竹)

❤️作者主页:小虚竹❤️作者简介:大家好,我是小虚竹。Java领域优质创作者🏆,CSDN博客专家🏆,华为云享专家🏆,掘金年度人气作者🏆,阿里云专家博主🏆❤️技术活,该赏... 查看详情

读书列表

 记录读书列表,促进阅读~蓝血十杰2017-04-20百年孤独(英文版)ThinkinginC++(英文版)卷一2017-04-26ThinkinginC++(英文版)卷二ReadingCodeJava核心技术卷一Java核心技术卷二重构    查看详情