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