JavaSE——面向对象8:Object类详解(==与equals的区别、hashCode、toString方法)

news2024/11/28 0:43:01

目录

一、==与equals()的区别

(一)==是一个比较运算符

(二)equals是Object类中的方法,只能判断引用类型

(三)equals方法重写练习

1.练习1

2.练习2

3.练习3

二、hashCode方法

三、toString方法

1.默认返回:全类名(包名+类名)+@+哈希值的十六进制

(1)不重写toString方法

(2)重写toString方法

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

四、finalize关键字(开发中用得不多)


一、==与equals()的区别

(一)==是一个比较运算符

(二)equals是Object类中的方法,只能判断引用类型

默认判断的是地址是否相等,子类中往往重写该方法,用于判断内容是否相等。比如Integer、String

Object类的equals源码:判断俩个对象的地址是否相同

System.out.println("hello".equals("abc")); // false

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

Integer类的equals源码:判断值的内容是否相同

//从源码可以看到 Integer 也重写了Object的equals方法,
//变成了判断两个值是否相同
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

String类的equals源码:比较两个字符串值是否相同。

public boolean equals(Object anObject) {
if (this == anObject) {//如果是同一个对象
    return true;//返回true
}
if (anObject instanceof String) {//判断类型
    String anotherString = (String)anObject;//向下转型
    int n = value.length;
    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
}


String str1 = new String("helloworld");
String str2 = new String("helloworld");
System.out.println(str1 == str2);//false
System.out.println(str1.equals(str2));//true

(三)equals方法重写练习

1.练习1

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

public class EqualsExercise01 {
    public static void main(String[] args) {
        Person p1 = new Person("zhangsan", 16, '男');
        Person p2 = new Person("zhangsan", 16, '男');
        System.out.println(p1.equals(p2)); // true
    }
}

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

    // 重写equals方法
    public boolean equals(Object obj) {
        // 先判断地址是否相等
        if (this == obj) {
            return true;
        }

        if (obj instanceof Person) {
            // 向下转型,因为要取得obj中的各个属性
            Person p = (Person) obj;
            return this.name.equals(p.name) && this.age == p.age && this.gender == p.gender;
        }
        return false;
    }

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

2.练习2

public class EqualsExercise02 {
    public static void main(String[] args) {
        Person_ p1 = new Person_();
        p1.name = "hspedu";
        Person_ p2 = new Person_();
        p2.name = "hspedu";

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

        String s1 = new String("asdf");
        String s2 = new String("asdf");
        System.out.println(s1.equals(s2));// true
        System.out.println(s1 == s2); // false
    }
}

class Person_ {
    public String name;
}

3.练习3

int it = 65;
float fl = 65.0f;
System.out.println(it == fl); // true
char ch1 = 'A';
char ch2 = 12;
System.out.println(it == ch1); // true
System.out.println(12 == ch2); // true
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1 == str2); // false
System.out.println(str1.equals(str2)); // true
// System.out.println("hello" = new java.sql.Date()); 编译报错

二、hashCode方法

  1. hashCode能够提高具有哈希结构的容器的效率,例如HashSet、LinkedHashSet、Hashtable
  2. 两个引用,如果指向的是同一个对象,则哈希值肯定是一样的!
  3. 两个引用,如果指向的是不同对象,则哈希值是不一样的
  4. 哈希值主要是根据地址号来的!不能完全将哈希值等价于地址
  5. 在集合中也可能会需要重写hashCode
public class HashCode_ {
    public static void main(String[] args) {
        AA aa = new AA();
        AA aa2 = new AA();
        AA aa3 = aa;
        System.out.println("aa.hashCode()=" + aa.hashCode());
        // aa.hashCode()=1163157884
        System.out.println("aa2.hashCode()=" + aa2.hashCode());
        // aa2.hashCode()=1956725890
        System.out.println("aa3.hashCode()=" + aa3.hashCode());
        // aa.hashCode()=1163157884
    }
}

class AA {}

三、toString方法

基本介绍:

1.默认返回:全类名(包名+类名)+@+哈希值的十六进制

子类往往重写toString方法,用于返回对象的属性信息

Object类的toString方法的源码:

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

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
(1)不重写toString方法
public class ToString_ {
    public static void main(String[] args) {
        Monster monster = new Monster("小妖怪", "巡山的", 1000);
        System.out.println(monster.toString() + " hashcode=" + monster.hashCode());
        // 未重写toString方法的输出:
        // com.testdemo.object_.Monster@4554617c hashcode=1163157884       
    }
}

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;
    }
}
(2)重写toString方法

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

public class ToString_ {
    public static void main(String[] args) {
        Monster monster = new Monster("小妖怪", "巡山的", 1000);
        System.out.println(monster.toString() + " hashcode=" + monster.hashCode());
        // 重写了toString方法的输出:
        // Monster{name='小妖怪', job='巡山的', sal=1000.0} hashcode=1163157884
    }
}

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 -> toString
    // 重写后,一般是把对象的属性值输出,当然程序员也可以自己定制
    
    @Override
    public String toString() { 
        return "Monster{" +
                "name='" + name + '\'' +
                ", job='" + job + '\'' +
                ", sal=" + sal +
                '}';
    }
}

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

即:System.out.println(monster.toString());等价于  System.out.println(monster);

四、finalize关键字(开发中用得不多)

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

        Car bmw = new Car("宝马");
        // 这时 car对象就是一个垃圾,垃圾回收器就会回收(销毁)对象, 在销毁对象前,会调用该对象的finalize方法
        // 可以在 finalize中,写自己的业务逻辑代码(比如释放资源:数据库连接,或者打开文件..)
        // 如果不重写 finalize,那么就会调用 Object类的 finalize, 即默认处理
        // 如果重写了finalize, 就可以实现自己的逻辑

        bmw = null;
        System.gc();// 主动调用垃圾回收器

        System.out.println("程序退出了....");
        
        // 程序退出了....
        // 我们销毁 汽车宝马
        // 释放了某些资源...
    }
}

class Car {
    private String name;

    //属性, 资源。。
    public Car(String name) {
        this.name = name;
    }

    //重写finalize
    @Override
    protected void finalize() throws Throwable {
        System.out.println("我们销毁 汽车" + name);
        System.out.println("释放了某些资源...");
    }
}

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

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

相关文章

VS编译器实用调试技巧

一.什么是bug bug本意是"昆虫"或"虫子],现在一般是指在电脑系统或程序中,隐藏着的一些未被发现的缺陷或问题,简称程序漏洞。“Bug"的创始人格蕾丝.赫柏(Grace Murray Hopper)&#xff…

算法笔记(七)——哈希表

文章目录 两数之和判定是否互为字符重排存在重复元素存在重复元素 II字母异位词分组 哈希表:一种存储数据的容器; 可以快速查找某个元素,时间复杂度O(1); 当频繁查找某一个数时,我们可以使用哈希表 创建一个容器&#…

堆的代码和基础知识

堆的向上和向下调整-CSDN博客 1.堆的基础知识 2.堆的代码 Heap.h #pragma once #include<stdio.h> #include<assert.h> #include<stdlib.h> #include<stdbool.h> #include<time.h>// typedef int HPDataType; typedef struct Heap {HPDataTy…

电场磁场,能量密度和平均值(定义式是用实数场计算的,不能直接将定义式里面修改为复数场)

能量密度的定义式&#xff0c;都是实数场 平均能量密度&#xff0c;里面的是复数表示的场。具体推导类似坡印廷矢量 、

4.6章节python中空语句pass保留字作用

在Python中&#xff0c;pass 是一个空语句&#xff0c;它什么也不做。它通常用作占位符&#xff0c;在需要语法上需要一个语句但程序逻辑上不需要执行任何操作的地方。 1.占位符&#xff1a;在编写代码时&#xff0c;如果你还没有决定某个部分应该做什么&#xff0c;可以先用 p…

[深度学习][python]yolov11+bytetrack+pyqt5实现目标追踪

【算法介绍】 YOLOv11、ByteTrack和PyQt5的组合为实现高效目标追踪提供了一个强大的解决方案。 YOLOv11是YOLO系列的最新版本&#xff0c;它在保持高检测速度的同时&#xff0c;通过改进网络结构、优化损失函数等方式&#xff0c;提高了检测精度&#xff0c;能够同时处理多个…

android RadioButton 设置颜色无效

原因好像是 RadioButton 自动被渲染为 MaterialRadioButton 设置颜色使用这个属性 app:buttonTint“color/black” material-components-android/docs/components/RadioButton.md at master material-components/material-components-android (github.com)https://github.…

【MySQL】SQL介绍+基础+DDL+数据备份+还原

目录 一、DDL建库建表 1. 数据库 2. 内部4特征 3. 外部4特征 4. 数据库结构 5. SQL语句分类&#xff08;重点&#xff09; 6. 注意 7. 数据库表的字段类型 8. 存储引擎 9. 数据库表的操作 二、三范式 1. 什么是范式 2. 约束作用 3. 三范式 4. 第一范式&#xff…

Python从入门到高手4.2节-掌握循环控制语句

目录 4.2.1 理解循环控制 4.2.2 for循环结构 4.2.3 循环结构的else语句 4.2.4 while循环结构 4.2.5 循环结构可以嵌套 4.2.6 国庆节吃好玩好 4.2.1 理解循环控制 我们先来搞清楚循环的含义。以下内容引自汉语词典: 循环意指往复回旋&#xff0c;指事物周而复始地运动或变…

Sharp.js:简单而又实用的图像处理库

前言 在现代Web开发中&#xff0c;图像处理是一个不可或缺的部分。 前端开发者经常需要处理图像&#xff0c;以确保它们在不同的设备和分辨率上都能保持良好的显示效果。 sharp.js是一个高性能的Node.js模块&#xff0c;它利用了libvips库&#xff0c;提供了快速且高效的图像…

网安学习(js漏洞挖掘)

内容来自bili白帽大法师白帽大法师的个人空间-白帽大法师个人主页-哔哩哔哩视频 (bilibili.com) 四种方式 目录 1、JS中存在插件名字&#xff0c;根据插件找到相应的漏洞直接利用 2、JS中存在一些URL链接&#xff0c;根据URL链接找到相应的页面进一步测试和利用 3、JS中存…

《软件工程概论》作业一:新冠疫情下软件产品设计

课程说明&#xff1a;《软件工程概论》为浙江科技学院2018级软件工程专业在大二下学期开设的必修课。课程使用《软件工程导论&#xff08;第6版&#xff09;》&#xff08;张海藩等编著&#xff0c;清华大学出版社&#xff09;作为教材。以《软件设计文档国家标准GBT8567-2006》…

Python案例--水仙花数的探索之旅

一、引言 水仙花数&#xff0c;也称为阿姆斯特朗数&#xff0c;是一种特殊的三位数&#xff0c;其各位数字的立方和等于其本身。例如&#xff0c;153就是一个水仙花数&#xff0c;因为 135333153135333153。这种数字的发现不仅展示了数字的内在美&#xff0c;也激发了人们对数…

STM32编码器接口解析及抗噪声措施探讨

1. 引言 在现代控制系统中&#xff0c;编码器扮演着非常重要的角色。它就像一个精密的测量工具&#xff0c;可以告诉我们机械部件的位置和运动状态。在STM32微控制器中&#xff0c;编码器接口可以轻松地与各种编码器连接&#xff0c;实现精确的控制。我将在这里探讨STM32编码器…

unity 默认渲染管线材质球的材质通道,材质球的材质通道

标准渲染管线——材质球的材质通道 文档&#xff0c;与内容无关&#xff0c;是介绍材质球的属性的。 https://docs.unity3d.com/2022.1/Documentation/Manual/StandardShaderMaterialParameters.html游戏资源中常见的贴图类型 https://zhuanlan.zhihu.com/p/260973533 十大贴图…

flutter_鸿蒙next(win)环境搭建

第一步 拉取鸿蒙版本flutterSDK仓库 仓库地址&#xff1a;OpenHarmony-SIG/flutter_flutter 第二步 找到拉取的仓库中的README.md 并根据说明配置环境 第三步 配置好环境变量之后 用管理员开启cmd 输入&#xff1a;flutter dcotor 并查看此时flutter所支持的系统 包括&…

Cpp::STL—string类的模拟实现(12)

文章目录 前言一、string类各函数接口总览二、默认构造函数string(const char* str "");string(const string& str);传统拷贝写法现代拷贝写法 string& operator(const string& str);传统赋值构造现代赋值构造 ~string(); 三、迭代器相关函数begin &…

leetcode打卡001-约瑟夫问题

约瑟夫问题 其背景故事是关于一组人站成一个圈&#xff0c;从某个人开始报数&#xff0c;每数到特定数字的人将被淘汰出圈&#xff0c;然后从被淘汰人的下一个人重新开始报数&#xff0c;直到最后剩下一个人。问题的目标是确定最后剩下的那个人在最初的位置。 关键词 递归&a…

HCIP-HarmonyOS Application Developer 习题(四)

1、以下哪个Harmonyos的AI能力可以提供文档翻拍过程中的辅助增强功能? A.文档检测矫正 B.通用文字识别 C.分词 D.图像超分辨率 答案&#xff1a;A 分析&#xff1a;文档校正提供了文档翻拍过程的辅助增强功能&#xff0c;包含两个子功能&#xff1a; 文档检测&#xff1a;能够…

基于单片机人体反应速度测试仪系统

** 文章目录 前言概要设计思路 软件设计效果图 程序文章目录 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师&#xff0c;一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们…