Object类和Java中内置的一些接口

news2024/11/23 20:53:45

文章目录

  • 一、Object类
    • 1.1Object类中的方法
      • 1.1.1toString()方法
      • 1.1.2equals()方法
      • 1.1.3hashCode()方法
  • 二、Java中内置的一些接口
    • 2.1Comparable<T>接口
    • 2.2Cloneable接口

一、Object类

Object类是所有类的父类

1.1Object类中的方法

1.1.1toString()方法

Object类中的toString()方法:

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

要获取自定义类型对象的信息,可以在自定义类型(类)中重写toString方法

System.out.println(person);//在Person类中没有重写toString方法时,打印的是practice.Person@1b6d3586;在Person类中重写toString方法后,打印的是自定义类型对象的信息(但重写的toString方法要写对)

1.1.2equals()方法

比较自定义类型(类)对象中的内容是否相同时,要在自定义类型中重写equals方法,equals方法的返回值是true或fase。建议自定义类型要重写equals方法(使equals方法实现自己想要的比较逻辑)
Object类中的equals方法:

public boolean equals(Object obj) {
    return (this == obj); // 使用引用直接来进行比较,谁调用equals,谁就是this
}

观察以下代码

Person p1 = new Person("ZhangSan", 20);
Person p2 = new Person("ZhangSan", 20);
int a = 10;
int b = 10;
System.out.println(a == b);//打印true
System.out.println(p1 == p2);//打印false
System.out.println(p1.equals(p2));//打印false

以上代码p1和p2两个人的名字和年龄相同,在这里我们希望System.out.println(p1.equals(p2))打印的是true
在Person类中没有重写equals方法时,下面两行代码没有区别

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

所以要在Person类中重写Object类中的equals方法,可以手动重写,也可以用idea生成,点击Generate和equals() and hashCode()

 @Override
    public boolean equals(Object obj) {
        if(obj == null) {//p1可以调用equals方法,说明p1指向的人已经创建好,p2为null不指向任何对象,说明p2指向的人没有被创建好
            return false ;
        }
        if(this == obj) {
            return true ;
        }
        if(!(obj instanceof Person)) {//检查obj是否引用了Person类型的对象
            return false ;
        }
        Person person = (Person)obj ;//向下转型,因为obj是父类引用
        return this.name.equals(person.name) && this.age==person.age ;
    }

1.1.3hashCode()方法

建议自定义类型要重写hashcode方法,可以简单地认为hashcode方法返回的是对象的地址,但这个地址是被处理过的
hashcode方法源码:

public native int hashCode();

hashcode方法由native修饰,底层是由C/C++代码写的,我们看不到

Person per1 = new Person("yixing", 20) ;
Person per2 = new Person("yixing", 20) ;
System.out.println(per1.hashCode());//打印460141958
System.out.println(per2.hashCode());//打印1163157884

以上代码p1和p2两个人的名字和年龄相同,在这里我们希望System.out.println(per1.hashCode())和System.out.println(per2.hashCode())打印的结果一样,所以要在Person类中重写Object类中的hashCode方法
下面是用idea生成重写的hashCode方法:

@Override
public int hashCode() {
return Objects.hash(name, age);
}

在Person类中重写Object类中的hashCode方法后,将p1和p2两个人的name和age传入重写的hashCode方法里的Objects.hash(name, age),Objects.hash(name, age)在逻辑上帮我们算出了这是同一个位置,返回这同一个人的地址

二、Java中内置的一些接口

2.1Comparable接口

(1)自定义类型的对象要比较大小,则在这个自定义类型(类)中实现Comparable接口,在这个自定义类型(类)中重写compareTo方法,来实现比较的逻辑,因为Comparable接口中的compareTo方法没有具体的实现,compareTo方法的返回值是int,Comparable的T是什么类型(如Person类型),compareTo的参数就是什么类型(如Person类型),因为Comparable源码的泛型是这样写的

class Person implements Comparable<Person>{
    public String name ;
    public int age ;
    public Person(String name, int age) {
        this.age = age ;
        this.name = name ;
    }
    @Override
    public int compareTo(Person o) {//重写compareTo方法后,compareTo用人的年龄来进行比较
        return this.age - o.age;
    }
}
public class Practice1 {
    public static void main(String[] args) {
        Person p1 = new Person("ZhangSan", 15) ;
        Person p2 = new Person("LiSi", 20) ;
        System.out.println(p1.compareTo(p2));//输出结果是-5
    }
}

数组排序Arrays.sort(arrays)底层是将数组的内容拿出来,强制类型转换为Comparable类型再调用compareTo方法(((Comparable)a[runHi++]).compareTo(a[lo])),数组内容是整数时可以用sort直接比较,数组内容是对象的引用时,则要在数组内容的类型(类)中实现comparable接口和重写compareTo方法
comparable接口对类的侵入性比较强,较不灵活
(2)使用比较器,对类的侵入性不强,较灵活,比较器(重新定义一个类,在这个类实现Comparator接口,在这个重新定义的类中重写compare方法,要比较时new一个这个重新定义的类的对象,用这个对象调用重写的compare方法),Comparator的T是什么类型(如Student类型),compare的参数就是什么类型(如Student类型),因为Comparator源码的泛型是这样写的

class AgeComparator implements Comparator<Student>{
    @Override
    public int compare(Student o1,Student o2){
        return o1.age-o2.age;
    }
}
class NameComparator implements Comparator<Student> {
    @Override
    public int compare(Student o1,Student o2){
        return o1.name.compareTo(o2.name);
    }//o1.name是String类型的引用,String类中实现了Comparable接口和重写了compareTo方法
}

public class Test{
    public static void main(String[] args) {
        Person p1 = new Person("ZhangSan", 10);
        Person p2 = new Person("LiSi", 15);
        AgeComparator ageComparator = new AgeComparator();
        System.out.println(ageComparator.compare(p1, p2));
        NameComparator nameComparator = new NameComparator();
        System.out.println(ageComparator.compare(p1, p2));
    }
}

2.2Cloneable接口

(1)Object类中有clone方法
以下是浅拷贝:

class Person implements Cloneable{//克隆接口Cloneable(空接口/标记接口),证明当前类是可以被克隆的
    public int age;
    public Person(int age){
        this.age = age;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException{//这里重写了Object类的clone方法,Object类的clone方法声明的异常是受查异常/编译时异常,必须是编译时处理
        return super.clone();//clone()在Object类中是protected修饰的(不是public修饰),所以要在Test2类中用person1调用clone()来克隆person1指向的对象,则要在Person类中重写clone()方法,这个重写的clone()方法里面用super调用Object类的clone()方法
    }
}
public class Test2{
    public static void main (String[] args) throws CloneNotSupportedException{//声明clone方法会出现的异常
        Person person1 = new Person(10);
        Person person2 = (Person)person1.clone();//向下转型,要强制类型转换,因为clone()方法的返回值类型是Object类型,返回值类型是父类。这里person1调用克隆方法,克隆person1指向的对象
        System.out.println(person1);//以下两个打印的结果相同
        System.out.println(person2);
    }
}

(2)浅拷贝:只克隆对象。深拷贝:克隆对象中的对象。
以下是深拷贝:

class Money implements Cloneable{
    public double money = 10.0;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    @Override
    public String toString() {
        return "Money{"+"money="+money+'}';
    }
}
class Person implements Cloneable{
    public int age;
    public Money m;//这里用了组合
    public Person(int age){
        this.age = age;
        this.m = new Money();
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person tmp = (Person) super.clone();
        tmp.m = (Money) this.m.clone();//clone()在Money类中虽然是protected修饰,但这里是同一个包下的不同类,所以可以在Person类中通过对象的引用调用Money类的clone()以克隆Money类对象
        return tmp;                    //克隆this.m所指向的内容,谁调用这个方法谁就是this,p1调用了这个方法所以p1是this,克隆p1.m所指向的内容
    }
    @Override
    public String toString() {
        return "Person{"+"age="+age+",m="+m+'}';
    }
}
class Test2 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person p1 = new Person(10);
        Person p2 = (Person) p1.clone();
        System.out.println(p1);
        System.out.println(p2);
        p2.m.money = 20.0;
        System.out.println(p2);
    }
}

在这里插入图片描述
打印结果是:
在这里插入图片描述
p2.m.money = 20.0改变了p2对象中的m对象里money的内容,说明p2对象中的m对象也被克隆出来了。

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

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

相关文章

Optimize Game Objects骨骼节点优化后SkinMesh以及动态骨骼

为了降低模型动画的性能开销&#xff0c;可以进行骨骼节点优化。 一、接口 unity官方提供了有两种方式可以进行节点优化&#xff1a; 注意当骨骼节点被优化后&#xff0c; Transform节点被剔除&#xff0c;因此需要将挂点等需要用到的节点暴露出来&#xff0c;即下面两个接口…

【高级篇】微服务保护

文章目录 微服务保护1.初识Sentinel1.1.雪崩问题及解决方案1.1.1.雪崩问题1.1.2.超时处理1.1.3.仓壁模式1.1.4.断路器1.1.5.限流1.1.6.总结 1.2.服务保护技术对比1.3.Sentinel介绍和安装1.3.1.初识Sentinel1.3.2.安装Sentinel 1.4.微服务整合Sentinel 2.流量控制2.1.簇点链路2.…

<DB2>《DB2内存详细介绍》

《DB2内存详细介绍》 1 架构图2 主要概念2.1 内存集&#xff08;Memory Set&#xff09;2.2 内存池&#xff08;Memory Pool&#xff09;2.3 内存块&#xff08;Memory Block&#xff09; 3 内存方案3.1 第一级服务器内存3.2 第二级操作系统内存和实例共享内存3.3 第三级数据库…

K8S | 核心原理分析

整体上理解流程和原理&#xff1b; 一、背景 基于分布式的架构中&#xff0c;需要管理的服务是非常多的&#xff0c;无论是服务的数量还是体系划分&#xff1b; 从服务的能力上看&#xff0c;可以进行分层管控&#xff0c;只是其中有相当一部分服务层&#xff0c;改动更新的频…

【Python黑科技】自动答题项目代码分析(保姆级图文+实现代码)

目录 实现效果图片素材和源码 实现思路1. 打开对应网页&#xff0c;做好准备工作2. 获取正确答案3. 答题4. 提交试卷实现代码总结 欢迎关注 『Python黑科技』 系列&#xff0c;持续更新中 欢迎关注 『Python黑科技』 系列&#xff0c;持续更新中 实现效果 图片素材和源码 已经…

chatgpt赋能python:Python如何在图像上标注

Python如何在图像上标注 对于图像标注&#xff0c;Python提供了许多工具和库&#xff0c;其中最常用的是OpenCV和Pillow。这篇文章将介绍如何使用Pillow在图像上进行标注。 安装Pillow库 在使用Pillow库之前&#xff0c;需要先安装它。在命令行中输入以下命令&#xff1a; …

2023-06-02 stonedb-修改包含内连接的嵌套外连接-问题反思

摘要: 最近在搞一个列存储引擎的包含内连接的嵌套外连接过慢的问题, 连接执行过慢的原因分析见此前的博客分析, 虽然逻辑很绕, 但是也不是无法分析. 更麻烦的问题在于修改查询计划, 让其能按照代价更小的方式正确的执行. 遇到的问题比我在修改查询计划前设想的更为棘手, 本文…

chatgpt赋能python:Python循环次数:实现高效编程的关键

Python循环次数&#xff1a;实现高效编程的关键 在编写Python程序时&#xff0c;循环次数是一个经常需要关注的问题。循环次数过多会导致程序执行效率低下&#xff0c;甚至可能引起性能问题。因此&#xff0c;如何控制循环次数成为实现高效编程的关键。本文将介绍Python中循环…

chatgpt赋能python:Python如何实现将数据结果导出

Python如何实现将数据结果导出 在Python编程中&#xff0c;我们经常需要将代码运行的结果导出保存在文件中&#xff0c;或在其他程序中使用。下面我们将介绍Python中几种将数据结果导出的方法。 方法一&#xff1a;使用文件输出 使用Python内置的open方法来打印输出的结果到…

【C++】类和对象 - 对象特性 - 构造函数和析构函数,函数分类及调用,拷贝构造函数调用时机,构造函数调用规则,深浅拷贝,初始化列表,类对象作为类成员

No.Contents1【C】基础知识 - HelloWorld&#xff0c;注释&#xff0c;变量&#xff0c;常量&#xff0c;关键字&#xff0c;标识符2【C】数据类型 - 整型&#xff0c;sizeof&#xff0c;实型&#xff0c;字符型&#xff0c;转义字符&#xff0c;字符串类型&#xff0c;布尔类型…

chatgpt赋能python:Python版本更新:为什么你应该及时升级

Python版本更新&#xff1a;为什么你应该及时升级 作为一名有10年Python编程经验的工程师&#xff0c;我深刻理解Python版本更新的重要性。在这篇文章中&#xff0c;我将向你介绍Python版本更新的背景和原因&#xff0c;并告诉你如何及时升级Python的版本以保持你的代码的安全…

由 Direct buffer memory 引发的附件下载优化方案

文章目录 前言一、Direct buffer memory1.1 原因分析1.2 解决方案 二、附件下载2.1 问题分析2.2 解决方案2.2.1 本地下载2.2.1 minio下载 前言 本地上传大文件内存溢出 Direct buffer memory附件下载服务端传流给前端需要将流缓存完毕才可以下载&#xff0c;导致大文件下载系统…

浏览器的渲染原理

网页的解析过程 ◼ 常见的浏览器内核有  Trident &#xff08; 三叉戟&#xff09;&#xff1a;IE、360安全浏览器、搜狗高速浏览器、百度浏览器、UC浏览器&#xff1b;  Gecko&#xff08; 壁虎&#xff09; &#xff1a;Mozilla Firefox&#xff1b;  Presto&#xff…

chatgpt赋能python:Python散点图连接成光滑曲线的技巧

Python散点图连接成光滑曲线的技巧 Python是一种功能强大的编程语言&#xff0c;广泛用于数据科学、机器学习、Web开发和自动化等领域。在数据可视化中&#xff0c;散点图是一种非常重要的图表类型&#xff0c;用于显示两个变量之间的关系。然而&#xff0c;有时散点图可能过于…

Linux 可视化管理-webmin 和 bt 运维工具

Linux 可视化管理-webmin 和bt 运维工具 webmin 基本介绍 Webmin 是功能强大的基于Web 的Unix/linux 系统管理工具。管理员通过浏览器访问Webmin 的各种管理功能并完成相应的管理操作。除了各版本的linux 以外还可用于&#xff1a;AIX、HPUX、Solaris、Unixware、Irix 和Fre…

freeRTOS学习(四)

队列管理 队列提供了任务到任务、任务到中断和中断到任务的通信机制。 队列的特征 数据存储 队列可以保存有限数量的固定大小的数据项。一个队列所能容纳的最大条目数称为它的长度。每个数据项的长度和大小都在创建队列时设置。 队列通常用作先进先出&#xff08;FIFO&…

【利用AI让知识体系化】常见的移动端适配知识

I. 引言 A. 移动设备的普及度 移动设备的普及度近年来持续攀升&#xff0c;据统计&#xff0c;截至2021年&#xff0c;全球手机用户数量已达51.98亿&#xff0c;而智能手机的普及率则已经超过了70%&#xff0c;成为人们生活中最为重要和常用的工具之一。 同时&#xff0c;平…

chatgpt赋能python:Python如何更改?

Python如何更改&#xff1f; 如果您想成为一名成功的Python程序员&#xff0c;那么您需要知道如何更改Python代码。在这篇文章中&#xff0c;我们将介绍Python如何更改&#xff0c;并提供一些实用的技巧和建议来使您的编码更加高效和有用。 什么是Python&#xff1f; Python…

chatgpt赋能python:Python如何填充颜色

Python如何填充颜色 Python是一种简单易学但功能丰富的编程语言&#xff0c;被广泛用于各种开发领域。其中填充颜色是Python中的一个非常重要的功能&#xff0c;在很多项目中都会经常用到。本文将介绍Python如何填充颜色&#xff0c;让你快速上手。 什么是填充颜色 填充颜色…

Python matplotlib库的使用

目录 画图的两种基本方式&#xff1a; 隐藏边框&#xff1a; 隐藏坐标系 设置网格线 共享坐标轴 双坐标轴 设置坐标轴标签及刻度字体大小 设置坐标轴标签据离坐标轴距离 画点与线 标注文字 画不同大小的多个坐标系 调节子图间距 导入库&#xff1a; import matplotl…