深入理解Object类
背景
在Java语言中,我们所编写的所有类都会自动继承自Object类,因此,了解其各个方法的作用是十分有必要的。
源码剖析
package java.lang;
/**
-
@author unascribed
-
@see java.lang.Class
-
@since JDK1.0
*/
public class Object {-
registerNatives这个方法是为了注册native方法。
-
native方法就是本地方法,这些本地方法的实现其实并非是采用Java编写的,而是C/C++,通过将这些C/C++代码编译成本地动态链接库文件,然后JVM将这些本地方法注册、链接到我们的程序中,我们就可以调用这些本地方法了,我们这里不对JNI的细节进行展开,读者有兴趣,可以自行了解JNI的实现原理。
private static native void registerNatives();
static {
registerNatives();
}
-
这个方法的作用,大家都比较熟悉,在运行时获取当前类对象的Class对象,如在HotSpot JVM中,其实一个Java类也是一个对象,它设计了OOP-Klass对象模型,会有一个对应的C++类来定义与描述所有的Java类的信息,我们可以把这里的Class对象看成是JVM中的OOPKlass的一个实例。那么我们通过getClass()方法就可以在运行时获取当前对象的类型信息,这也是Java反射机制的核心内容,关于反射,后面我们会在专门的文章对它进行介绍。
public final native Class<?> getClass();
-
返回当前实例的hashcode。
-
hashcode只是JVM为当前对象生成的一个int数值;
-
hashcode并不一定是对象的内存地址,关于这个结论,请移步这篇文章:Java中的hashcode究竟是不是对象的内存地址
-
不同的对象,hashcode有可能一样,也就是哈希冲突;
-
相反,如果一个对象所有的属性值都相同,对象的hascode也可能不相同
-
如果要重写equals方法,必须同时重写hashcode方法。
public native int hashCode();
-
判断两个对象是否相等
-
默认情况下,是比较两个对象的hashcode的值是否相同,关于hashcode,上面已经提及,这里不再赘述。
public boolean equals(Object obj) {
return (this == obj);
}
-
拷贝一个对象并返回这个对象的引用
-
如果被拷贝的对象的属性里,还包含了其它对象,会不会一并拷贝呢?这里我们暂时不展开来讲,读者可以自己实验一下,涉及到深度克隆及浅克隆的问题,大家可以参考这篇文章:Java中的clone和深度clone。
-
如果被克隆对象的类,没有实现Cloneable接口,会抛出CloneNotSupportedException
protected native Object clone() throws CloneNotSupportedException;
-
返回对象的字符串描述,默认是:类名+@+hashcode的十六进制字符串
-
如果我们在打印该对象时,不想看到这样没有什么实际意义的字符串,我们可以重写toString()方法,通常情况下,我们在记录日志的时候,比如说转化成JSON的格式然后输出对象信息。
public String toString() {
return getClass().getName() + “@” + Integer.toHexString(hashCode());
}
-
持有锁的当前线程唤醒以当前对象作为同步(synchronized)监视器对象的其它等待线程当中的某一个线程
public final native void notify();
-
持有锁的当前线程唤醒以当前对象作为同步(synchronized)监视器对象的其它所有等待线程
public final native void notifyAll();
-
等待持有同步(synchronized)监视器对象的线程释放锁
-
等待时间为timeout毫秒
public final native void wait(long timeout) throws InterruptedException;
-
等待持有同步(synchronized)监视器对象的线程释放锁
-
等待时间为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);
}
-
等待持有同步(synchronized)监视器对象的线程释放锁
-
不设置超时时间,它会一直等待下去
public final void wait() throws InterruptedException {
wait(0);
}
-
这个方法是通过通知垃圾回收器回收当前对象
-
由于在JVM中,处理finalize()所标记对象的垃圾回收的线程优先级非常低,导致了通过finalize()方法调用去通知垃圾回收的不可控性,通常情况下,我们不建议开发者去使用这个方法,我个人觉得,我们最好是忘了这个方法的存在。
protected void finalize() throws Throwable { }
}
-