ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java中的Object对象

2021-03-17 17:31:26  阅读:123  来源: 互联网

标签:Java 克隆 对象 clone Object equals hashCode


一、Object对象简介

Object类是java.lang包下的核心类,是所有类的父类
所有的Java对象都隐式地继承了Object对象(不用写extends继承)
所有的对象都拥有Object默认的方法

那么先来看一看Object都有些什么方法:
在这里插入图片描述
registerNatives() 底层实现
clone() 克隆(复制)
equals() 对象值比较
finalize() 垃圾回收前调用的方法
getClass() 返回字节码文件对象class
hashCode() 对象的hash值
notify() 唤醒线程
notifyAll() 唤醒全部线程
toString() 获取对象的信息
wait() 线程等待


二、equals和hashCode方法

equals()比较对象的地址是否相等,如果子类重写,则比较对象的内容是否相等

public native int hashCode();
public boolean equals(Object obj) {
	return (this == obj);
}

hashCode()native方法底层实现
equals()直接==判断是否相等

equals()方法默认比较对象的地址,使用==等值运算符

equals()方法的默认原则:

  • 自反性:x.equals(x)必须返回true
  • 一致性:只要对象没有被修改,那么多次调用还是返回对应的结果
  • 传递性:x.equals(y)y.equals(z)都返回true,那么x.equals(z)也返回true
  • 对称性:x.equals(y)y.equals(x)结果应该是相等的
  • 任何情况下x.equals(null),都会返回false

hashCode()方法对底层是散列表的对象有提升性能的功能


1、equals和hashCode方法重写

equals()方法默认比较对象的地址,使用的是==运算符

重写equals()方法,就必须重写hashCode()方法,以保证相同的对象返回相同的hash值,不同的对象返回不同的hash值

为什么要重写equals方法?

equals是Object中的方法,其源码如下:
在这里插入图片描述
可以看出,equals默认使用==来比较,而==对于基本数据类型,比较的是值,对于引用数据类型,比较的是内存地址。

根据hashCode的规范,我们重写了equals()就必须重写hashCode()


为什么要重写hashCode()?

hashCode是用于散列数据的快速存取,如利用HashSet/HashMap/Hashtable 类来存储数据时,都会根据存储对象的 hashCode 值来进行判断是否相同。

由于Object的hashCode返回的是对象的hash值,所以即使equals返回TRUE,集合也可能判定两个对象不等,所以必须重写hashCode方法,以保证当equals返回TRUE时,hashCode也返回Ture,这样才能使得集合中存放的对象唯一


两个对象用equals方法比较结果为true,他们的hashcode值相同么?

不一定相同。正常情况下,因为equals()方法比较的就是对象在内存中的值,如果值相同,那么Hashcode值也应该相同。但是如果不重写hashcode方法,就会出现不相等的情况。

2、String实现的equals和hashCode方法

String已经实现了equals和hashCode方法

所以,我们可以直接使用String.equals()来判断两个字符串是否相等
在这里插入图片描述
在这里插入图片描述

三、toString方法

在实际开发中,通常希望对象的toString()方法返回的不仅仅是基本信息,而是一些特有的信息,这时重写Object的toString()方法便可以实现。

toString()以文本的方式来表示一个对象,可以根据实际需要重写toString()来编写打印结果

	@Override
    public String toString() {
        return "Student{" +
                "姓名:'" + name + '\'' +
                ", 成绩:'" + grades + '\'' +
                '}';
    }

在这里插入图片描述


四、clone方法

在这里插入图片描述

  • clone方法用于对象的克隆,一般克隆出的对象是独立的(与原有的对象分开)
  • 深层克隆指的是该对象的成员变量(如果是可变引用)都应该克隆一份,浅克隆指的是成员变量没有被克隆一份

在这里插入图片描述
浅克隆:基本数据类型属性完全重新创建,引用类型属性依然共用的克隆
在这里插入图片描述

深克隆:所有类型属性都完全重新创建
在这里插入图片描述


如何使用克隆?

无论是深克隆还是浅克隆:

  • 克隆的对象要实现Cloneable接口
  • 重写克隆方法,最好修饰成public

clone()Objectprotected方法,他不是public方法,一个类不显示地重写clone(),其它类就不能直接去调用该类实例的 clone() 方法

应该注意的是, clone() ⽅法并不是 Cloneable 接⼝的⽅法,而是 Object 的一个 protected ⽅法。Cloneable 接口只是规定,如果一个类没有实现 Cloneable 接口又调用了 clone() ⽅法,就会抛出CloneNotSupportedException


浅克隆:仅仅克隆了Person对象,而name没有克隆!

public class Person implements Cloneable {

    // 可变的成员变量
    private String name;

    @Override
    public Object clone() throws CloneNotSupportedException {

        return super.clone();
    }
}

深克隆:不仅克隆了Person对象,也克隆了name成员变量

public class Person implements Cloneable {

    // 可变的成员变量
    public String name;

    @Override
    public Object clone() throws CloneNotSupportedException {

        // 克隆Person对象
        Person person = (Person) super.clone();

        // 将可变的成员变量也克隆
        person.name = (String) name.clone();

        // 返回克隆的对象
        return person;
    }
}

标签:Java,克隆,对象,clone,Object,equals,hashCode
来源: https://blog.csdn.net/hyh17808770899/article/details/110956045

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有