摘要:入隊列,即表示當(dāng)前對象已回收。時,清空對象的屬性即執(zhí)行,再將對象加入該對象關(guān)聯(lián)的中。當(dāng)一個被掉之后,其相應(yīng)的包裝類對象會被放入中。原因是編譯程序?qū)崿F(xiàn)上的困難內(nèi)部類對象的生命周期會超過局部變量的生命期。
一個類的靜態(tài)成員在類的實例gc后,不會銷毀。
對象引用強度強引用Strong Reference
就是指在代碼之中普遍存在的,類似:“Object objectRef = new Obejct”。只要強引用還存在,永遠(yuǎn)不會被GC清理。
軟引用SoftReference
當(dāng)Jvm內(nèi)存不足時(內(nèi)存溢出之前)會被回收。
SoftReference很適合用于實現(xiàn)緩存。
ReferenceQueuereferenceQueue = new ReferenceQueue (); SoftReference softReference = new SoftReference (new Man(), referenceQueue); /*If this reference object has been cleared, either by the program or by the garbage collector, then this method returns null.*/ softReference.get(); //This method is invoked only by Java code; when the garbage collector enqueues references it does so directly, without invoking this method. softReference.enqueue(); //入隊列,即表示當(dāng)前Reference對象已回收。 //Tells whether or not this reference object has been enqueued softReference.isEnqueued();
弱引用WeakReference
弱引用的對象,只能生存到下一次GC前,當(dāng)GC工作時,無論內(nèi)存是否足夠,都會回收掉弱引用關(guān)聯(lián)的對象。
GC時,清空Reference對象的referent屬性(即執(zhí)行Reference.clear()),再將Reference對象加入該對象關(guān)聯(lián)的ReferenceQueue中。
ReferenceQueuequeue = new ReferenceQueue (); WeakReference ref = new WeakReference (new Man(), queue); Assert.assertNotNull(ref.get()); Object obj = null; obj = queue.poll(); Assert.assertNull(obj); System.gc(); Assert.assertNull(ref.get()); Thread.sleep(10);// 入隊列操作較慢,要等一下。 obj = queue.poll(); Assert.assertNotNull(obj);
虛引用PhantomReference
一個虛引用的對象,隨時都會被gc。為一個對象設(shè)置虛引用關(guān)聯(lián)的唯一目的就是希望能在這個對象被GC回收時收到一個系統(tǒng)通知。
phantomReference.get方法永遠(yuǎn)返回null, 當(dāng)從內(nèi)存中刪除時,調(diào)用isEnqueued會返回true
為什么要用ReferenceQueue
Object obj = new Object(); Ref ref = new Ref(obj);
對于以上代碼,我們希望當(dāng)一個對象被gc掉的時候通知用戶線程,進行額外的處理時,就需要使用引用隊列ReferenceQueue。當(dāng)一個obj被gc掉之后,其相應(yīng)的包裝類ref對象會被放入queue中。我們可以從queue中獲取到相應(yīng)的對象信息,進行額外的處理。比如反向操作,數(shù)據(jù)清理等。
比如weakHashMap使用weakReference當(dāng)作key來進行數(shù)據(jù)的存儲,當(dāng)key中的引用被gc掉之后,它不是自動將相應(yīng)的entry給移除掉,而是我們調(diào)用get,size,put等方法時,weakHashMap從key的ReferenceQueue中獲取引用信息,從而使得被gc掉的key值所對應(yīng)的entry從map中被移除,然后再處理我們的業(yè)務(wù)調(diào)用。
類的初始化對于有static final 修飾的變量的類,當(dāng)引用該變量時,該類不會被構(gòu)造。
對于有static變量的類,當(dāng)?shù)谝淮螌嵗擃?,則靜態(tài)變量會初始化,第二次不會。
父類靜態(tài)屬性?-> 父類靜態(tài)塊?-> 子類靜態(tài)屬性?-> 子類靜態(tài)塊?-> 父類屬性?-> 父類塊?-> 父類構(gòu)造器?-> 子類屬性 -> 子類塊 -> 子類構(gòu)造器???
相同等級下先定義的先初始化。
class SuperClass{ public SuperClass(){ System.out.println("SuperClass of constructor"); m(); } public void m(){ System.out.println("SuperClass.m()"); } } public class SubClassTest extends SuperClass { private int i = 10; public SubClassTest(){ System.out.println("SubClass of constructor"); super.m(); m(); } public void m(){ System.out.println("SubClass.m(): i = " + i); } }
測試:
SuperClass t = new SubClassTest();
在生成對象時,父類調(diào)用的M()方法,不是父類的 M()方法,而是子類中被重寫了的M()方法?。∽宇惖膒rivate int i 也被父類訪問到,和private的成員只能在本類使用的原則相違背。其實我們說的這條原則是編譯期間所遵守的,在JAVA程序的編譯期間,它只檢查語法的合法性,在JAVA的JVM中,即運行期間,不管你聲明的什么,對于JVM來說都是透明的,而動態(tài)引用是在運行期間執(zhí)行的,所以能拿到SubClass的private成員,只是此時還沒執(zhí)行 i = 10,所以只能將i賦予初值0。
抽象類和接口記住一個原則:接口目的是抽象,抽象類目的是復(fù)用;
接口可以繼承接口,一個抽象類或具體類可以實現(xiàn)多個接口(對于模塊功能擴展,不需要修改原有接口)。
抽象類在實現(xiàn)接口中可以不用實現(xiàn)接口的所有方法。
接口的方法都是抽象方法。抽象類比接口靈活(彈性),多層抽象類的繼承可以讓整個主體更有擴展性和層次性。
當(dāng)一個類實現(xiàn)一個接口時,如果不能完全實現(xiàn)就把這個類寫作抽象類,就跟一個類如果不能實現(xiàn)他所繼承的抽象類的全部抽象方法,那這個類也要命名為抽象類。
接口中定義變量必須為public static final,一般默認(rèn),可省略。
就是在對象的方法內(nèi)部定義的類。而該局部內(nèi)部類中的方法訪問該局部內(nèi)部類所在的方法中的局部變量時,該局部變量要加上final。
原因是:編譯程序?qū)崿F(xiàn)上的困難:內(nèi)部類對象的生命周期會超過局部變量的生命期。當(dāng)該方法被調(diào)用時,該方法中的局部變量在棧中被創(chuàng)建,當(dāng)方法調(diào)用結(jié)束時,退棧,這些局部變量全部死亡。而內(nèi)部類生命期,與其它類一樣,只有沒有其它人再引用它時,它才能死亡。
為什么局部變量定義為final可以呢?因為final變量為不可改變,編譯程序具體實現(xiàn):將所有的局部內(nèi)部類對象要訪問的final型局部變量,拷貝到局部內(nèi)部類中。
在Java8中,這種限制被新的概念“effectively final”取代了。它的意思是你可以聲明為final,也可以不聲明final但是要按照final來用,也就是一次賦值永不改變。即保證它加上final前綴后不會出編譯錯誤。
注:不管變量是不是final,他的生命周期都在于{}中。
泛型使得類型錯誤可以在編譯時被捕獲,而不是在運行時當(dāng)作 ClassCastException 展示出來;消除強制類型轉(zhuǎn)換,這使得代碼更加可讀。
類型擦除:
C#里面泛型無論在程序源碼中、編譯后的IL中(Intermediate Language,中間語言,這時候泛型是一個占位符)或是運行期的CLR中都是切實存在的,List
Java泛型只在程序源碼中存在,在編譯后的字節(jié)碼文件中,就已經(jīng)被替換為原來的原生類型(Raw Type),并且在相應(yīng)的地方插入了強制轉(zhuǎn)型代碼,因此對于運行期的Java來說,ArrayList
所以以下代碼method()無法重載:
public?class?GenericTypes?{?? ?? ???public?static?void?method(List?list)?{?? ??????......?? ???}? ? ???public?static?void?method(List ?list)?{?? ???????...... ???}?? }?
?
方法的Signature屬性是在字節(jié)碼層面存儲一個方法的特征簽名,這個屬性中保存了參數(shù)化類型的信息。雖然擦除法對方法體的源碼的字節(jié)碼進行類型擦除,但由于Signature,我們還是能通過反射API取得參數(shù)化類型。?
對象引用一個父類對象的引用指向一個子類對象,從編譯角度,該引用只能調(diào)用父類中定義的方法和變量;如果子類中重寫了父類中的一個方法,那么會調(diào)用子類中的這個方法;變量不能被重寫(覆蓋),”重寫“的概念只針對方法。
對象引用在內(nèi)存中兩個對象都生成了,子類、父類變量都生成了。
class Father { String name = "Father"; public void func1() { func2(); // 若子類實現(xiàn)了func2(),則調(diào)用子類的func2() } public void func2() { System.out.println("Father func2"); } } class Child extends Father { String name = "Child"; public void func2() { System.out.println("Child func2"); } }
測試:
Child child1 = new Child(); Father child2 = new Child(); child2.func1(); // Child func2 // 與方法重載不同,屬性是無法重載的,屬性跟類型走 System.out.println(child1.name); // Child System.out.println(child2.name); // FatherEnum
Enum用于數(shù)據(jù)結(jié)構(gòu)是穩(wěn)定的,而且數(shù)據(jù)個數(shù)是有限的“數(shù)據(jù)集”。
//其內(nèi)部實現(xiàn) public abstract class Enum> implements Comparable , Serializable public enum Man { //wangliqiu、centifocus必定是public static final。 wangliqiu, centifocus; public String name; public int age; public String sex; } //類比以上enum public static class Man { public static final Man wangliqiu = new Man(); public static final Man centifocus = new Man(); public String name; public int age; public String sex; }
示例:
public enum ColorEnum { red, // green, // yellow, // blue; } public static void main(String[] args) { ColorEnum colorEnum = ColorEnum.blue; switch (colorEnum) { case red: System.out.println("color is red"); break; case blue: System.out.println("color is blue"); break; } // 遍歷 for (ColorEnum color : ColorEnum.values()) { System.out.println(color); } System.out.println("枚舉索引位置:" + ColorEnum.red.ordinal());// 0 // 枚舉默認(rèn)實現(xiàn)java.lang.Comparable接口,因為ENUM抽象類實現(xiàn)了。 System.out.println(ColorEnum.red.compareTo(ColorEnum.green));// -1 }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/67273.html
摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍(lán)圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍(lán)圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍(lán)圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:原文地址對象和對象的區(qū)別對象和對象使用說明,需要的朋友可以參考下。同樣,對象也不能使用方法。學(xué)習(xí)開始就應(yīng)當(dāng)樹立正確的觀念,分清對象和對象之間的區(qū)別,之后學(xué)習(xí)就會輕松很多的。 原文地址:http://www.cnblogs.com/yellow... DOM對象和JQuery對象的區(qū)別 jQuery對象和DOM對象使用說明,需要的朋友可以參考下。jQuery對象和DOM對象第一次學(xué)習(xí)jQ...
摘要:對象的分類內(nèi)置對象原生對象就是語言預(yù)定義的對象,在標(biāo)準(zhǔn)定義,有解釋器引擎提供具體實現(xiàn)宿主對象指的是運行環(huán)境提供的對象。不過類型是中所有類型的父級所有類型的對象都可以使用的屬性和方法,可以通過的構(gòu)造函數(shù)來創(chuàng)建自定義對象。 對象 javaScript中的對象,和其它編程語言中的對象一樣,可以比照現(xiàn)實生活中的對象來理解。在JavaScript中,一個對象可以是一個單獨擁有屬性和類型的實體。和...
摘要:對象是什么在中,一個對象就像一個單獨擁有屬性和類型的實體。一個杯子作為一個對象,杯子有顏色重量等屬性。同樣,對象也有屬性定義它的特征。方法是關(guān)聯(lián)到某個對象的函數(shù),或者說,一個方法是一個值為某個函數(shù)的對象屬性。 對象是什么 在JavaScript中,一個對象就像一個單獨擁有屬性和類型的實體。一個杯子作為一個對象,杯子有顏色、重量等屬性。同樣,JavaScript對象也有屬性定義它的特征。...
閱讀 1500·2021-11-17 09:33
閱讀 1267·2021-10-11 10:59
閱讀 2900·2021-09-30 09:48
閱讀 1909·2021-09-30 09:47
閱讀 3032·2019-08-30 15:55
閱讀 2343·2019-08-30 15:54
閱讀 1499·2019-08-29 15:25
閱讀 1653·2019-08-29 10:57