天天看點

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制

2016-10-19 

說說&和&&的差別

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
初級問題,但是還是加入了筆記,因為得滿分不容易。

&和&&都可以用作邏輯與的運算(兩邊是boolean類型),全真則真,一假則假。

&&還具有短路的功能,即第一個表達式為false,則不再計算第二個表達式。例如,

if(str != null&& !str.equals(““))

當str為null時,後面的表達式不會執行,不會出現NullPointerException,如果将&&改為&,則會抛出NullPointerException異常。

&還可以用作位運算符,當&操作符兩邊的表達式不是boolean類型時,&表示按位與操作,我們通常使用0x0f來與一個整數進行&運算,來擷取該整數的最低4個bit位,例如,0x31 & 0x0f的結果為0x01。備注:這道題先說兩者的共同點,再說出&&和&的特殊之處,并列舉一些經典的例子來表明自己了解透徹深入。      

解析

final有什麼用法?它的記憶體層面的語義你了解麼?

前半部分是老生常談的。大家都知道:final 用于聲明類的屬性,方法和類本身,分别表示屬性本身不可變,方法不可覆寫,類不可繼承。且内部類要通路局部變量,局部變量必須定義成final類型,因為常量的作用範圍變大,内部類才可以通路到。

本題問的主要是後者,涉及到了Java記憶體模型和重排序的含義。更加詳細參考下面文章

JVM學習(3)——總結Java記憶體模型

深入了解Java記憶體模型(六)——final

簡單說就是構造器内對一個final域的寫,與随後把這個被構造對象的引用指派給一個引用變量,這兩個操作之間不能重排序,即如果final域在構造器内初始化,那麼一定是先初始化完畢,才能使用對象。不會逃逸。

初次讀一個包含final域的對象的引用,與随後初次讀這個final域,這兩個操作之間不能重排序,讀final域的重排序規則可以確定:在讀一個對象的final域之前,一定會先讀包含這個final域的對象的引用。

在構造器内對一個final引用的對象的成員域的寫入,與随後在構造函數外把這個被構造對象的引用指派給一個引用變量,這兩個操作之間不能重排序。

下面代碼的輸出結果是?

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
不能執行,編譯有錯, final修飾的變量是常量,使用之前必須進行初始化,可以顯示初始化,也可以通過構造方法或者初始化塊進行初始化,如果不初始化編譯會報錯。      

請說說finalize方法的用法,為什麼一些書上不推薦程式員手動調用它?

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
finalize是Object類的一個保護方法

protected void finalize() throws Throwable { } 

當垃圾回收器确定不存在對該對象的更多引用時,對象的垃圾回收器自動調用此方法,程式員可以覆寫此方法提供垃圾收集時的其他資源回收,例如關閉檔案等。而記得《Java程式設計思想》說:“如果需要進行清理,最好是編寫你自己的清理方法,但不要用finalize”,其實你寫了或者你用了“自己的清理方法”,隻是沒感覺到。比如I/O的close方法就是,現在的問題是為什麼釋放資源的代碼不直接寫在finalize裡面。因為手動調用它,JVM不保證此方法總被及時調用或者根本不保證會被調用,這都不能保證,要你何用。而且它的調用對性能影響很大。具體來說就是:

java的GC隻負責記憶體的清理,所有其它資源的清理必須由程式員手工完成。要不然會引起資源洩露,有可能導緻程式崩潰。 而finalize()是Object的protected方法,那麼子類理論上可以覆寫該方法,且GC會在回收對象之前調用對象的該方法。但是finalize()與C++中的析構函數不是對應的。C++中的析構函數調用的時機是确定的(對象離開作用域或delete掉),但Java中的finalize的調用具有不确定性,不建議用finalize方法完成“非記憶體資源”的清理工作。Java語言規範并不保證finalize方法會被及時地執行、而且根本不會保證它們會被執行,finalize方法可能會帶來性能問題。因為JVM通常在單獨的低優先級線程中完成finalize的執行。

在Java虛拟機的垃圾回收器看來,堆區中的每個對象都可能處于以下三個狀态之一。

可觸及狀态:當一個對象(假定為Sample對象)被建立後,隻要程式中還有引用變量引用它,那麼它就始終處于可觸及狀态。
可複活狀态:當程式不再有任何引用變量引用Sample對象時,它就進入可複活狀态。在這個狀态中,垃圾回收器會準備釋放它占用的記憶體,在釋放之前,會調用它及其他處于可複活狀态的對象的finalize()方法,這些finalize()方法有可能使Sample 對象重新轉到可觸及狀态。
不可觸及狀态:當Java虛拟機執行完所有可複活對象的finalize()方法後,假如這些方法都沒有使Sample對象轉到可觸及狀态,那麼Sample對象就進入不可觸及狀态。隻有當對象處于不可觸及狀态時,垃圾回收器才會真正回收它占用的記憶體。
一個對象開始是可觸及态的,當對象到GC Root沒有任何引用連接配接相連。那麼就證明這個對象目前是不可用的,這時這個對象就被判死緩了(從可觸及到可複活),但是想要真正的對這個對象判死刑,這個對象還至少經曆兩次判決。第一次是判斷是否有必要對這個對象執行finalize()方法,如果目前對象沒有覆寫finalize()方法,或finalize()方法已經被調用過了(最多調用一次),那麼目前對象就不會調用finalize()方法了,即對象成功的逃脫了一審判決。如果對象有必要執行finalize()方法,那麼這個對象會被放入一個叫做F-Queue的隊列中,這也就意味着在一審中這個對象已經被判死刑了,但是還沒執行。而在JVM中,會有一個叫做Finalizer的低優先級線程去觸發可複活對象的finalize()方法,finalize()方法是對象逃脫死刑的最後一次機會,如果在finalize()的過程中成功的與GC Root相連,則對象成功的逃脫死刑(進入可觸及态)。否則對象就會被第二次标記(進入不可觸及态),被第二次标記的對象就會被送上刑場槍斃。又想起一個問題,即使在程式裡,不顯式指定對象指向null,JVM也會找機會解決它。

分析說明:finalize方法至多由GC執行一次, 盡管finalize()方法是保證在回收記憶體空間之前執行的,但是對具體的執行時間和執行順序是沒有任何保證的。多個執行個體之間的finalize()執行順序是不能提前預知的,甚至有可能它們是并行執行的。程式不應該預先假設執行個體執行finalize()的方法,也不應該使用finalize()方法來回收資源。      

可以參考文章

JVM學習(4)——全面總結Java的GC算法和回收機制

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
這個題很重要,糾正我一個誤區:Java隻有值傳遞。java中沒有顯式的指針。沒有類似c和c++的那種位址,引用傳遞。對于java值傳遞,形參str指向了實參str指向的對象good字元串,但是change方法内部,形參str指向重新開辟一個空間存儲的test ok,change執行完畢,實參str的指向對象并沒有被修改。故不起作用。而ch是數組,值傳遞的是對象的引用,值發生了改變,列印good and gbc
重要:别混淆:Java傳參方式隻有一種:按值傳遞

Java一直是隻有值傳遞。不幸的是,制定規則的人決定把Java裡的指針的東西叫做引用,是以初學者總是被搞暈。其實這些引用也是通過值傳遞的。即Java中傳遞任何東西都是傳值。如果傳入方法的是基本類型的東西,你就得到此基本類型的一份拷貝。如果是傳遞引用,就得到引用的拷貝。 一般來說,對于基本類型的傳遞,我們很容易了解,而對于對象,總讓人感覺是按引用傳遞。      

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制

1true 

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制

請看下面這個簡單的例子,其中"c.getDeclaredMethods"的作用是?

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
取得類的所有方法的對象。
public Method[] getDeclaredMethods() //傳回類或接口聲明的所有方法,包括public, protected, default (package) 通路和private方法的Method對象,但不包括繼承的方法。當然也包括它所實作接口的方法。

public Method[] getMethods() // 傳回某個類的所有public方法,包括其繼承類的公用方法,當然也包括它所實作接口的方法

Java反射

可以了解為在運作時期擷取對象類型資訊的操作,傳統的程式設計方法要求程式員在編譯階段決定使用的類型,但是在反射的幫助下,程式設計人員可以動态擷取這些資訊,進而編寫更加具有可移植性的代碼。嚴格地說,反射并非java語言的特性,因為任何一種語言都可以實作反射機制,但是如果程式設計語言本身支援反射,那麼反射的實作就會友善很多。 

獲得類型類;Java中一切都是對象,我們一般所使用的對象都直接或間接繼承自Object類。Object類中包含一個方法名叫getClass(final修飾),利用這個方法就可以獲得一個執行個體的類型類。類型類指的是代表一個類型的類,因為一切皆是對象,類型也不例外,在Java使用類型類來表示一個類型。所有的類型類都是Class類的執行個體。例:

A a = new A();

if(a.getClass()==A.class)  

  System.out.println("equal");

else

  System.out.println("unequal");

結果就是列印出 “equal”。對象a是A的一個執行個體,if中使用a.getClass()傳回的結果正是A的類型類。在Java中表示一個特定類型的類型類可以用“類型.class”的方式獲得,因為a.getClass()獲得是A的類型類,也就是A.class,是以上面的代碼執行的結果就是列印出 “equal”,特别注意的是,類型類是一一對應的,父類的類型類和子類的類型類是不同的,是以,假設A是B的子類,那麼如下的代碼将得到 “unequal”的輸出:

A a = new A();

if(a.getClass()==B.class)  

  System.out.println("equal");

else

  System.out.println("unequal");

是以,如果你知道一個執行個體,那麼你可以通過執行個體的“getClass()”方法獲得該對象的類型類,如果你知道一個類型,那麼你可以使用“.class”的方法獲得該類型的類型類。

小結:

Class cl=A.class;  // JVM将使用類A的類裝載器, 将類A裝入記憶體(前提是:類A還沒有裝入記憶體),不對類A做類的初始化工作.傳回類A的Class的對象(類型類,一切都是對象)。

Class cl=對象引用.getClass(); // 傳回引用運作時真正所指的對象(因為:子對象的引用可能會賦給父對象的引用變量)所屬的類的Class的對象。 

Class.forName(); //  傳回的是一個類,   .newInstance() 後才建立一個對象,  Class.forName()的作用是要求JVM查找并加載指定的類

 

獲得類型的資訊

在獲得類型類之後可以調用其中的一些方法獲得類型的資訊,主要的方法有:

getName():String:獲得該類型的全稱名稱。

getSuperClass():Class:獲得該類型的直接父類,如果該類型沒有直接父類,那麼傳回null。

getInterfaces():Class[]:獲得該類型實作的所有接口。

isArray():boolean:判斷該類型是否是數組。

isEnum():boolean:判斷該類型是否是枚舉類型。

isInterface():boolean:判斷該類型是否是接口。

isPrimitive():boolean:判斷該類型是否是基本類型,即是否是int,boolean,double等等。

isAssignableFrom(Class cls):boolean:判斷這個類型是否是類型cls的父(祖先)類或父(祖先)接口。

getComponentType():Class:如果該類型是一個數組,那麼傳回該數組的元件類型。      

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Object的getClass作用是傳回運作時的類的名字,但是SuperTest和Date的getClass都沒有被重寫,他們都是調用Object的getClass,而Object的getClass作用是傳回運作時的類的名字。那麼此時這個運作時的類就是目前類,是以傳回的是test.SuperTest,與Date類無關,要傳回Date類的名字需要寫super.getClass().getSuperclass()。還有别忘了包名!      

以下聲明合法的是?

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
java的通路權限有public、protected、private和default的,default不能修飾變量。native是方法修飾符。定義navtive方法時,并不提供實作體,因為其實作體是用非Java語言在外面實作的。native可以和任何修飾符連用,abstract除外。因為native暗示這個方法有實作體,而abstract卻顯式指明了這個方法沒有實作體。      

JAVA語言的下面幾種數組複制方法中,哪個效率最高?

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
從c++/c的角度來看,數組的複制就是對某塊記憶體的複制,直接和記憶體打交道的是最快的,for循環的話,for是最慢的。雖然很靈活。

看System.arraycopy()源碼:

public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

可以看到是native方法:native關鍵字說明其修飾的方法是一個原生态方法,方法對應的實作不是在目前檔案,而是在用其他語言(如C和C++)實作的檔案中。 可以将native方法比作Java程式同C程式的接口。效率最高。

C項寫法就錯了,copyOf不是System的方法,而是Arrays的靜态方法,下面是源碼,可以看到本質上是調用的本地方法arraycopy,那麼其效率必然是比不上 arraycopy的。

       public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {

           @SuppressWarnings("unchecked")

           T[] copy = ((Object)newType == (Object)Object[].class)

               ? (T[]) new Object[newLength]

               : (T[]) Array.newInstance(newType.getComponentType(), newLength);

           System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));

           return copy;

       }

clone的話,屬于Object類的保護本地方法,傳回的是Object,需要強制轉換。 一般用clone效率是比較差的。

protected native Object clone() throws CloneNotSupportedException;          

Java的入口方法:main為什麼必須是靜态的?它可以被重載麼?

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
main()方法一定是靜态的。如果main()允許是非靜态的,那麼在調用main方法時,JVM就得執行個體化它的類。在執行個體化時,得調用類的構造函數。必然要找該類的入口,而入口是非靜态的方法,沖突了。main()方法必須聲明為靜态的,這樣JVM才可以調用main()方法而無需執行個體化它的類。如果從main()方法去掉“static”這個聲明,雖然編譯依然可以成功,但在運作時會導緻程式失敗。

對于後個問題,當然可以重載main()方法。一個Java類可以有任意數量的main()方法。為了運作java類,類的main()方法應該有例如“public static void main(String[] args)”的聲明。如果對此聲明做任何修改,編譯也是可以成功的。但是,運作不了Java程式。會得到運作時錯誤,因為找不到main方法。      

能否聲明main方法為private或protected,或者不用通路修飾符?

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
不能,main方法必須public。不能定義main()方法為private和protected,也不能不用通路修飾符。這是為了能讓JVM通路main()方法。如果你不定義main()方法為public,雖然編譯也會成功,但你會得到運作時錯誤,因為找不到main方法。      

能否在Java中覆寫main方法?

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
不能,因為main方法是靜态方法,而在Java中靜态方法在編譯時會結合在一起,是以你在Java中不能覆寫靜态方法。      

能否在Java中同步main方法?

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
main方法可以在Java中同步,synchronized修飾符允許用于main方法的聲明中,這樣就可以在Java中同步main方法了。      

說說Object類java.lang.Object,它裡面都有什麼方法?

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
java.lang包在使用的時候無需顯示導入,編譯時由編譯器自動導入。提供java編成語言的程式設計的基礎類.Object類是類層次結構的根,Java中所有的類從根本上都繼承自這個類。Object類是Java中唯一沒有父類的類。其他所有的類,包括标準容器類,比如數組,都繼承Object類中的方法

補充;Object類源代碼分析

package java.lang;   
public class Object {   
   /* 一個私有靜态的native方法,具體是用C(C++)在DLL Dynamic Link Library 中實作的,然後通過JNI調用。*/    
    private static native void registerNatives();   
  /* 對象初始化時自動調用此方法*/  
    static {   
        registerNatives();   
    }   
   /* 傳回此 Object 的運作時類。*/  
    public final native Class<?>  getClass();   
/*  hashCode 的正常協定是:  1.在 Java 應用程式執行期間,在對同一對象多次調用 hashCode 方法時,必須一緻地傳回相同的整數,前提是将對象進行 equals 比較時所用的資訊沒有被修改。從某一應用程式的一次執行到同一應用程式的另一次執行,該整數無需保持一緻。   2.如果根據 equals() 方法,兩個對象是相等的,那麼對這兩個對象中的每個對象調用 hashCode 方法都必須生成相同的整數結果。3.如果根據 equals() 方法,兩個對象不相等,那麼對這兩個對象中的任一對象上調用 hashCode 方法不要求一定生成不同的整數結果。但是,程式員應該意識到,為不相等的對象生成不同整數結果可以提高哈希表的性能。*/  
public native int hashCode();   
//Object類的equals()方法判斷調用equals()方法的引用于傳進來的引用是否一緻,即兩個引用是否指向同一個對象。Object類中的equals()方法等價于==。
//隻有當繼承Object的類覆寫(override)equals()方法之後,繼承類實作equals(),才可以說equals()方法與==的不同。
//equals()方法需要具有如下特點:
//自反性(reflexive):任何非空引用x.equals(x)傳回為true。
//對稱性(symmetric)任何非空引用x和y,x.equals(y)傳回true當且僅當y.equals(x)傳回true。
//傳遞性(transitive):任何非空引用x和y,如果x.equals(y)傳回true,并且y.equals(z)傳回true,那麼x.equals(z)傳回true。
//一緻性(consistent):兩個非空引用x和y,x.equals(y)的多次調用應該保持一緻的結果,(前提條件是在多次比較之間沒有修改x和y用于比較的相關資訊)。
//約定:對于任何非空引用x,x.equals(null)應該傳回為false。并且覆寫equals()方法時,應該同時覆寫hashCode()方法,反之亦然。
    public boolean equals(Object obj) {   
        return (this == obj);   
    }   
/*本地clone方法,用于對象的複制。(想到了一個面試題:Java生成對象有幾種方式?)任何類在執行個體上調用clone(),他将實作cloneable接口重寫clone方法建立副本。有這個方法的類必須實作java.lang.Cloneable接口,否則會抛出CloneNotSupportedException異常。Cloneable接口中不包含任何方法,是以實作它時隻要在類聲明中加上implements語句即可。
第二個比較特殊的地方在于這個方法是protected修飾的,覆寫clone()方法的時候需要寫成public,才能讓類外部的代碼調用。
    protected native Object clone() throws CloneNotSupportedException;   
/*傳回該對象的字元串表示。列印引用會自動調用對象的toString()方法,列印出引用所指的對象的toString()方法的傳回值,因為每個類都直接或間接地繼承自Object,是以每個類都有toString()方法。
    public String toString() {   
        return getClass().getName() + "@" + Integer.toHexString(hashCode());   
    }     
    public final native void notify();   
public final native void notifyAll();   
/*在其他線程調用此對象的 notify() 方法或 notifyAll() 方法前,導緻目前線程等待。換句話說,此方法的行為就好像它僅執行 wait(0) 調用一樣。目前線程必須擁有此對象螢幕。該線程釋出對此螢幕的所有權并等待,直到其他線程通過調用 notify 方法,或 notifyAll 方法通知在此對象的螢幕上等待的線程醒來。然後該線程将等到重新獲得對螢幕的所有權後才能繼續執行。*/  
    public final void wait() throws InterruptedException {   
        wait(0);   
    }   
/*在其他線程調用此對象的 notify() 方法或 notifyAll() 方法,或者超過指定的時間量前,導緻目前線程等待。*/  
    public final native void wait(long timeout) throws InterruptedException;   
/* 在其他線程調用此對象的 notify() 方法或 notifyAll() 方法,或者其他某個線程中斷目前線程,或者已超過某個實際時間量前,導緻目前線程等待。*/  
    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 >= 500000 || (nanos != 0 && timeout == 0)) {   
        timeout++;   
    }     
    wait(timeout);   
    }   
    /*當垃圾回收器确定不存在對該對象的更多引用時,由對象的垃圾回收器調用此方法。
    protected void finalize() throws Throwable { } 
}      

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
枚舉類所有的枚舉值都是類靜态常量,在初始化時會對所有的枚舉值對象進行第一次初始化。枚舉類在背景實作時,實際上是轉化為一個繼承了java.lang.Enum類的實體類,原先的枚舉類型變成對應的實體類型,上例中AccountType變成了個class AccountType,并且會生成一個新的構造函數,若原來有構造函數,則在此基礎上添加兩個參數,生成新的構造函數,新構造器會包含已有的構造器的代碼,而且在這個類中,還會添加若幹(本例子是3個字段)靜态final字段來代表具體的枚舉類型。最後而且還會添加一段static代碼段初始化他們。在初始化過程中new AccountType構造函數被調用了三次,是以Enum中定義的構造函數中的列印代碼被執行了3遍。或者簡單的說private類内可見,類外不可見,枚舉類有三個執行個體,故調用三次構造方法,列印三次It is a account type,然後main方法裡列印一次FIXED。      

Java的instanceof運算符是幹嘛的?實作原理是怎樣的? 

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
java 中的instanceof 運算符是用來在運作時指出對象是否是特定類的一個執行個體。instanceof通過傳回一個布爾值來指出這個對象是否是這個特定類或者是它的子類的一個執行個體。 用法:
result = object instanceof class
參數:

Result:布爾類型。

Object:必選項。任意對象表達式。

Class:必選項。任意已定義的對象類。

說明:如果 object 是 class 的一個執行個體,則 instanceof 運算符傳回 true。如果 object 不是指定類的一個執行個體,或者 object 是 null,則傳回 false。 

至于具體實作原理,簡單說說:JVM有一條名為 instanceof 的指令,而Java源碼編譯到Class檔案時會把Java語言中的 instanceof 運算符映射到JVM的 instanceof 指令上。      

解析 

參考:Java instanceof 關鍵字是如何實作的? 

在使用super 和this關鍵字時,以下描述正确的是

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制

super(), this() 都得放在構造函數第一行,肯定不能放在一起。

關鍵字super的作用是?

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制

super代表父類對應的對象,是以用super通路在子類中無法直接使用的父類成員和方法,如果在子類中對從父類繼承來的成員變量進行重新定義,即出現了子類變量對父類變量的隐藏,不是說的private成員。

除去擴充名.java的部分,包含在java檔案裡的Java裡的公共類必須與檔案的名字相同麼?

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
public class Outter{
  public class Inner{
  }
}

内部類就不需要與檔案名相同      

下列語句正确的是( )

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
形式參數就是函數定義時設定的參數。例如函數頭 int min(int x,int y,int z) 中 x,y,z 就是形參。

實際參數是調用函數時所使用的實際的參數。

形參可以是對象,是對象的時候傳遞引用.形式參數隻能用final修飾符,其它任何修飾符都會引起編譯器錯誤 。但是用這個修飾符也有一定的限制,就是在方法中不能對參數做任何修改。 不過一般情況下,一個方法的形參不用final修飾。隻有在特殊情況下,那就是:方法内部類。

一個方法内的内部類如果使用了這個方法的參數或者局部變量的話,這個參數或局部變量應該是final。

形式參數可被視為local variable。形參和局部變量一樣都不能離開方法。都隻有在方法内才會發生作用,也隻有在方法中使用,不會在方法外可見。      

下列說法正确的有( )

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制
a選項 
-d即可設定系統屬性

c選項 
一次編譯多個java檔案用javac  *.java. 即可編譯目前目錄下的所有java檔案

d選項
-s指定存放生成的源檔案的位置      

歡迎關注

dashuai的部落格是終身學習踐行者,大廠程式員,且專注于工作經驗、學習筆記的分享和日常吐槽,包括但不限于網際網路行業,附帶分享一些PDF電子書,資料,幫忙内推,歡迎拍磚!

Core Java 總結(關鍵字,特性問題) JVM學習(3)——總結Java記憶體模型深入了解Java記憶體模型(六)——finalJVM學習(4)——全面總結Java的GC算法和回收機制

辛苦的勞動,轉載請注明出處,如果真心幫到了您,為鼓勵更多的寫作,您可以選擇部落格右側的打賞功能。