JDK源码解析系列之object

JDK源码之Object类

1 private static native void registerNatives();

Java中,用native关键字修饰的函数表明该方法的实现并不是在Java中去完成,而是由C++去完成,并被编译成了.dll,由Java去调用。方法的具体实现体在dll文件中,对于像Window,Linux,Mac不同平台,其具体实现有所不同,主要作用是将C++的方法映射到Java中,实现方法命名的解藕。

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

clone()方法又是一个被声明为native的方法,因此,我们知道了clone()方法并不是Java的原生方法,具体的实现是有C++完成的,其目的是创建并返回此对象的一个副本,在List集合中,会经常用到,比如说,list集合扩容。

3 public final native Class<?> getClass();

在Java中,每一个类都有相同的特征和行为的实例的抽象并进行描述,例如,都具有类的名称,由类加载器去加载,
都有包,父类的属性和方法,Java中有专门定义的一个类,class,可以通过getClass方法,就可以获取类的所有特征,在Java的反射技术中,大量使用这个方法。

4 public boolean equals(Object obj);

在此方法中,返回的结果是this == obj ,可知,Object的原生的equals()方法调用的正是==,与==具有相同的含义。在object类中,此标尺即为==。当然,这个标尺不是固定的,其他类中可以按照实际的需要对此标尺含义进行重定义。如String类中则是依据字符串内容是否相等来重定义了此标尺含义。如此可以增加类的功能型和实际编码的灵活性。当然了,如果自定义的类没有重写equals()方法来重新定义此标尺,那么默认的将是其父equals(),直到object基类。

5 public native int hashCode();

hashCode()方法返回一个整形数值,表示该对象的哈希码值。在Java应用程序程序执行期间,对于同一对象多次调用hashCode()方法时,其返回的哈希码是相同的,前提是将对象进行equals比较时所用的标尺信息未做修改。在Java应用程序的一次执行到另外一次执行,同一对象的hashCode()返回的哈希码无须保持一致。如果两个对象相等(依据:调用equals()方法),那么这两个对象调用hashCode()返回的哈希码也必须相等;反之,两个对象调用hasCode()返回的哈希码相等,这两个对象不一定相等。以集合类中,以Set为例,当新加一个对象时,需要判断现有集合中是否已经存在与此对象相等的对象,如果没有hashCode()方法,需要将Set进行一次遍历,并逐一用equals()方法判断两个对象是否相等,此种算法时间复杂度为o(n)。通过借助于hasCode方法,先计算出即将新加入对象的哈希码,然后根据哈希算法计算出此对象的位置,直接判断此位置上是否已有对象即可。

6 public String toString();

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

7 public final native void notify();

唤醒所有在这个对象的监视器上等待的线程,线程通过调用一个对象来监视对象的监视器。在当前线程放弃对该对象的锁定之前,唤醒线程将无法继续进行。被唤醒的线程将以通常的方式与可能在此对象上积极竞争同步的任何其他线程竞争;例如,被唤醒的线程在成为下一个锁定此对象的线程时没有可靠的特权或缺点。

8 public final native void notifyAll();

同 notify ,其所在线程不会立即释放所持有的锁,直到其所在同步代码块中的代码执行完毕,此时释放锁,因此,如果其同步代码块后还有代码,其执行则依赖于JVM的线程调度

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

wait(...)方法调用后当前线程将立即阻塞,且适当其所持有的同步代码块中的锁,直到被唤醒或超时或打断后且重新获取到锁后才能继续执行;

10 protected void finalize() throws Throwable { }

Object中定义finalize方法表明Java中每一个对象都将具有finalize这种行为,其具体调用时机在:JVM准备对此对形象所占用的内存空间进行垃圾回收前,将被调用。由此可以看出,此方法并不是由我们主动去调用的(虽然可以主动去调用,此时与其他自定义方法无异)

11 为什么所有的类的父类都是Object类,而有些源码并没有继承Object

在编译源代码时,当遇到没有父类的类时,编译器会将其指定一个默认的父类(一般为Object),而虚拟机在处理到这个类时,由于这个类已经有一个默认的父类了,因此,VM仍然会按着常规的方法来处理每一个类。对于这种情况,从编译后的二进制角度来看,所有的类都会有一个父类。

相关推荐