Java从JDK源码角度对Object进行实例分析
Object是所有类的父类,也就是说java中所有的类都是直接或者间接继承自Object类。比如你随便创建一个classA,虽然没有明说,但默认是extendsObject的。
后面的三个点"..."表示可以接受若干不确定数量的参数。老的写法是Objectargs[]这样,但新版本的java中推荐使用...来表示。例如
publicvoidgetSomething(String...strings)(){}
object是java中所有类的父类,也就是说所有的类,不管是自己创建的类还是系统中的类都继承自object类,也就是说所有的类在任何场合都可以代替object类,根据里氏替换原则,子类在任何场合都可以代替其父类,而父类却不一定能代替其子类,java中常说的万物皆对象说的其实就是这个道理!object类体现了oop思想中的多态,继承,封装,抽象四大特性!
object类是所有类的基类,不是数据类型。这个你可以查询jdk文档了解,所有类都继承自Object。
Object...objects这种参数定义是在不确定方法参数的情况下的一种多态表现形式。即这个方法可以传递多个参数,这个参数的个数是不确定的。这样你在方法体中需要相应的做些处理。因为Object是基类,所以使用Object...objects这样的参数形式,允许一切继承自Object的对象作为参数。这种方法在实际中应该还是比较少用的。
Object[]obj这样的形式,就是一个Object数组构成的参数形式。说明这个方法的参数是固定的,是一个Object数组,至于这个数组中存储的元素,可以是继承自Object的所有类的对象。
这些基础东西建议你多看几遍"Thinkinjava"
Java的Object是所有其他类的父类,从继承的层次来看它就是最顶层根,所以它也是唯一一个没有父类的类。它包含了对象常用的一些方法,比如getClass、hashCode、equals、clone、toString、notify、wait等常用方法。所以其他类继承了Object后就可以不用重复实现这些方法。这些方法大多数是native方法,下面具体分析。
主要的代码如下:
publicclassObject{
	privatestaticnativevoidregisterNatives();
	static{
		registerNatives();
	}
	publicfinalnativeClass>getClass();
	publicnativeinthashCode();
	publicBooleanequals(Objectobj){
		return(this==obj);
	}
	protectednativeObjectclone()throwsCloneNotSupportedException;
	publicStringtoString(){
		returngetClass().getName()+"@"+Integer.toHexString(hashCode());
	}
	publicfinalnativevoidnotify();
	publicfinalnativevoidnotifyAll();
	publicfinalnativevoidwait(longtimeout)throwsInterruptedException;
	publicfinalvoidwait(longtimeout,intnanos)throwsInterruptedException{
		if(timeout<0){
			thrownewIllegalArgumentException("timeoutvalueisnegative");
		}
		if(nanos<0||nanos>999999){
			thrownewIllegalArgumentException("nanosecondtimeoutvalueoutofrange");
		}
		if(nanos>0){
			timeout++;
		}
		wait(timeout);
	}
	publicfinalvoidwait()throwsInterruptedException{
		wait(0);
	}
	protectedvoidfinalize()throwsThrowable{
	}
}
registerNatives方法
由于registerNatives方法被static块修饰,所以在加载Object类时就会执行该方法,对应的本地方法为Java_java_lang_Object_registerNatives,如下,
JNIEXPORTvoidJNICALL
Java_java_lang_Object_registerNatives(JNIEnv*env,jclasscls)
{
	(*env)->RegisterNatives(env,cls,
	methods,sizeof(methods)/sizeof(methods[0]));
}
可以看到它间接调用了JNINativeInterface_结构体的方法,简单可以看成是这样:它干的事大概就是将Java层的方法名和本地函数对应起来,方便执行引擎在执行字节码时根据这些对应关系表来调用C/C++函数,如下面,将这些方法进行注册,执行引擎执行到hashCode方法时就可以通过关系表来查找到JVM的JVM_IHashCode函数,其中()I还可以得知Java层上的类型应该转为int类型。这个映射其实就可以看成将字符串映射到函数指针。
staticJNINativeMethodmethods[]={
{"hashCode","()I",(void*)&JVM_IHashCode},
{"wait","(J)V",(void*)&JVM_MonitorWait},
{"notify","()V",(void*)&JVM_MonitorNotify},
{"notifyAll","()V",(void*)&JVM_MonitorNotifyAll},
{"clone","()Ljava/lang/Object;",(void*)&JVM_Clone},
};
getClass方法
getClass方法也是个本地方法,对应的本地方法为Java_java_lang_Object_getClass,如下:
JNIEXPORTjclassJNICALL
Java_java_lang_Object_getClass(JNIEnv*env,jobjectthis)
{
if(this==NULL){
JNU_ThrowNullPointerException(env,NULL);
return0;
}else{
return(*env)->GetObjectClass(env,this);
}
}
所以这里主要就是看GetObjectClass函数了,Java层的Class在C++层与之对应的则是klassOop,所以关于类的元数据和方法信息可以通过它获得。
JNI_ENTRY(jclass,jni_GetObjectClass(JNIEnv*env,jobjectobj))
JNIWrapper("GetObjectClass");
DTRACE_PROBE2(hotspot_jni,GetObjectClass__entry,env,obj);
klassOopk=JNIHandles::resolve_non_null(obj)->klass();
jclassret=
(jclass)JNIHandles::make_local(env,Klass::cast(k)->java_mirror());
DTRACE_PROBE1(hotspot_jni,GetObjectClass__return,ret);
returnret;
JNI_END
hashCode方法
由前面registerNatives方法将几个本地方法注册可知,hashCode方法对应的函数为JVM_IHashCode,即
JVM_ENTRY(jint,JVM_IHashCode(JNIEnv*env,jobjecthandle))
JVMWrapper("JVM_IHashCode");
//asimplementedintheclassicvirtualmachine;return0ifobjectisNULL
returnhandle==NULL?0:ObjectSynchronizer::FastHashCode(THREAD,JNIHandles::resolve_non_null(handle));
JVM_END
对于hashcode生成的逻辑由synchronizer.cpp的get_next_hash函数决定,实现比较复杂,根据hashcode的不同值有不同的生成策略,最后使用一个hash掩码处理。
staticinlineintptr_tget_next_hash(Thread*Self,oopobj){
	intptr_tvalue=0;
	if(hashCode==0){
		value=os::random();
	}else
	if(hashCode==1){
		intptr_taddrBits=intptr_t(obj)>>3;
		value=addrBits^(addrBits>>5)^GVars.stwRandom;
	}else
	if(hashCode==2){
		value=1;
		//forsensitivitytesting
	}else
	if(hashCode==3){
		value=++GVars.hcSequence;
	}else
	if(hashCode==4){
		value=intptr_t(obj);
	}else{
		unsignedt=Self->_hashStateX;
		t^=(t<<11);
		Self->_hashStateX=Self->_hashStateY;
		Self->_hashStateY=Self->_hashStateZ;
		Self->_hashStateZ=Self->_hashStateW;
		unsignedv=Self->_hashStateW;
		v=(v^(v>>19))^(t^(t>>8));
		Self->_hashStateW=v;
		value=v;
	}
	value&=markOopDesc::hash_mask;
	if(value==0)value=0xBAD;
	assert(value!=markOopDesc::no_hash,"invariant");
	TEVENT(hashCode:GENERATE);
	returnvalue;
}
equals方法
这是一个非本地方法,判断逻辑也十分简单,直接==比较。
clone方法
由本地方法表知道clone方法对应的本地函数为JVM_Clone,clone方法主要实现对象的克隆功能,根据该对象生成一个相同的新对象(我们常见的类的对象的属性如果是原始类型则会克隆值,但如果是对象则会克隆对象的地址)。Java的类要实现克隆则需要实现Cloneable接口,if(!klass->is_cloneable())这里会校验是否有实现该接口。然后判断是否是数组分两种情况分配内存空间,新对象为new_obj,接着对new_obj进行copy及C++层数据结构的设置。最后再转成jobject类型方便转成Java层的Object类型。
JVM_ENTRY(jobject,JVM_Clone(JNIEnv*env,jobjecthandle))
JVMWrapper("JVM_Clone");
Handleobj(THREAD,JNIHandles::resolve_non_null(handle));
constKlassHandleklass(THREAD,obj->klass());
JvmtiVMObjectAllocEventCollectoroam;
if(!klass->is_cloneable()){
	ResourceMarkrm(THREAD);
	THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(),klass->external_name());
}
constintsize=obj->size();
oopnew_obj=NULL;
if(obj->is_javaArray()){
	constintlength=((arrayOop)obj())->length();
	new_obj=CollectedHeap::array_allocate(klass,size,length,CHECK_NULL);
}else{
	new_obj=CollectedHeap::obj_allocate(klass,size,CHECK_NULL);
}
Copy::conjoint_jlongs_atomic((jlong*)obj(),(jlong*)new_obj,
(size_t)align_object_size(size)/HeapWordsPerlong);
new_obj->init_mark();
BarrierSet*bs=Universe::heap()->barrier_set();
assert(bs->has_write_region_opt(),"Barriersetdoesnothavewrite_region");
bs->write_region(MemRegion((HeapWord*)new_obj,size));
if(klass->has_finalizer()){
	assert(obj->is_instance(),"shouldbeinstanceOop");
	new_obj=instanceKlass::register_finalizer(instanceOop(new_obj),CHECK_NULL);
}
returnJNIHandles::make_local(env,oop(new_obj));
JVM_END
toString方法
逻辑是获取class名称加上@再加上十六进制的hashCode。
notify方法
此方法用来唤醒线程,final修饰说明不可重写。与之对应的本地方法为JVM_MonitorNotify,ObjectSynchronizer::notify最终会调用ObjectMonitor::notify(TRAPS),这个过程是ObjectSynchronizer会尝试当前线程获取freeObjectMonitor对象,不成功则尝试从全局中获取。
JVM_ENTRY(void,JVM_MonitorNotify(JNIEnv*env,jobjecthandle))
JVMWrapper("JVM_MonitorNotify");
Handleobj(THREAD,JNIHandles::resolve_non_null(handle));
assert(obj->is_instance()||obj->is_array(),"JVM_MonitorNotifymustapplytoanobject");
ObjectSynchronizer::notify(obj,CHECK);
JVM_END
ObjectMonitor对象包含一个_WaitSet队列对象,此对象保存着所有处于wait状态的线程,用ObjectWaiter对象表示。notify要做的事是先获取_WaitSet队列锁,再取出_WaitSet队列中第一个ObjectWaiter对象,再根据不同策略处理该对象,比如把它加入到_EntryList队列中。然后再释放_WaitSet队列锁。它并没有释放synchronized对应的锁,所以锁只能等到synchronized同步块结束时才释放。
voidObjectMonitor::notify(TRAPS){
	CHECK_OWNER();
	if(_WaitSet==NULL){
		TEVENT(Empty-Notify);
		return;
	}
	DTRACE_MONITOR_PROBE(notify,this,object(),THREAD);
	intPolicy=Knob_MoveNotifyee;
	Thread::SpinAcquire(&_WaitSetLock,"WaitSet-notify");
	ObjectWaiter*iterator=DequeueWaiter();
	if(iterator!=NULL){
		TEVENT(Notify1-Transfer);
		guarantee(iterator->TState==ObjectWaiter::TS_WAIT,"invariant");
		guarantee(iterator->_notified==0,"invariant");
		if(Policy!=4){
			iterator->TState=ObjectWaiter::TS_ENTER;
		}
		iterator->_notified=1;
		ObjectWaiter*List=_EntryList;
		if(List!=NULL){
			assert(List->_prev==NULL,"invariant");
			assert(List->TState==ObjectWaiter::TS_ENTER,"invariant");
			assert(List!=iterator,"invariant");
		}
		if(Policy==0){
			//prependtoEntryList
			if(List==NULL){
				iterator->_next=iterator->_prev=NULL;
				_EntryList=iterator;
			}else{
				List->_prev=iterator;
				iterator->_next=List;
				iterator->_prev=NULL;
				_EntryList=iterator;
			}
		}else
		if(Policy==1){
			//appendtoEntryList
			if(List==NULL){
				iterator->_next=iterator->_prev=NULL;
				_EntryList=iterator;
			}else{
				//CONSIDER:findingthetailcurrentlyrequiresalinear-timewalkof
				//theEntryList.Wecanmaketailaccessconstant-timebyconvertingto
				//aCDLLinsteadofusingourcurrentDLL.
				ObjectWaiter*Tail;
				for(Tail=List;Tail->_next!=NULL;Tail=Tail->_next);
				assert(Tail!=NULL&&Tail->_next==NULL,"invariant");
				Tail->_next=iterator;
				iterator->_prev=Tail;
				iterator->_next=NULL;
			}
		}else
		if(Policy==2){
			//prependtocxq
			//prependtocxq
			if(List==NULL){
				iterator->_next=iterator->_prev=NULL;
				_EntryList=iterator;
			}else{
				iterator->TState=ObjectWaiter::TS_CXQ;
				for(;;){
					ObjectWaiter*Front=_cxq;
					iterator->_next=Front;
					if(Atomic::cmpxchg_ptr(iterator,&_cxq,Front)==Front){
						break;
					}
				}
			}
		}else
		if(Policy==3){
			//appendtocxq
			iterator->TState=ObjectWaiter::TS_CXQ;
			for(;;){
				ObjectWaiter*Tail;
				Tail=_cxq;
				if(Tail==NULL){
					iterator->_next=NULL;
					if(Atomic::cmpxchg_ptr(iterator,&_cxq,NULL)==NULL){
						break;
					}
				}else{
					while(Tail->_next!=NULL)Tail=Tail->_next;
					Tail->_next=iterator;
					iterator->_prev=Tail;
					iterator->_next=NULL;
					break;
				}
			}
		}else{
			ParkEvent*ev=iterator->_event;
			iterator->TState=ObjectWaiter::TS_RUN;
			OrderAccess::fence();
			ev->unpark();
		}
		if(Policy<4){
			iterator->wait_reenter_begin(this);
		}
		//_WaitSetLockprotectsthewaitqueue,nottheEntryList.Wecould
		//movetheadd-to-EntryListoperation,above,outsidethecriticalsection
		//protectedby_WaitSetLock.Inpracticethat'snotuseful.Withthe
		//exceptionofwait()timeoutsandinterruptsthemonitorowner
		//istheonlythreadthatgrabs_WaitSetLock.There'salmostnocontention
		//on_WaitSetLocksoit'snotprofitabletoreducethelengthofthe
		//criticalsection.
	}
	Thread::SpinRelease(&_WaitSetLock);
	if(iterator!=NULL&&ObjectMonitor::_sync_Notifications!=NULL){
		ObjectMonitor::_sync_Notifications->inc();
	}
}
notifyAll方法
与notify方法类似,只是在取_WaitSet队列时不是取第一个而是取所有。
wait方法
wait方法是让线程等待,它对应的本地方法是JVM_MonitorWait,间接调用了ObjectSynchronizer::wait,与notify对应,它也是对应调用ObjectMonitor对象的wait方法。该方法较长,这里不贴出来了,大概就是创建一个ObjectWaiter对象,接着获取_WaitSet队列锁将ObjectWaiter对象添加到该队列中,再释放队列锁。另外,它还会释放synchronized对应的锁,所以锁没有等到synchronized同步块结束时才释放。
JVM_ENTRY(void,JVM_MonitorWait(JNIEnv*env,jobjecthandle,jlongms))
JVMWrapper("JVM_MonitorWait");
Handleobj(THREAD,JNIHandles::resolve_non_null(handle));
assert(obj->is_instance()||obj->is_array(),"JVM_MonitorWaitmustapplytoanobject");
JavaThreadInObjectWaitStatejtiows(thread,ms!=0);
if(JvmtiExport::should_post_monitor_wait()){
JvmtiExport::post_monitor_wait((JavaThread*)THREAD,(oop)obj(),ms);
}
ObjectSynchronizer::wait(obj,ms,CHECK);
JVM_END
finalize方法
这个方法用于当对象被回收时调用,这个由JVM支持,Object的finalize方法默认是什么都没有做,如果子类需要在对象被回收时执行一些逻辑处理,则可以重写finalize方法
总结
以上就是本文关于Java从JDK源码角度对Object进行实例分析的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!