写在开头

在上一篇博文中我们提到了Java面向对象的四大特性,其中谈及“抽象”特性时做了一个引子,引出今天的主人公Object,作为所有类的顶级父类,Object被视为是James.Gosling的哲学思考,它高度概括了事务的自然与社会行为。

源码分析

跟进Object类的源码中我们可以看到,类的注释中对它做了一个总结性的注释。

在Object的内部主要提供了这样的11种方法,大家可以在源码中一个个的跟进去看,每个方法上均有详细的英文注释,养成良好的看英文注释习惯,是一个合格程序员的必备基础技能哈。

/**
* 方法一
*/
public final native Class<?> getClass()
/**
* 方法二
*/
public native int hashCode()
/**
*方法三
*/
public boolean equals(Object obj)
/**
* 方法四
*/
protected native Object clone() throws CloneNotSupportedException
/**
* 方法五
*/
public String toString()
/**
* 方法六
*/
public final native void notify()
/**
* 方法七
*/
public final native void notifyAll()
/**
* 方法八
*/
public final native void wait(long timeout) throws InterruptedException
/**
* 方法九
*/
public final void wait(long timeout, int nanos) throws InterruptedException
/**
* 方法十
*/
public final void wait() throws InterruptedException
/**
* 方法十一
*/
protected void finalize() throws Throwable { }

getClass()

getClass()是Java的一个native 方法,用于返回当前运行时对象的 Class 对象,使用了 final 关键字修饰,故不允许子类重写。在源码中我们可以到,该方法的返回是Class类。

Class 类存放类的结构信息,能够通过 Class 对象的方法取出相应信息:类的名字、属性、方法、构造方法、父类、接口和注解等信息。

hashCode()

同样是native 方法,用于返回对象的哈希码,主要使用在哈希表中,比如 JDK 中的HashMap。

equals()

默认比较对象的地址值是否相等,子类可以重写比较规则,如String 类对该方法进行了重写以用于比较字符串的值是否相等。

clone()

native 方法,用于创建并返回当前对象的一份拷贝。

toString()

返回类的名字实例的哈希码的 16 进制的字符串。建议 Object 所有的子类都重写这个方法。

notify()

native 方法,并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)。如果有多个线程在等待只会任意唤醒一个。

notifyAll()

native 方法,并且不能重写。跟 notify 一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程。

wait(long timeout)

native方法,并且不能重写。暂停线程的执行。注意:sleep 方法没有释放锁,而 wait 方法释放了锁 ,timeout 是等待时间。

wait(long timeout, int nanos)

多了 nanos 参数,这个参数表示额外时间(以纳秒为单位,范围是 0-999999)。 所以超时的时间还需要加上 nanos 纳秒。

wait()

让持有对象锁的线程进入等待,不可设置超时时间,没有被唤醒的情况下,会一直等待。

finalize()

实例被垃圾回收器回收的时候触发的操作

高频面试考点总结

虽然在日常的代码开发中,我们很少会直接使用Object类,但考虑到它的独特地位,与此相关的面试考点还是不少的,我们今天总结一下。

1.浅拷贝、深拷贝、引用拷贝的区别?

浅拷贝:基本类型的属性会直接复制一份,而引用类型的属性复制:复制栈中的变量和变量指向堆内存中的对象的指针,不复制堆内存中的对象,也就是说拷贝对象和原对象共用同一个内部对象。

深拷贝:深拷贝会完全复制整个对象,包括这个对象所包含的内部对象。

引用拷贝:简单来说,引用拷贝就是两个不同的引用指向同一个对象。

2.Java中如何实现浅拷贝与深拷贝

其实实现浅拷贝很简单,实现 Cloneable 接口,重写 clone() 方法,在clone()方法中调用父类Object的clone()方法。

public class TestClone {

    public static void main(String[] args) throws CloneNotSupportedException {
Person p1 = new Person(1, "ConstXiong");//创建对象 Person p1
Person p2 = (Person)p1.clone();//克隆对象 p1
p2.setName("其不答");//修改 p2的name属性,p1的name未变
System.out.println(p1);
System.out.println(p2);
} } /**
* person类
*/
class Person implements Cloneable { private int pid; private String name; public Person(int pid, String name) {
this.pid = pid;
this.name = name;
System.out.println("Person constructor call");
} public int getPid() {
return pid;
} public void setPid(int pid) {
this.pid = pid;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
} @Override
public String toString() {
return "Person [pid:"+pid+", name:"+name+"]";
} }

那么如何实现深拷贝呢,这里给出两种方法

方法一:将对象的属性的Class 也实现 Cloneable 接口,在克隆对象时也手动克隆属性。

方法二:结合序列化(JDK java.io.Serializable 接口、JSON格式、XML格式等),完成深拷贝。

3.==和equals的区别是什么?

**区别**
== 是关系运算符,equals() 是方法,结果都返回布尔值
Object 的 == 和 equals() 比较的都是地址,作用相同 **== 作用:**
基本类型,比较值是否相等
引用类型,比较内存地址值是否相等
不能比较没有父子关系的两个对象 **equals()方法的作用:**
JDK 中的类一般已经重写了 equals(),比较的是内容
自定义类如果没有重写 equals(),将调用父类(默认 Object 类)的 equals() 方法,Object 的 equals() 比较使用了 this == obj
可以按照需求逻辑,重写对象的 equals() 方法(重写 equals 方法,一般须重写 hashCode 方法)

4.为什么说重写equals方法也要重写hashCode方法呢?

equals()方法是用来判断两个对象是否相等的重要方法,Object中默认比较地址,但这在实际使用上意义不大,比如两个字符串,我们比较的初衷肯定是他们的字符串内容是否相等,而不是内存地址,典型的就是String内部的重写equals。

hashCode()方法是一个C或C++实现的本地方法,用以获取对象的哈希码值(散列码),通过码值可以确定该对象在哈希表中的索引位置,是通过线程局部状态来实现的随机数值。子类可通过重写该方法去重新设计hash值。

使用hashCode方法可以一定程度上判断两个对象是否相等,因为,若两个对象相等,那么他们所在的索引位置肯定就一样,这时hashCode获取的哈希码自然也就一样,但这个条件反过来就不一定成立了,哈希码相等的两个对象不一定相等,因为存在哈希碰撞

看完这两个方法的特点,我们大概可以明白了,确保两个对象是否真正相等,需要这个两个方法的协作,equals是逻辑上的相等,hashCode是物理上的相等,若我们在重写equals()方法时,不去重写配套的hashCode方法,就会导致两个对象在逻辑上相等,但物理上不等,这会带来很多问题,譬如集合类HashMap的底层实现是数据+链表/红黑树的方式,通过计算hash寻找位置,通过equals判断元素相等,这时候若仅重写equals的话,hash不重写,就会出现逻辑上我们认为相等的两个数,存在了不同的位置上,造成混乱的场面。

作为所有类的顶层父类,没想到Object的魔力如此之大!的更多相关文章

  1. 万万没想到,面试中,连 ClassLoader类加载器 也能问出这么多问题…..

    1.类加载过程 类加载时机 「加载」 将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在内存上创建一个java.lang.Class对象用来封装类在方法区内的数据 ...

  2. Android(java)学习笔记119:继承中父类没有无参构造

    /* 如果父类没有无参构造方法,那么子类的构造方法会出现什么现象呢? 报错. 如何解决呢? A:在父类中加一个无参构造方法 B:通过使用super关键字去显示的调用父类的带参构造方法 C:子类通过th ...

  3. 【JVM虚拟机】(6)---深入理解Class中访问标志、类索引、父类索引、接口索引

    JVM(6)访问标志,类索引 上一篇博客讲[JVM虚拟机](5)---深入理解JVM-Class中常量池 我们知道一个class文件正常可以分为7个部分: 魔数与class文件版本 常量池 访问标志 ...

  4. 在做关于NIO TCP编程小案例时遇到无法监听write的问题,没想到只是我的if语句的位置放错了位置,哎,看了半天没看出来

    在做关于NIO TCP编程小案例时遇到无法监听write的问题,没想到只是我的if语句的位置放错了位置,哎,看了半天没看出来 贴下课堂笔记: 在Java中使用NIO进行网络TCP套接字编程主要以下几个 ...

  5. Android(java)学习笔记60:继承中父类 没有无参构造

    1. 继承中父类 没有无参构造: package com.himi.test1; /* 如果父类没有无参构造方法,那么子类的构造方法会出现什么现象呢? 报错. 如何解决呢? A:在父类中加一个无参构造 ...

  6. mybatis-plus代码生成,实体类不生成父类属性

    一.参考文档: 官方文档其实说的很清楚了,可能有个别地方有点不太清楚. mybatis-plus官方: https://mp.baomidou.com/guide/generator.html 模版引 ...

  7. 杀死众筹的N种方法:没想到山寨大军也参与了

    ​ ​ 众筹作为当下创业者筹集资金,将创意变为现实的最重要手段之一,正面临着越来越多的困难,甚至衍生出杀死众筹的N种方法.甚至这些方法还分为了两类,就众筹本身看,杀死它们的主要方法是:创业者卷钱跑路. ...

  8. 没想到 Google 排名第一的编程语言,为什么会这么火?

    没想到吧,Python 又拿第一了! 在 Google 公布的编程语言流行指数中,Python 依旧是全球范围内最受欢迎的技术语言!   01 为什么 Python 会这么火? 核心还是因为企业需要用 ...

  9. 没想到吧!这个可可爱爱的游戏居然是用 ECharts 实现的!

    摘要:echarts 是一个很强大的图表库,除了我们常见的图表功能,还可以自定义图形,这个功能让我们可以很简单地在画布上绘制一些非常规的图形,基于此,我们来玩一些花哨的:做一个 Flappy Bird ...

  10. JVM-class文件完全解析-类索引,父类索引和索引集合

    类索引,父类索引和接口索引集合 前面介绍了class文件,从头开始的魔数,次版本号,主版本号,常量池入口,常量池,访问标志.那么再接下来的就是用来确定这个类的继承关系的类索引,父类索引和接口索引集合这 ...

随机推荐

  1. dms

          产品解决方案文档与社区免费试用定价云市场合作伙伴支持与服务了解阿里云       备案控制台 首页关系型数据库NoSQL数据库数据仓库数据管理工具向量数据库免费试用 个人     打卡 发 ...

  2. Thinking in Java 4th Edition Source Code

    Thinking in Java 4th Edition Source Code Instructions for downloading, installing and testing the so ...

  3. Regions 题解

    Regions 这里提供一种时间复杂度不那么优秀但十分好写也好理解的做法. 题目大意 给定一颗 \(n\) 个节点的树,每个节点拥有一个颜色,进行若干次询问,每次询问给出两种颜色 \(A,B\),求所 ...

  4. React技术栈支援Vue项目,你需要提前了解的

    写在前面 react整体是函数式的思想,把组件设计成纯组件,状态和逻辑通过参数传入,而vue的思想是响应式的,也就是基于是数据可变的,通过对每一个属性建立Watcher来监听, 当属性变化的时候,响应 ...

  5. VK Cup 2016 - Round 1 (CF639)

    A. Bear and Displayed Friends Div2 的题,不写. B. Bear and Forgotten Tree 3 这种东西怎么评蓝的? Description 给定 \(n ...

  6. 20.3 OpenSSL 对称AES加解密算法

    AES算法是一种对称加密算法,全称为高级加密标准(Advanced Encryption Standard).它是一种分组密码,以128比特为一个分组进行加密,其密钥长度可以是128比特.192比特或 ...

  7. 《最新出炉》系列初窥篇-Python+Playwright自动化测试-24-处理单选和多选按钮-上篇

    1.简介 在工作和生活中,经常会遇到我们需要进行选择的情况,比如勾选我们选择性别,男女两个性别总是不能同时选中的,再比如我们在选择兴趣爱好时,我们可以选择多个自己感兴趣的话题,比如:篮球.足球.电竞等 ...

  8. 飞腾E2000板载以太网适配

    飞腾E2000板载以太网适配 e20005.4.18macbyt8521 1. 设备树移植 2. MACB驱动移植 3. 网络连通性调试 3-1. MACB驱动环回测试 3-2. YT8521 PHY ...

  9. 【外包杯】【报错】微信小程序 “[app.json 文件内容错误]app.json:未找到[“pages”][0]对应 pages/xx/xx.wxml(或其他)文件” 报错 的简单解决方案(已解决)

    问题的解决方案 删除components目录下的uni-link文件夹

  10. git可视化管理工具有哪些?

    在 Git 中,有许多可视化管理工具可供使用.以下是一些常见的 Git 可视化管理工具及其功能的详细介绍. GitHub Desktop: GitHub Desktop 是由 GitHub 官方推出的 ...