JDK1.8源码阅读(一)Java.lang.Object

本文深入解析Java.lang包,探讨Object类的重要性和其提供的关键方法,包括构造器、getClass、hashCode、equals、clone、toString、线程同步方法及finalize。揭示了Java面向对象的基础和核心行为。

Java.lang

  java.lang包下的所有类在使用时无需手动导入,系统会在程序编译时自动导入。

1.Object:

  Object类是Java中其他所有类的基类,没有Object类Java面向对象无从谈起。作为其他所有类的基类,Object具有哪些属性和行为,是Java语言设计背后的思维体现。

类构造器

  类构造器是创造java对象的途径之一,通过new关键字调用构造器完成对象实例化,还能通过构造器对对象进行相应的初始化。一个类必须有一个构造器存在,如果没有显示声明,那么系统会默认创造一个无参构造器,在jdk源码中我们看不到构造器,系统会自动添加一个无参构造器。我们可以通过Object obj = new Object();构造一个Object对象。

Object类结构图

1.private static native void registerNatives();

   static { registerNatives(); }

   registerNatives方法由native关键字修饰,java中native关键字修饰的函数表明该方法的实现并不是在java中完成的,而是由C/C++,并编译成了.dll,由java调用,方法的具体实现在.dll文件中。registerNatives()其主要作用是将C/C++中的方法映射到Java中的native方法,实现方法命名的解耦。

2.public final native Class<?> getClass();

  getClass也是一个被native声明的方法,作用是返回此Object对象的类对象/运行时类对象Class<?>。效果与Object.class相同。

类对象:在java中,类是对具有一组相同特征行为的实例的抽象并进行描述,对象则是此类所描述的特征或行为的具体实例。作为概念层次的类,其本身也具有某些共同的特征,如都具有类名称、由类加载器去加载,都有包,具有父类,属性,方法等。于是,java就专门定义了一个类Class,去描述其他类所具有的这些特性。因此从此角度看,类本身也是属于Class类的对象,为与其他类区分,在此称为“类对象”。

3.public native int hashCode();

hashCode()也是native方法。返回一个整形数值。表示该对象的哈希码值。

hashCode()具有如下约定:

  1).在java应用程序执行期间,对于一个对象多次调用hashCode方法时,其返回的哈希码值是相同的,前提是将对象进行equals比较时所用的标尺信息未修改。在java应用程序的一次执行到另外一次执行,同一个对象的hashCode()返回的哈希码无须相同。

  2).如果两个对象equals相等,那么这两个对象的hashCode()返回的哈希码值也必须相等。

  3).如果两个对象的哈希码值不相等,那么这两个对象也不相等。

hashCode()方法的主要作用是增强哈希表的性能。如果没有hashCode(),在集合类中,以Set为例,每新增一个对象时,都需要遍历一次set,调用equals方法判断两对象是否相等。此算法时间复杂度为0(n),而通过hashCode方法,先计算出即将添加对象的哈希码值,根据哈希算法计算出此对象的位置,判断该位置是否存在对象即可。(Set底层使用的是Map原理)

在此需要纠正一个理解上的误区:对象的hashCode()返回的不是对象所在的物理内存地址。甚至也不一定是对象的逻辑地址,hashCode()相同的两个对象,不一定相等,换言之,不相等的两个对象,hashCode()返回的哈希码可能相同。

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

==与equals在经常使用,==用于基础类型比较,表示变量值完全相同。

equals()判断两个对象是否完全相等。如果定义一个对象没有重写equals方法,那么比较对象就是调用object的equals方法,等同于==,那么为什么String类型不能使用==来进行比较呢?是因为String重写了equals方法:

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
}

 String 是引用类型,比较时不能比较引用是否相等,重点是字符串的内容是否相等。所以 String 类定义两个对象相等的标准是字符串内容都相同

5.protected native Object clone() throws CloneNotSupportedException;

clone()方法也是被native声明的方法,其作用是创建返回此对象的副本。clone()的正确调用是需要实现Cloneable接口,如果没有实现Cloneable接口,子类直接调用Object类的clone()方法,则会抛出CloneNotSupportedException异常。Cloneable接口仅是一个表示接口,它本身不包含任何方法,用来指示Object.clone()可以合法的被子类所调用。使用clone方法的优点是速度快,而且灵活。速度快是因为clone方法最终会调用Object.clone()方法,这是一个native方法,本质是内存块复制,所以在速度上比使用new创建对象要快。灵活是因为可以在运行时动态的获取对象的类型以及状态,从而创建一个对象。但是clone创建对象的缺点也很明显:实现深拷贝较为困难,需要整个类继承的所有类以及所有的属性都很好的实现clone方法。另外就是需要处理CloneNotSupportedException异常。

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

toString()返回一个String对象,

getClass()返回对象的类对象,getClassName()以String形式返回类对象的名称(含包名)。Integer.toHexString(hashCode())则是以对象的哈希码为实参,以16进制无符号整数形式返回此哈希码的字符串表示形式。

如上例中的u1的哈希码是638,则对应的16进制为27e,调用toString()方法返回的结果为:com.corn.objectsummary.User@27e。

因此:toString()是由对象的类型和其哈希码唯一确定,同一类型但不相等的两个对象分别调用toString()方法返回的结果可能相同。

7.public final native void notify();

唤醒在此对象监视器上等待的单个线程

8.public final native void notifyAll();

唤醒在此对象监视器上等待的所有线程

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

10.public final void wait(long timeout, int nanos) throws InterruptedException 

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

调用此方法所在的当前线程等待,直到在其他线程上调用此方法的主调(某一对象)的notify()/notifyAll()方法。

12.protected void finalize() throws Throwable { }

finalize方法主要与Java垃圾回收机制有关。他是一个空方法,在Object类中定义这个方法是表明java所有对象都将具有finalize这种行为,其调用时机在JVM准备对此对象形成所占用的内存空间进行垃圾回收前。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值