Object类源码理解

35 篇文章 0 订阅
34 篇文章 0 订阅


前言

本文章帮助大家对Object类的理解。


一、概述

Object意为对象。顾名思义,此类是java(面向对象)最基础的类,它是所有类的父类,即其它所有类都直接或间接或默认继承它,子类可以使用它的所有方法。其方法有:构造、获取类、哈希码、判等、克隆、转字符串、通知、等待、完成(不推荐)。

二、源码理解

package java.lang;

使用Object类时,此包自动引入。

Object类

public class Object { /*...*/ }

Object方法

Object

public Object() {}

构造函数,不做处理。

getClass

public final native Class<?> getClass();

final方法,无法重写。返回此对象的“运行时的类”,返回值也是一个对象,用它可以获取Object对象所属类的相关信息,如类名、成员属性等。java的反射机制与此方法密切相关,需要利用此机制的,可以使用此方法。参考Class类。

注意:使用Class的泛型类型接收返回值时,其类型会被擦除,即返回原对象的“类”。

为本地方法,源码参考:

  • Object.c的Java_java_lang_Object_getClass(JNIEnv *env, jobject this)(入口);
  • jni.cpp的JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj))Klass* k = JNIHandles::resolve_non_null(obj)->klass()jclass ret = (jclass) JNIHandles::make_local(env, k->java_mirror())
  • jniHandles.cpp的jobject JNIHandles::make_local(JNIEnv* env, oop obj)jobject JNIHandleBlock::allocate_handle(oop obj)(分配堆空间)。

equals

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

判断此对象与obj是否相同(引用相同)。它应当具有自反性、对称性、传递性、幂等性等。

hashCode

public native int hashCode();

返回此对象的哈希码,若为空对象,返回0。一个对象的哈希码通常不改变(同一程序的不同执行,哈希码不一致)。若两个对象相同(即调用equals方法结果相同),则其哈希码相等;反之不然。通常可以用来帮助查找。

为本地方法,源码参考:

  • Object.c的static JNINativeMethod methods[]{"hashCode", "()I", (void *)&JVM_IHashCode}(入口);
  • jvm.cpp的JVM_ENTRY(jint, JVM_IHashCode(JNIEnv* env, jobject handle))
  • synchronizer.cpp的intptr_t ObjectSynchronizer::FastHashCode(Thread * Self, oop obj)static inline intptr_t get_next_hash(Thread * Self, oop obj)(计算)。

clone

protected native Object clone() throws CloneNotSupportedException;

被保护方法仅此包及其子类可见。返回此对象的“克隆”,这里为浅拷贝,及“克隆对象”的成员引用与原对象成员引用相同。若要子类的“克隆”为深拷贝,则需要重写此方法,将所有成员引用赋为原对象成员拷贝的引用,除非成员为原始类型或immutable(不可变)对象。

注意:规定需要使用此方法的子类,需要实现Cloneable接口,否则将抛CloneNotSupportedException异常。当然此类本身没有实现Cloneable接口,直接调用此方法也将抛同样的异常。参考Cloneable接口。

为本地方法,源码参考:

  • Object.c的static JNINativeMethod methods[]{"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone}(入口);
  • jvm.cpp的JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))if (!klass->is_cloneable())(判断是否可克隆)、THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name())(抛CloneNotSupportedException异常)、new_obj_oop = CollectedHeap::obj_allocate(klass, size, CHECK_NULL)HeapAccess<>::clone(obj(), new_obj_oop, size)(复制内容,即浅拷贝)、new_obj = Handle(THREAD, new_obj_oop)(中间指针分配堆空间)、return JNIHandles::make_local(env, new_obj())(分配堆空间);
  • classFileParser.cpp的if (SystemDictionary::Cloneable_klass_loaded())Cloneable接口已加载)、if (ik->is_subtype_of(SystemDictionary::Cloneable_klass()))(实现了Cloneable接口)、ik->set_is_cloneable()(设置可克隆)。

toString

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

将此对象“转换”为字符串,返回 类名 + “@” + 哈希码的十六进制。由于返回字符串用来以“文本”方式表示此对象,建议在子类中重写此方法以提供更好的表示对象的方法。

wait

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

final方法,无法重写。使当前线程睡眠,直至被唤醒后才能往下执行,可以是被“通知”(参考notifynotifyAll方法)、中断(参考Thread类的interrupt方法)、timeoutMillis时间到了。若timeoutMillis为0,则不使用此方式唤醒线程;若小于0,将抛出IllegalArgumentException异常。

注意:它阻塞当前线程,并释放此对象的锁,故需要使用synchronized同步锁关键字,否则java为使多线程执行顺序不混乱,将抛出IllegalMonitorStateException非法监视器状态异常。若线程在等待前或等待时被中断,当还原此对象的锁定状态后,将抛出InterruptedException异常。

为本地方法,源码参考:

  • Object.c的static JNINativeMethod methods[]{"wait", "(J)V", (void *)&JVM_MonitorWait}}(入口);
  • jvm.cpp的JVM_ENTRY(void, JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms))JvmtiExport::post_monitor_wait((JavaThread *)THREAD, (oop)obj(), ms)ObjectSynchronizer::wait(obj, ms, CHECK)
  • synchronizer.cpp的int ObjectSynchronizer::wait(Handle obj, jlong millis, TRAPS)if (millis < 0) { /*...*/ THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative"); }(抛IllegalArgumentException异常)、ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj(), inflate_cause_wait)(获取监视器);
  • objectMonitor.cpp的void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS)if (interruptible && Thread::is_interrupted(Self, true) && !HAS_PENDING_EXCEPTION)THROW(vmSymbols::java_lang_InterruptedException())(抛InterruptedException异常)、Self->_ParkEvent->park()Self->_ParkEvent->park(millis)
  • os_posix.cpp的os::PlatformEvent::park()pthread_cond_wait(_cond, _mutex)(线程等待_cond信号)、os::PlatformEvent::park(jlong millis)pthread_cond_timedwait(_cond, _mutex, &abst)(线程等待_cond信号(带abst超时));或os_solaris.cpp的os::PlatformEvent::park()os::Solaris::cond_wait(_cond, _mutex)(线程等待_cond信号)、os::PlatformEvent::park(jlong millis)os::Solaris::cond_timedwait(_cond, _mutex, &absTime)(线程等待_cond信号(带absTime超时));或os_windows.cpp的os::PlatformEvent::park()::WaitForSingleObject(_ParkHandle, INFINITE)(线程等待_ParkHandle信号)、os::PlatformEvent::park(jlong Millis)::WaitForSingleObject(_ParkHandle, prd)(线程等待_ParkHandle信号(带prd超时))。
public final void wait() throws InterruptedException { wait(0L); }

final方法,无法重写。使当前线程睡眠,直至被唤醒后才能往下执行,可以是被“通知”、中断。同wait(long timeoutMillis),但它不能被计时唤醒。

public final void wait(long timeoutMillis, int nanos) throws InterruptedException { /*...*/ }

final方法,无法重写。使当前线程睡眠,直至被唤醒后才能往下执行,可以是被“通知”、中断、时间到了。同wait(long timeoutMillis),但nanos大于0时,会为timeoutMillis加1。

notify

public final native void notify();

final方法,无法重写。随机唤醒一个在此对象监控器上wait(等待)的线程,即当另一线程对此对象调用wait方法后,线程将睡眠,直至被唤醒后(并释放此对象的锁)才能往下执行。适用于生产消费者模式等。

注意:配合wait方法使用,并且需要使用synchronized同步锁关键字,否则java为使多线程执行顺序不混乱,将抛出 IllegalMonitorStateException非法监视器状态异常。参考wait方法。

为本地方法,源码参考:

  • Object.c的static JNINativeMethod methods[]{"notify", "()V", (void *)&JVM_MonitorNotify}(入口);
  • jvm.cpp的JVM_ENTRY(void, JVM_MonitorNotify(JNIEnv* env, jobject handle))
  • synchronizer.cpp的void ObjectSynchronizer::notify(Handle obj, TRAPS)
  • objectMonitor.cpp的ObjectMonitor::notify(TRAPS)INotify(THREAD)
  • os_posix.cpp的os::PlatformEvent::unpark()pthread_cond_signal(_cond)(线程发送_cond信号);或os_solaris.cpp的os::PlatformEvent::unpark()os::Solaris::cond_signal(_cond)(线程发送_cond信号);或os_windows.cpp的os::PlatformEvent::unpark()::SetEvent(_ParkHandle)(线程发送_ParkHandle信号)。

notifyAll

public final native void notifyAll();

final方法,无法重写。唤醒所有在此对象监控器上wait(等待)的线程,即当其它线程对此对象调用wait方法后,线程将睡眠,直至被唤醒后(并释放此对象的锁)并竞争获得对象锁才能往下执行。适用于生产消费者模式等。类似notify方法。

注意:配合wait方法使用,并且需要使用synchronized同步锁关键字,否则java为使多线程执行顺序不混乱,将抛出 IllegalMonitorStateException非法监视器状态异常。参考wait方法。

为本地方法,源码参考:

  • Object.c的static JNINativeMethod methods[]{"notifyAll", "()V", (void *)&JVM_MonitorNotifyAll}(入口);
  • jvm.cpp的JVM_ENTRY(void, JVM_MonitorNotifyAll(JNIEnv* env, jobject handle))
  • synchronizer.cpp的ObjectSynchronizer::notifyall(Handle obj, TRAPS)
  • objectMonitor.cpp的ObjectMonitor::notify(TRAPS)INotify(THREAD)(等待集非空时被循环调用);
  • os_posix.cpp的os::PlatformEvent::unpark()pthread_cond_signal(_cond)(线程发送_cond信号);或os_solaris.cpp的os::PlatformEvent::unpark()os::Solaris::cond_signal(_cond)(线程发送_cond信号);或os_windows.cpp的os::PlatformEvent::unpark()::SetEvent(_ParkHandle)(线程发送_ParkHandle信号)。

finalize

protected void finalize() throws Throwable { }

不推荐(弃用)。被保护方法仅此包及其子类可见。空实现,一般用来重写,重写它时jvm会将它注册到终结器中,当对象gc前将进行调用,并且可以通过在此方法的finally语句中调用super.finalize父类完成。此方法通常用来释放一些资源,特别是“非堆”资源。

注意:由于此方法被jvm调用的时机不确定,或可能长时间不被调用,可能造成时序不能把控、内存泄漏、内存溢出等问题,不推荐使用。建议使用其它方法代替它的功能,如自动关闭、清理器等。


总结

新人源码理解,望大家多多指点。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值