JDK1.8源码学习-Object

目录

一、方法简介

1.一个本地方法,主要作用是将本地方法注册到虚拟机中。

private static native void registerNatives();
static {
registerNatives();
}

2.获取类的字节码对象

public final native Class<?> getClass();

3.返回当前对象的hash值

 public native int hashCode();

4.比较党当前对象的引用是否和要比较的对象的引用指向同一对象

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

5.克隆对象,浅拷贝

protected native Object clone() throws CloneNotSupportedException;

6.返回当前对象的一个字符串表示形式

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

7.唤醒一个正在等待该对象的线程,如果有多个线程等待,则只能唤醒其中一个

public final native void notify();

8.唤醒所有正在等待这个对象的线程

public final native void notifyAll();

9.阻塞当前线程,等timeout毫秒后会自动唤醒当前线程,当timeout为0时,表示不会自动唤醒线程

public final native void wait(long timeout) throws InterruptedException;

10.阻塞当前线程,等timeout毫秒后会自动唤醒当前线程,nanos为纳秒

    public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
} if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
} if (nanos > 0) {
timeout++;
} wait(timeout);
}

11.阻塞当前线程

    public final void wait() throws InterruptedException {
wait(0);
}

12.当垃圾回收器确定该对象在任何地方没有被引用时,会调用此方法进行垃圾回收

protected void finalize() throws Throwable { }

二、方法详解

1.equals方法

在面试中经常会问道equals()方法和==运算的区别,==运算符用于比较基本类型的值是否相同而equals用于比较两个对象是否相等,在Object中equals与==是等价的,比较的是两个对象的引用,所以自定义对象的时候需要重写equals方法。在Java规范中,对equals方法的使用必须遵循以下几个原则:    

  • 自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
  • 对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
  • 传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
  • 一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改
  • 对于任何非空引用值 x,x.equals(null) 都应返回 false

  需要注意的是重写equals必须重写hashCode,且

X.equals(Y)==true,则X.hashCode()==Y.hashCode();

X.hashCode()==Y.hashCode(),则X.equals(Y)不一定为true,也可能为false;

具体原因可查看hashMap等集合源码。

 2. getClass方法 

1.一个类的实例对象可以有很多,但是它的字节对象只有一个。

2.一个对象可以被强转为其他对象但是其字节码不变。

public class App {
public static void main(String[] args) { Class clazz1 = new Person().getClass();
Class clazz2 = new Person().getClass();
Class clazz3 = Person.class; System.out.println(clazz1 == clazz2);//true
System.out.println(clazz1 == clazz3);//true System.out.println(Object.class == (Object)(new Person()).getClass());//false
System.out.println(Person.class == (Object)(new Person()).getClass());//true }
} class Person{ }

3.clone方法

浅拷贝与深拷贝的区别:

  浅拷贝:如果在一个对象的内部还有一个引用类型的变量,那么在拷贝对象的时候,clone方法新产生的对象只是拷贝了一个该基本类型的引用。

  深拷贝:如果在一个对象内部含有一个引用类型的变量,那么就会将该引用类型的变量指向的对象复制一份,然后引用该新对象。

  

4.toString方法

该方法返回一个能代表该对象的字符串,该字符串由类名以及该对象的十六进制的哈希值拼成。通常情况下,其子类需要覆写该方法。

5.finalize方法

垃圾回收器在认为该对象是垃圾对象的时候会调用该方法,子类可以通过重写该方法来达到资源释放的目的。

在方法调用过程中出现的异常会被忽略且方法调用会被终止。

任何该对象的方法只会被调用一次。

总结

  本地方法7个:

private static native void registerNatives()

public final native Class<?> getClass()

    public native int hashCode()

    protected native Object clone()

public final void notify()

public final native void notifyAll()

public final native void wait(long timeout)

       非本地方法5个:

   public boolean equals(Object obj)

   public String toString()

     public final void wait(long timeout,int nanos)

     public final void wait()

     protected void finalize()

思考点:notify、notifyAll、wait这些和多线程有关的方法为什么定义在Object类中?

1.在java的内置锁机制中,每个对象都可以成为锁,也就是说每个对象都是可以去调用这些方法的,而Object是所有类的父类,所以要把这些方法放到Object中。

2.一个线程可以拥有多个对象锁,上面这些方法跟对象锁之间是有一个绑定关系的,比如用对象锁aObject调用的wait()方法,那么只能通过aObject.notify()或者aObject.notifyAll()来唤醒这个线程,这样JVM很容易就知道该从哪个对象锁的等待池中去唤醒线程,假如用Thread.wait()、Thread.notify()、Thread.notifyAll()来调用,虚拟机则无法判断要操作的对象锁是哪个。

JDK1.8源码学习-Object的更多相关文章

  1. JDK1.8源码学习-String

    JDK1.8源码学习-String 目录 一.String简介 String类是Java中最常用的类之一,所有字符串的字面量都是String类的实例,字符串是常量,在定义之后不能被改变. 二.定义 p ...

  2. JDK1.8源码学习-LinkedList

    JDK1.8源码学习-LinkedList 目录 一.LinkedList简介 LinkedList是一个继承于AbstractSequentialList的双向链表,是可以在任意位置进行插入和移除操 ...

  3. JDK1.8源码学习-ArrayList

    JDK1.8源码学习-ArrayList 目录 一.ArrayList简介 为了弥补普通数组无法自动扩容的不足,Java提供了集合类,其中ArrayList对数组进行了封装,使其可以自动的扩容或缩小长 ...

  4. JDK1.8源码学习-HashMap

    JDK1.8源码学习-HashMap 目录 一.HashMap简介 HashMap 主要用来存放键值对,它是基于哈希表的Map接口实现的,是常用的Java集合之一. 我们都知道在JDK1.8 之前 的 ...

  5. Java JDK1.8源码学习之路 1 Object

    写在最前 对于一个合格的后端程序员来说,现行的流行框架早已经能胜任基本的企业开发,Springboot 任何的框架都把重复的工作更佳简单/优化的解决掉,但是完全陷入在这样的温水里面, 好比温水煮青蛙, ...

  6. jdk1.8源码学习笔记

    前言: 前一段时间开始学习了一些基本的数据结构和算法,算是弥补了这方面的知识短板,但是仅仅是对一些算法的了解,目前工作当中也并没有应用到这些,因此希望通过结合实际例子来学习,巩固之前学到的内容,思前想 ...

  7. Java JDK1.8源码学习之路 2 String

    写在最前 String 作为我们最常使用的一个Java类,注意,它是一个引用类型,不是基本类型,并且是一个不可变对象,一旦定义 不再改变 经常会定义一段代码: String temp = " ...

  8. JDK1.8源码学习-String-hashCode方法为什么选择数字31作为乘子

    1. 背景 某天,我在写代码的时候,无意中点开了 String hashCode 方法.然后大致看了一下 hashCode 的实现,发现并不是很复杂.但是我从源码中发现了一个奇怪的数字,也就是本文的主 ...

  9. 源码学习-Object类

    1.Object类是Java所有类的超类 2.查看Object的属性和方法,发现Object类没有属性,只有13个方法,其中7个本地方法. 3.接下来看具体的方法 3.1 Object() 默认的构造 ...

随机推荐

  1. Mybatis——Mapper代理

    mapper的代理对象生成位于org.apache.ibatis.binding.MapperProxyFactory的newInstance方法,使用jdk的动态代理,代理的InvocationHa ...

  2. Huffuman树--------找最值学会用sort和cmp

    问题描述 Huffman树在编码中有着广泛的应用.在这里,我们只关心Huffman树的构造过程. 给出一列数{pi}={p0, p1, …, pn-1},用这列数构造Huffman树的过程如下: 1. ...

  3. Springboot(一)springboot简介与入门程序

    一.springboot简介: 对spring框架盛行了多年的java方向开发人员来说,每个人java开发已经把spring框架当做开发中不可或缺的一部分. 之前传统的模式都是以application ...

  4. [转载]android网络通信解析

    原文地址:android网络通信解析作者:clunyes 网络编程的目的就是直接戒间接地通过网络协议不其他计算机进行通讯. 网络编程中有两个主要的问题, 一个是如何准确的定位网络上一台戒多台指主机: ...

  5. logrotate nginx日志切割

    1.安装 centos: yum -y install logrotate ubuntu: apt-get install -y logrotate 2. 配置文件 /etc/logrotate.co ...

  6. 我是如何从零开始自学转行IT并进入世界500强实现薪资翻倍?

    本部分内容对应视频链接. 熟悉我的朋友应该知道,我本科及硕士期间所学的专业都是机械相关,毕业两年之后才从零开始自学转行成为一名程序员.当时我写了一篇文章,介绍我的转行经历,很多小伙伴因为我的这篇文章, ...

  7. Calibre LVS BOX 详细用法

    https://www.cnblogs.com/yeungchie/ LVS BOX的使用对于后端的团队协作起到非常便利的作用. 通过在lvs rules file添加BOX的相关语句可以达到这个目的 ...

  8. 牛客挑战赛 39 牛牛与序列 隔板法 容斥 dp

    LINK:牛牛与序列 (牛客div1的E题怎么这么水... 还没D难. 定义一个序列合法 当且仅当存在一个位置i满足 $a_i>a_,a_j<a_$且对于所有的位置i,$1 \leq a_ ...

  9. 【python接口自动化】- logging日志模块

    前言:我们之前运行代码时都是将日志直接输出到控制台,而实际项目中常常需要把日志存储到文件,便于查阅,如运行时间.描述信息以及错误或者异常发生时候的特定上下文信息. logging模块介绍 ​ Pyth ...

  10. .net core MongoDB 初试

    是这样的,我们有一个场景,另一个服务器是写到MongoDB里面,我们的MVC页面要展示,需要分页展示 自己写了一个DAL public class MongoConnect { public stri ...