Object源码解析

Object:我是所有类的祖先

java.lang.Object 这个类看似其貌不扬,但在Java中的地位就像南方古猿"lucy"在人类中的地位一样——我们所有人的身体里都有她的基因。
当一个类SonClass没有显式的父类时,编译器就会默认Object是它的父类;反之SonClass有显示的父类FatherClass,沿着FatherClass向上追溯,会发现它也是Object类的血脉,所以Object是所有类的祖先。

解析前调

方法属性

方法名关键字返回值
registerNativesprivate static nativevoid
getClasspublic final nativeClass
hashCodepublic nativeint
equalspublicboolean
cloneprotected nativeObject
toStringpublicString
notifypublic final nativevoid
notifyAllpublic final nativevoid
waitpublic final nativevoid

关键字

Object类中的方法中使用的关键字除了native关键字,剩下的都很常见。那我们就着重理解一下native关键字。
Java之所以做到了平台无关性和可移植性,是因为Java不直接和硬件层面进行直接交互。那么Java如何将操作同步到硬件层面呢,那就要用到Java native interface(JNI)了,native关键字标识的java方法为本地方法,jdk底层是有c/c++编写的程序编译后dll文件,java加载dll文件后,可用通过本地方法调用dll中函数。JNI只可调用c++或C吗,答案当然是否定的,具体请参考这篇文章native详解

方法源码解析

registerNatives方法

作用:创建对象时,先加载加载本地Object对应的.dll文件

getClass

作用:返回Object的运行类

hashcode

这个方法返回对象的哈希码值,这个方法与哈希表的性能有关,它的实现方法是通过将对象在内存中所处于的位置转换成数字,这个数字就是hashCode。但是这个内存地址实际上java程序并不关心也是不可知的。这个地址是由JVM维护并保存的,所以实现是native的。通用的约定是:

(1)在同个java环境下,相同的对象必须有同样的哈希码值;但是对于这个具体的整数值(哈希码)在两个相同应用下不需要一定要保持一致(后期会学到如何构建哈希表,一个对象在不同的哈希表下会有不同的哈希值)。

(2)如果两个对象通过equals方法是相等的,则他们的哈希值相同。

(3)反过来,如果两个对象通过equals方法是不相等的,他们的哈希值不一定不同。但是开发者应该明白,对于不相等的两个对象返回不同的哈希值会提高哈希表的性能。

equals

要注意,这里比较的是对象的内存地址

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

clone

注意:这里的clone是浅克隆
何为浅克隆,就是克隆就是复制一个对象的复本.若只需要复制对象的字段值(对于基本数据类型,如:int,long,float等,则复制值;对于复合数据类型仅复制该字段值,如数组变量则复制地址,对于对象变量则复制对象的reference。
举个例子:

 import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ShadowClone implements Cloneable{
    private int cint;
    private long clong;
    private int[] intArray;
    @Override
    public ShadowClone clone(){
        ShadowClone shadowClone = null;
        try {
            shadowClone = (ShadowClone)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return shadowClone;
    }

    public static void main(String[] args) {
        ShadowClone shadowClone1 = new ShadowClone();
        shadowClone1.setCint(2);
        shadowClone1.setClong(3L);
        shadowClone1.setIntArray(new int[]{1,2,3,4});

        ShadowClone shadowClone2 = shadowClone1.clone();
        System.out.println("不改变克隆对象shadowClone1-----------");
        System.out.println("shadowClone1数值     "+shadowClone1.toString());
        System.out.println("shadowClone2数值     "+shadowClone2.toString());
        System.out.println("---------------------结束");


        int[] afterArray =  shadowClone2.getIntArray();
        afterArray[0] = 100;
        shadowClone2.setCint(200);
        shadowClone2.setClong(300L);
        shadowClone2.setIntArray(afterArray);
        System.out.println("改变克隆对象shadowClone1-----------");
        System.out.println("shadowClone1数值     "+shadowClone1.toString());
        System.out.println("shadowClone2数值     "+shadowClone2.toString());
        System.out.println("---------------------结束");
    }
}

结果如下

不改变克隆对象shadowClone1-----------
shadowClone1数值     ShadowClone(cint=2, clong=3, intArray=[1, 2, 3, 4])
shadowClone2数值     ShadowClone(cint=2, clong=3, intArray=[1, 2, 3, 4])
---------------------结束
改变克隆对象shadowClone1-----------
shadowClone1数值     ShadowClone(cint=2, clong=3, intArray=[100, 2, 3, 4])
shadowClone2数值     ShadowClone(cint=200, clong=300, intArray=[100, 2, 3, 4])
---------------------结束

与克隆相关的知识请参考https://blog.csdn.net/bigconvience/article/details/25025561

notify

不能被重写,用于唤醒一个在因等待该对象(调用了wait方法)被处于等待状态(waiting 或 time_wait)的线程,该方法只能同步方法或同步块中调用,即经过 synchronized修饰过。

notifyAll

不能被重写,用于唤醒所有在因等待该对象(调用wait方法)被处于等待状态(waiting或time_waiting)的线程,该方法只能同步方法或同步块中调用,即经过 synchronized修饰过。

wait(long timeOut)

用于在线程调用中,导致当前线程进入等待状态(time_waiting),timeout单位为毫秒,该方法只能同步方法或同步块中调用,超过设置时间后线程重新进入可运行状态

finalize

这个方法用于当对象被回收时调用,这个由JVM支持,Object的finalize方法默认是什么都没有做,如果子类需要在对象被回收时执行一些逻辑处理,则可以重写finalize方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值