最新在整體回歸下java基礎(chǔ)薄弱環(huán)節(jié),以下為自己整理筆記,若有理解錯(cuò)誤,請(qǐng)批評(píng)指正,謝謝。

java.lang.Object為java所有類(lèi)的基類(lèi),所以一般的類(lèi)都可用重寫(xiě)或直接使用Object下方法,以下為邏輯結(jié)構(gòu)圖,沒(méi)有畫(huà)類(lèi)圖

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

(注: 以上綠色方法為 非native方法  粉色方法為 native方法)

那么問(wèn)題來(lái)了 :

1、what is a native object? 

  本人理解: native關(guān)鍵字標(biāo)識(shí)的java方法為本地方法,底層是有c/c++編寫(xiě)的程序編譯后dll文件,java加載dll文件后,

        可用通過(guò)本地方法調(diào)用dll中函數(shù),如有疑問(wèn)可用參考JNI使用方式,看參考:http://blog.csdn.net/yangjiali014/article/details/1633017

        以下為Object類(lèi)對(duì)應(yīng)openjdk\jdk\src\share\native\java\lang\Object.c的源碼片段1

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

1 static JNINativeMethod methods[] = {2     {"hashCode",    "()I",                    (void *)&JVM_IHashCode},3     {"wait",        "(J)V",                   (void *)&JVM_MonitorWait},4     {"notify",      "()V",                    (void *)&JVM_MonitorNotify},5     {"notifyAll",   "()V",                    (void *)&JVM_MonitorNotifyAll},6     {"clone",       "()Ljava/lang/Object;",   (void *)&JVM_Clone},7 };

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

  網(wǎng)友見(jiàn)解:http://stackoverflow.com/questions/4568972/what-is-a-native-object

2、Why exist native method in Object Class?

  本人理解:涉及調(diào)用系統(tǒng)及考慮性能,使用c++或c實(shí)現(xiàn)更佳

  網(wǎng)友見(jiàn)解:http://stackoverflow.com/questions/10578764/why-are-hashcode-and-getclass-native-methods

       http://stackoverflow.com/questions/27224577/why-is-object-clone-native-in-java

  

現(xiàn)在按上圖逐個(gè)方法講講理解:

  1、Object():默認(rèn)構(gòu)造函數(shù)

  2、 registerNatives(): 用于注冊(cè) 代碼片段1中的本地方法到j(luò)vm中

  java代碼 片段2

1  private static native void registerNatives();2  static {3      registerNatives();4  }

  對(duì)應(yīng)c++代碼 片段3

1 JNIEXPORT void JNICALL2 Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)3 {4     (*env)->RegisterNatives(env, cls,5                             methods, sizeof(methods)/sizeof(methods[0]));6 }

  3、final getClass():  (不能重寫(xiě)方法)方法說(shuō)明中已經(jīng)提示:Returns:The Class object that represents the runtime class of this object.

   來(lái)個(gè)簡(jiǎn)單例子 片段4

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

 1 package jdk; 2  3 public class ObjectTest { 4  5     public static void main(String[] args) { 6         A a = new B(); 7         System.out.println(a.getClass()); 8     } 9 }10 11 class A {12     static{13         System.out.println("初始化a");14     }15     16 }17 18 class B extends A{19     static{20         System.out.println("初始化b");21     }22 }

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

  輸出結(jié)果:

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

  可以看到getClass返回的為class B 非 A。

   4、hashCode():返回一個(gè)整數(shù)的值依賴于內(nèi)部表示堆上的對(duì)象的指針

    方法說(shuō)明:This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not           required by the Java™ programming language

  一起看下native方法 位于openjdk\hotspot\src\share\vm\prims\jvm.cpp中 JVM_IHashCode的實(shí)現(xiàn) 

1 JVM_ENTRY(jint, JVM_IHashCode(JNIEnv* env, jobject handle))2   JVMWrapper("JVM_IHashCode");3   // as implemented in the classic virtual machine; return 0 if object is NULL4   return handle == NULL ? 0 : ObjectSynchronizer::FastHashCode (THREAD, JNIHandles::resolve_non_null(handle)) ;5 JVM_END

調(diào)用了ObjectSynchronizer::FastHashCode方法,位于openjdk\hotspot\src\share\vm\runtime\synchronizer.cpp中 第530行起

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn) View Code

  該方法一般會(huì)被子類(lèi)重寫(xiě),String方法的hashCode方法代碼 片段5

  計(jì)算方法是 s[0]31^(n-1) + s[1]31^(n-2) + … + s[n-1],其中s[0]表示字符串的第一個(gè)字符,n表示字符串長(zhǎng)度;

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

 1  public int hashCode() { 2         int h = hash; 3         if (h == 0 && value.length > 0) { 4             char val[] = value; 5  6             for (int i = 0; i < value.length; i++) { 7                 h = 31 * h + val[i]; 8             } 9             hash = h;10         }11         return h;12     }

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

  5、equals():返回 2個(gè)對(duì)象的內(nèi)存地址是否相等

  源碼 片段6

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

  該方法一般會(huì)被子類(lèi)重寫(xiě),String方法的equal方法代碼 片段7

   先比較String對(duì)象內(nèi)存地址相同,若相同則返回true,否則判斷String對(duì)象對(duì)應(yīng)字符的內(nèi)容是否相等,若相等則返回true

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

 1 public boolean equals(Object anObject) { 2         if (this == anObject) { 3             return true; 4         } 5         if (anObject instanceof String) { 6             String anotherString = (String)anObject; 7             int n = value.length; 8             if (n == anotherString.value.length) { 9                 char v1[] = value;10                 char v2[] = anotherString.value;11                 int i = 0;12                 while (n-- != 0) {13                     if (v1[i] != v2[i])14                         return false;15                     i++;16                 }17                 return true;18             }19         }20         return false;21     }

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

  6、clone() throws CloneNotSupportedException:返回復(fù)制對(duì)象

    先看下方法的說(shuō)明:Note that all arrays are considered to implement the interface Cloneable and that the return type of the clone method of an array     type T[] is T[] where T is any reference or primitive type

    一起看下native方法 位于openjdk\hotspot\src\share\vm\prims\jvm.cpp中 JVM_Clone的實(shí)現(xiàn)  片段8

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
  JVMWrapper("JVM_Clone");
  Handle obj(THREAD, JNIHandles::resolve_non_null(handle));  const KlassHandle klass (THREAD, obj->klass());
  JvmtiVMObjectAllocEventCollector oam;

#ifdef ASSERT  // Just checking that the cloneable flag is set correct
  if (obj->is_javaArray()) {
    guarantee(klass->is_cloneable(), "all arrays are cloneable");
  } else {
    guarantee(obj->is_instance(), "should be instanceOop");    bool cloneable = klass->is_subtype_of(SystemDictionary::Cloneable_klass());
    guarantee(cloneable == klass->is_cloneable(), "incorrect cloneable flag");
  }#endif

  // Check if class of obj supports the Cloneable interface.  // All arrays are considered to be cloneable (See JLS 20.1.5)
  if (!klass->is_cloneable()) {
    ResourceMark rm(THREAD);
    THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name());
  }  // Make shallow object copy
  const int size = obj->size();
  oop new_obj = NULL;  if (obj->is_javaArray()) {    const int length = ((arrayOop)obj())->length();
    new_obj = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL);
  } else {
    new_obj = CollectedHeap::obj_allocate(klass, size, CHECK_NULL);
  }  // 4839641 (4840070): We must do an oop-atomic copy, because if another thread  // is modifying a reference field in the clonee, a non-oop-atomic copy might  // be suspended in the middle of copying the pointer and end up with parts  // of two different pointers in the field.  Subsequent dereferences will crash.  // 4846409: an oop-copy of objects with long or double fields or arrays of same  // won't copy the longs/doubles atomically in 32-bit vm's, so we copy jlongs instead  // of oops.  We know objects are aligned on a minimum of an jlong boundary.  // The same is true of StubRoutines::object_copy and the various oop_copy  // variants, and of the code generated by the inline_native_clone intrinsic.
  assert(MinObjAlignmentInBytes >= BytesPerLong, "objects misaligned");
  Copy::conjoint_jlongs_atomic((jlong*)obj(), (jlong*)new_obj,
                               (size_t)align_object_size(size) / HeapWordsPerLong);  // Clear the header
  new_obj->init_mark();  // Store check (mark entire object and let gc sort it out)
  BarrierSet* bs = Universe::heap()->barrier_set();
  assert(bs->has_write_region_opt(), "Barrier set does not have write_region");
  bs->write_region(MemRegion((HeapWord*)new_obj, size));  // Caution: this involves a java upcall, so the clone should be  // "gc-robust" by this stage.
  if (klass->has_finalizer()) {
    assert(obj->is_instance(), "should be instanceOop");
    new_obj = instanceKlass::register_finalizer(instanceOop(new_obj), CHECK_NULL);
  }  return JNIHandles::make_local(env, oop(new_obj));
JVM_END

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

  隱含意思:數(shù)組類(lèi)型默認(rèn)可以直接克隆,而其他對(duì)象實(shí)現(xiàn)clone需要先實(shí)現(xiàn)Cloneable接口,否則拋出CloneNotSupportedException異常

  問(wèn)題1:對(duì)象的創(chuàng)建有多中方式,類(lèi)似 new 、getInstance、clone等 clone有什么好處?

  問(wèn)題2:對(duì)象調(diào)用clone方法生成的對(duì)象 和 原對(duì)象是否還有什么關(guān)聯(lián)關(guān)系?

  問(wèn)題3 : 對(duì)象clone存在 “淺復(fù)制”、“深復(fù)制”概念,怎么區(qū)分?

  帶著這3個(gè)問(wèn)題,理解Object clone方法:

    1、一般native方法比java中非native方法執(zhí)行效率高 ,看示例  片段9

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

 1 package jdk; 2  3 import java.util.Calendar; 4 import java.util.Date; 5  6 public class ObjectCloneTest1 { 7  8     static final int N = 100000; 9 10     public static void main(String[] args) {11 12         final Date date = new Date();13 14         {15 16             final long startTime = System.currentTimeMillis();17             for (int i = 0; i < N; i++) {18                 Date date2 = (Date) date.clone();19             }20 21             final long endTime = System.currentTimeMillis();22 23             System.out.println("clone:" + (endTime - startTime) + "ms");24         }25 26         {27             final long startTime = System.currentTimeMillis();28             for (int i = 0; i < N; i++) {29                 final Calendar cal = Calendar.getInstance();30                 cal.setTime(date);31                 final Date date2 = cal.getTime();32             }33 34             final long endTime = System.currentTimeMillis();35             System.out.println("Calender.setTime:" + (endTime - startTime) + "ms");36 37         }38 39     }40 41 }

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

  2、clone生成的新對(duì)象與原對(duì)象的關(guān)系,需要區(qū)別2個(gè)對(duì)象建是否存在相同的引用或?qū)?yīng)的內(nèi)存地址是否存在共用情況,若存在則 該次clone為 “淺復(fù)制”,否則為“深復(fù)制”, 而且Object的clone方法是屬于 “淺復(fù)制”,看示例  片段10

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn) View Code

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

  "深復(fù)制"時(shí),需要將共同關(guān)聯(lián)的引用也復(fù)制完全看示例  片段11

 

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn) View Code

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

  7、toString():a string representation of the object.

    方法說(shuō)明:

    The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@',     and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:

 getClass().getName() + '@' + Integer.toHexString(hashCode())

   默認(rèn)返回對(duì)象的名稱及引用地址,但一般被子類(lèi)重寫(xiě)用于說(shuō)明子類(lèi)相關(guān)屬性值描述

  8、final notify() : 不能被重寫(xiě),用于喚醒一個(gè)在因等待該對(duì)象(調(diào)用了wait方法)被處于等待狀態(tài)(waiting 或 time_wait)的線程,該方法只能同步方法或同步塊中調(diào)用

    方法說(shuō)明:Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be     awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait     methods. 

  9、final notifyAll():不能被重寫(xiě),用于喚醒所有在因等待該對(duì)象(調(diào)用wait方法)被處于等待狀態(tài)(waiting或time_waiting)的線程,該方法只能同步方法或同步塊中調(diào)用

    方法說(shuō)明:Wakes up all threads that are waiting on this object's monitor. A thread waits on an object's monitor by calling one of the wait methods. 

  10、final wait(long timeout):不能被重寫(xiě),用于在線程調(diào)用中,導(dǎo)致當(dāng)前線程進(jìn)入等待狀態(tài)(time_waiting),timeout單位為毫秒,該方法只能同步方法或同步塊中調(diào)用,超過(guò)設(shè)置時(shí)間后線程重新進(jìn)入可運(yùn)行狀態(tài)

    方法說(shuō)明:Note that the wait method, as it places the current thread into the wait set for this object, unlocks only this object; any other objects on     which the current thread may be synchronized remain locked while the thread waits. 

  11、final wait(long timeout, int nanos):不能被重寫(xiě),在jdk1.8中看當(dāng),沒(méi)有什么特殊作用類(lèi)似 wait(long timeout)方法,片段12

if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
            timeout++;
 }

  12、final void wait()::不能被重寫(xiě),用于在線程調(diào)用中,導(dǎo)致當(dāng)前線程進(jìn)入阻塞狀態(tài)(waiting),該方法只能同步方法或同步塊中調(diào)用,不會(huì)自動(dòng),片段13

   方法說(shuō)明:The specified amount of real time has elapsed, more or less. If timeout is zero, however, then real time is not taken into consideration and the thread simply waits until notified.

1     public final void wait() throws InterruptedException {2         wait(0);3     }

   8,9,10,11,12幾個(gè)方法一般配套使用,先了解一下JAVA 線程執(zhí)行模型

  平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

  詳細(xì)看示例 片段14

1 synchronized (obj) {2          while (<condition does not hold>)3              obj.wait(timeout);4          ... // Perform action appropriate to condition5 }

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn) View Code

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

  執(zhí)行wait過(guò)程中堆棧信息:

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

  再來(lái)個(gè)生產(chǎn)消費(fèi)者的示例 片段15

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn) View Code

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開(kāi)發(fā),動(dòng)畫(huà)培訓(xùn)

 

 13、finalize():Object的protected方法,子類(lèi)可以覆蓋該方法以實(shí)現(xiàn)資源清理工作,GC在回收對(duì)象之前調(diào)用該方法

    方法說(shuō)明:Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. A     subclass overrides the finalize method to dispose of system resources or to perform other cleanup. 

,該方法只能同步方法或同步塊中調(diào)用