Java基础39 Object类(节选)

news2025/1/22 22:45:42

Object

  • Object类
    • 一、 equals( )
      • ● == 与 equals的对比(☆)
    • 二、hashCode( )
    • 三、toString( )
    • 四、finalize( )


Object类

Object类:Java中lang包的类,是类层次结构的根类,每个类都使用Object作为超类。所有对象(包括数组)都实现这个类的方法。

Object类所含有的方法

  • clone()
  • equals(Object obj)
  • finalize()
  • getClass()
  • hashCode()
  • notify()
  • notifyAll()
  • toString()
  • wait()
  • wait(long timeout)
  • wait(long timeout, int nanos)

一、 equals( )

boolen | equals(Object ob) : 指示其他某个对象是否与此对象"相等"。

● == 与 equals的对比(☆)

(1)== 运算符

  1. == : 既可以判断基本类型,又可以判断引用类型
  2. == : 如果判断基本类型,判断的是值是否相等。
  3. == : 如果判断引用类型,判断的是地址是否相等,即判定是不是同一个对象。

例如:

public static void main(String[] args){
    	A a = new A();
    	A b = a;
    	A c = b;
    	System.out.println( a == c);
    	System.out.println( b == c);
}

class B{}
class A extends B{}

创建了一个A对象,现在有一个a引用,指向了A对象,再有一个b引用,指向了A对象,最后再创建一个c引用也指向A对象,现在用 == 号来比较a与c,而由上述概念得知:== 符号在比较引用类型时,比较的是它们所指向的地址值,而明显a与c指向的都是A对象,即地址值相同,所以a与c比较后返回的是true,同理b == c返回的也是true。

现在增加一个判断

B bObj = a;
Sysout.println(bObj == c);

这时创建一个向上转型的对象,而此时bObj指向的也是A对象,所以最后比较的地址值与c依然相等,最后输出的结果也是true。

(2)equals方法

equals

  1. Object类中的方法,只能判断引用类型
  2. 默认判断的是地址值是否相等,子类中往往重写该方法,用于判断内容是否相等。比如:Integer,String

String类的equals方法(JDK源码)

//把Object的equals方法重写了,变成了比较两个字符串值是否相同
if(anObject instanceof String){//判断类型
      String anotherString = (String)anObject; //向下转型
      int n = value.lenghth;
      if(n == anotherString.value.length){ //如果长度相同
           char v1[] = value;
           char v2[] = anotherString.value;
           int i = 0;
           while(n-- ! = 0){ //一个一个比较字符
               if(v1[i] != v2[i])
                   return false;
               i++;
           }
           return true; //如果两个字符串的所有字符都相等,则返回true
       }
}
return false //如果比较的不是字符串,则直接返回false

Object类的equals方法(JDK源码)

//Object 的 equals 方法默认就是比较对象地址是否相同
//也就是判断两个对象是不是同一个对象。
public boolean equals(Object obj){
	return (this == obj);
}

Integer类的equals方法(JDK源码)

public boolean equals(Object obj){
	if(obj instanceof Integer){
		return value == ((Integer)obj).intValue();
	}
	return false;
}

Integer integer1 = new Integer(1000);
Integer integer2 = new Integer(1000);
System.out.println(integer1 == integer2); //false
System.out.println(integer1.equals(integer2)); //true

● equals方法练习

实例1

判断两个Person对象的内容是否相等,如果两个Person对象的各个属性值都一样,则返回true,反之false。

创建Person类

class Person{
    private String name;
    private int age;
    private char gender;

    public Person(String name, int age, char gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }
}

创建test类

如果现在在主方法里直接调用equals方法,则调用的是Object类中的equals方法,因为Person没有继承任何类,默认继承的是Object类,而Object类中的equals方法相当于 “==” 来判断,比较的是地址值,很明显现在创建了两个对象,ps1和ps2,直接对比的话肯定返回的值是false,显然和我们想要的true不同。

public class test {
    public static void main(String[] args) {
    
        Person ps1 = new Person("jack",19,'男');
        Person ps2 = new Person("jack",19,'男');

        System.out.println(ps1.equals(ps2)); //false

    }
}

那如何得到正确的结果?那就是在Person中重写Object 的 equals方法。

在Person中重写Object的equals方法

    //重写Object的equals方法
    public boolean equals(Object obj){ //这里的Object obj指的是输出语句中传入的ps2
        //判断如果比较的两个对象是同一个对象,则直接返回true
        if(this == obj){ //这里的this指的是ps1
            return true;
        }
        //类型判断
        if(obj instanceof Person){ //是Person,才进行比较

            //向下转型,因为现在需要得到obj的各个属性
            Person p = (Person) obj;
            return this.name.equals(p.name) && this.age == p.age && this.gender == p.gender;
        }
        //如果不是Person,则直接返回false
        return false;
    }

实例2

看下列代码,分析输出的值为多少?

class Person{ //类 	
	public String name; 
 }

主方法

Person p1 = new Person();
p1.name = "ccc";

Person p2 = new Person();
p2.name = "CCC";

System.out.println(p1 == p2);
System.out.println(p1.name.equals(p2.name));
System.out.println(p1.equals(p2));

String s1 = new String("asdf");

String s2 = new String("asdf");
System.out.println(s1.equals(s2));
System.out.println(s1 == s2);

第一个输出语句

p1与p2的比较,由于是使用"==",所以比较的是地址值,而此时p1、p2分别是new出来的,并不是同一个对象,所以最后的结果为false

System.out.println(p1 == p2); //false

第二个输出语句

p1.name是字符串,已经把equals方法重写了,所以p1与p2比较的就是内容,显然内容一直,所以得到的结果应为true

System.out.println(p1.name.equals(p2.name)); //true

第三个输出语句

由于p1与p2都是自定义的类(Person),而此时的Person类中并没有重写equals方法,那么使用的就是他的父类Object的equals方法,所以比较的还是两者的地址值,显然最后的结果为false

System.out.println(p1.equals(p2)); //false

第四个输出语句

由于创建的是String类型的对象,必然使用的是String类重写的equals方法,所以两者比较的是内容的差异,显然二者都是一致的,最后的结果为true

System.out.println(s1.equals(s2)); //true

第五个输出语句

显然两者比较的是地址值,指向的不是同一个对象,所以最后的结果为false

System.out.println(s1 == s2); //false

运行结果

在这里插入图片描述

● 实例3

看下面的代码输出的是什么值?

int it = 65;
float fl = 65.0f;
System.out.println("65和65.0f是否相等? " + (it == fl));
char ch1 = 'A'; char ch2 = 12;
System.out.println("65和 'A' 是否相等? " + (it == ch1));
System.out.println("12和ch2是否相等? " + (12 == ch2));

String st1 = new String("hello");
String st2 = new String("hello");
System.out.println("str1和str2是否相等? " + (str1 == str2));

System.out.println("str1是否equals str2?" + (str1.equals(str2)));
System.out.println("hello" == new java.sql.Date());

false,false,true,true,true,true

第一个输出语句

由于是"==",所以判断的是值是否相等,而一个是int类型,一个是float类型,判断时自动转换,所以为true。

System.out.println("65和65.0f是否相等? " + (it == fl)); // true

第二个输出语句

同样是双等号,所以判断值是否相等,而 A 的ascll码值就为65,所以输出结果为true。

System.out.println("65和 'A' 是否相等? " + (it == ch1)); //true

第三个输出语句

同样是比较值,显然相等,所以输出结果为true。

System.out.println("12和ch2是否相等? " + (12 == ch2)); //true

第四个输出语句

两个对象str1、str2都是被new出来的新对象,所以地址值不同,结果为false

System.out.println("str1和str2是否相等? " + (str1 == str2)); //false

第五个输出语句

String类的equals方法必然重写,比较两者的值,相等,所以输出true。

System.out.println("str1是否equals str2?" + (str1.equals(str2))); //true

最后一个输出语句

编译器报错,因为编译器无法识别这两个对象的关系,它们既不是同一个类型,也没有继承关系,所以报错。

System.out.println("hello" == new java.sql.Date()); //报错

二、hashCode( )

hashCode( ) :返回该对象的哈希码值。

hashCode

  1. 提高具有哈希结构的容器的效率。
  2. 两个引用,如果指向的是同一个对象,则哈希值肯定相同,反之则不同(特殊情况除外)
  3. 哈希值主要根据地址号来的,不能完全将哈希值等价于地址!
  4. 后续在集合中介绍hashCode的重写。

hashCode的使用

现创建三个对象,一个aa1、aa2、aa3,其中aa1与aa2是新创建的对象,而aa3是指向aa1创建的对象。

public class test {
     public static void main(String[] args) {

        AA aa1 = new AA();
        AA aa2 = new AA();
        AA aa3 = aa1;

        System.out.println("aa1.hashCode() = " + aa1.hashCode());
        System.out.println("aa2.hashCode() = " + aa2.hashCode());
        System.out.println("aa3.hashCode() = " + aa3.hashCode());
    }
}

class AA{}

现在看通过hashCode输出的结果:

在这里插入图片描述
显然aa1与aa3是同一个对象,所以输出的值一致。

三、toString( )

toString( ) : 返回该对象的字符串表示。

  • 默认返回:全类名(包名 + 类名) + @ + 哈希值的十六进制(通过hashCode得到的整数),子类往往重写toString方法,用于返回对象的属性信息。

  • 重写toString方法,打印对象或拼接对象时,都会自动调用该对象的toString形式。

  • 当直接输出一个对象时,toString方法会被默认的调用。

Object的toString( ) 原码

ObjecttoString() 原码

(1) getClass().getName() 类的全类名(包名 + 类名)
(2) Integer.toHexString(hashCode()) 将对象的hashCode值转成16进制字符串

public String toString(){
	return getClass().getName() + "@" + Integer.toHexString(hashCode())
}

hashcode使用案例

创建Monster[name,job,sal]

直接使用toString

public class test {
     public static void main(String[] args) {

        Monster monster = new Monster("章鱼哥","恰人",1000);
         System.out.println(monster.toString() + "hashCode值 = " + monster.hashCode());
     }
}

class Monster{
    private String name;
    private String job;
    private double sal;

    public Monster(String name, String job, double sal) {
        this.name = name;
        this.job = job;
        this.sal = sal;
    }
}

运行效果

在这里插入图片描述

重写toString方法

class Monster{
    private String name;
    private String job;
    private double sal;

    public Monster(String name, String job, double sal) {
        this.name = name;
        this.job = job;
        this.sal = sal;
    }

    //重写toString方法,输出对象的属性
    //使用快捷键 alt + insert - >
    @Override
    //重写后,一般是把对象的属性值输出,当然程序员也可以自定义内容
    public String toString() {
        return "Monster{" +
                "name='" + name + '\'' +
                ", job='" + job + '\'' +
                ", sal=" + sal +
                '}';
    }
}

重写后继续调用monster,运行的结果如下所示:

在这里插入图片描述

当直接输出一个对象时,toString方法会被默认的调用。

还是以上面的代码为例,直接在输出语句中传入monster,实际上等价于monster.toString:

System.out.println(monster);//等价 monster.toString()

得到的结果如下所示:

在这里插入图片描述
但是可以注意到一个问题,那就是输出语句并没有重写hashcode,所以并没有输出哈希值。


四、finalize( )

finalize() :当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。

finalize()

  1. 当对象被回收时,系统自动调用该对象的finalize方法。子类可以重写该方法,做一些释放资源的操作。
  2. 什么时候被回收:当某个对象没有任何引用时,则jvm就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来销毁该对象,在销毁该对象前,会先调用finalize方法。
  3. 垃圾回收机制的调用,是由系统来决定(即有自己的GC算法),也可以通过System.gc()主动触发垃圾回收机制

finalize使用实例

public class test {
     public static void main(String[] args) {

         Car bmw = new Car("宝马");
         //把bmw置空,此时Car现在就没人使用,就变为了垃圾对象
         //这时垃圾回收器就会回收(销毁)这个对象(堆释放)
         //在销毁对象前,会调用该对象的finalize方法
         // 此时程序员就可以在finalize中,写自己的业务逻辑代码(比如释放资源:数据库链接,或者打开文件等等)
         //如果程序员不重写finalize,那么就会默认调用Object类的finalize方法,如果程序员重写了finalize,就可以实现自己的逻辑。
         bmw = null;
     }
}

class Car{
    private String name;

    public Car(String name){
        this.name = name;
    }
}      

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/26038.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【2015NOIP普及组】T3:求和 试题解析

【15NOIP普及组】求和 时间限制: 1000 ms 内存限制: 131072 KB 【题目描述】 一条狭长的纸带被均匀划分出了n个格子,格子编号从1到n。每个格子上都染了一种颜色colori用[1,m]当中的一个整数表示),并且写了一个数字numberi。 定义一种特殊的三元组:(x,y,z),其中x,…

Java架构该如何进阶?还在东拼西凑的学习?这份进阶指南相信会对你有所帮助,十多位资深大佬独家秘籍一并传授!

如何成为一名架构师? 笔者认为,想成为一名架构师,首先第一点必然是你的技术足够优秀,知识的深度和广度足够,遇到问题能很快从脑海中寻找出最合适的解决之道。其次,架构师会从整体上领导项目,与人打交道必不可少,因此…

区块链baas平台告警方案

前言 在《24*7动态化监管为“链”站岗》中,我们介绍了区块链动态化监控中心,如果说监控的作用是防患于未然,那么告警则是当异常发生时第一时间触发运维人员的关键,可充分降低监控对象异常的时间,最大化降低因异常给区…

深度解析KubeEdge EdgeMesh 高可用架构

摘要:通过高可用特性应用场景、高可用特性使用手册、课题总结、未来展望等四个部分的内容来向大家介绍新版本EdgeMesh的高可用架构。本文分享自华为云社区《KubeEdge EdgeMesh 高可用架构详解|KubeEdge云原生边缘计算社区》,作者:南开大学&am…

【计算机视觉OpenCV基础】实验二 基元检测

实验二 基元检测 计算机视觉OpenCV基础实验合辑(实验1234扩展) 资源下载地址: https://download.csdn.net/download/weixin_53403301 合辑:(加在下载地址后面) /87113581 讲义(包括理论、图例、…

[附源码]SSM计算机毕业设计火车售票系统论文JAVA

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

antd table 表格滚动高度适配

文章の目录问题产生背景如何解决写在最后问题产生背景 在开发一个后台管理系统,某一页面用到了table表格,产品的需求是: table表格无论展示多少条数据,表头和分页信息要展示出来 此时我们一定首先想到了table表格的 scroll 属性…

【设计模式】原型模式

原型模式属于创建型模式,主要作用是利用一个原型对象的克隆方法,在保证性能的情况下创建多个重复的对象,本质就是通过克隆一个原有的对象来复制出一个新对象。 文章目录原型模式的介绍使用场景原型模式的实现类图实现方法第一步,编…

一文解决 Go 安装和常用环境变量的配置

一文解决 Go 安装和常用环境变量的配置下载链接Windows 操作系统下安装Linux 操作系统下安装安装多个 Go 版本常用环境变量的解释结尾耐心和持久胜过激烈和狂热。 下载链接 官网:https://golang.org/dl中国大陆的镜像站点:https://golang.google.cn/dl/…

跨境电商卖家只青睐亚马逊?其实你不知道,“备胎”早已选好!(Starday)

跨境电商平台作为一个新的国际贸易形态,打破传统贸易形态的方式,将互联网与外贸交易相结合,从而大大降低外贸的运营成本,因此在这两年逐渐燃爆电商行业,让许多行业的人趋之若鹜,从观察中我们可以发现&#…

线性插值方法

插值,通俗来说当在一个离散的事件中,想知道某一个位置确定的值时,就可以利用插值方式计算得到,即利用已知数据估计未知位置数值。插值的方式有很多,下面介绍几种常用的插值方式。 一、最近邻插值(Nearest Neighbour …

矩阵分析:特征值分解都在这里了

矩阵分析:特征值分解前置知识空间变换伸缩旋转对称矩阵对称矩阵对角化正交矩阵向量的基基变换不同基下的向量变换逆矩阵不同基下的空间变换内积的几何意义特征值、特征向量特征值分解代码前置知识 空间变换 伸缩 一个矩阵其实就是一个线性变换,因为一个…

借道元宇宙 一汽-大众揽巡打造沉浸式上市体验

11月18日,一汽-大众以元宇宙科技为载体,举行了行业首场元宇宙游戏形式的“巡梦之旅”线上虚拟发布会,宣布旗下“硬核大五座SUV”揽巡Tavendor正式上市。全新揽巡共提供330TSI 精英巡行版、330TSI 豪华巡逸版、380TSI 四驱R-Line 巡游版、380T…

代码库制作与使用

静态库 假定有以下目录结构,main.c 为src测试文件,所以要调用src目录下的四个文件。我们可以把src打包成一个静态库供main.c使用 tree 命令展示目录结构制作 1.先把目标代码编译生成.o文件 需要包含头文件,否则会报错,使用-I来…

dB family cheat sheet: dB, dBW, dBm, dBi, dBc, etc

目录 1. dB 2. dBi 3. dBW和dBm 4. dBc(Decibel relative to carrier power level) 5. dBuV(dB over 1 microvolt), dBmV(dB over 1 millivolt) 6. 功率、电压、匹配阻抗 7. dBFS 1. dB dB用于表示功率之间的对数比率,所以它没有单位,其定义为&am…

【2022.11最新】Python疫情数据采集 + 可视化展示

嗨害大家好鸭!我是小熊猫 最近我又又又在家里居家办公了 闲来无事,用python采集一下 再做个可视化 康康现在疫情如何 源码、资料素材电子书点击这里 知识点: 1. 爬虫基本流程 2. requests 发送请求 3. re 正则表达式 4. json 结构化数据解析 5. pyech…

【深度学习】CycleGAN开源项目学习笔记 | 完整流程 | 报错总结 | pytorch

文章目录前言一、下载项目,文件结构观察二、数据集下载三、训练3.1、训练初体验3.2、命令行输入参数3.3、继续训练命令四、预测4.1、使用自己训练完的权重文件进行预测4.2、使用网上的预训练文件进行预测前言 你敢想象,就是这么一个简单的开源网站&…

南卡电容笔和绿联哪款更好用?性价比高的电容笔推荐

随着生活节奏逐渐加快,从而Apple Pencil的出现引来了不少热度,不过Apple Pencil由于价格昂贵,让不少用户望而止步。然而现在出现了平替电容笔,而且品牌众多,有很多百元左右的平替电容笔,性能和配置都做的不…

适合运动的耳机有哪些?六款相当不错的运动耳机分享

户外运动是现代青年最常见的一种生活方式,无论是在公交地铁上,还是晚上散步的公园里,都能看到很多人在运动,然而他们在做运动的时候都会佩戴上一款运动耳机,音乐能够让我们沉醉于运动中。也越来越多人会问,…

一款可以阻止网络钓鱼诈骗的解决方案?

“你继承了一笔财富。要转账,我需要你的银行账户凭证。” 你是否也遇见过此类的电话诈骗话术。 根据2022年数据泄露调查报告,25%的数据泄露涉及网络钓鱼。 这是怎么发生的?参与网络钓鱼的欺诈者一般都是心理方面的高手。他们知道如何营造紧…