




已閱讀5頁(yè),還剩4頁(yè)未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
J2SE基礎(chǔ) 九種基本數(shù)據(jù)類型的大小,以及他們的封裝類?;绢愋停篵oolean byte char short int long float double void 封裝類型:Boolean Byte 基本類型大小范圍默認(rèn)值包裝類型boolean1True、falseFalseBooleanbyte8-128 +1270Byte char16Unicode0 unicode216 -1u0000Charactershort16-215 215-1Shortint32-231 231-1Integerlong64-263 263-1Longfloat32Floatdouble64DoublevoidVoidl 基本數(shù)據(jù)類型與其對(duì)應(yīng)的封裝類由于本質(zhì)的不同,具有一些區(qū)別:基本數(shù)據(jù)類型只能按值傳遞,而封裝類按引用傳遞?;绢愋驮诙褩V袆?chuàng)建;而對(duì)于對(duì)象類型,對(duì)象在堆中創(chuàng)建,對(duì)象的引用在堆棧中創(chuàng)建。基本類型由于在堆棧中,效率會(huì)比較高,但是可能會(huì)存在內(nèi)存泄漏的問(wèn)題。 2. Switch能否用string做參數(shù)?在java7之前,switch只支持byte、short、char、int 或者其對(duì)應(yīng)的封裝類以及Eumn類型,在java7中,String支持被加上了。如在jdk 7 之前的版本使用, 會(huì)提示如下錯(cuò)誤:Cannot switch on a value of type String for source level below 1.7.Only convertible int values or enum variables are permitted 3. equals與=的區(qū)別。值類型是存儲(chǔ)在內(nèi)存的棧中,引用類型的變量在棧中存放其引用類型變量的地址,其值存儲(chǔ)在堆中。= 比較的是兩個(gè)變量的值是否相等,對(duì)于引用變量表示的是兩個(gè)變量在堆中存儲(chǔ)的地址是否相同,即棧中的內(nèi)容是否相同。Equals 比較的是兩個(gè)變量是否是對(duì)同一個(gè)對(duì)象的引用,即堆中的內(nèi)容是否相同。public class TestString public static void main(String args) String s1 = Monday; String s2 = Monday; if (s1 = s2) System.out.println(s1 = s2); else System.out.println(s1 != s2); 創(chuàng)建對(duì)象之前會(huì)在字符串緩沖池中查找是否有此字符串常量,如果存在直接返回其引用,s1、s2兩者的引用都是相同的。public class TestString public static void main(String args) String s1 = Monday; String s2 = new String(Monday); s2 = ern(); if (s1 = s2) System.out.println(s1 = s2); else System.out.println(s1 != s2); if (s1.equals(s2) System.out.println(s1 equals s2); else System.out.println(s1 not equals s2); 本程序中的s1指向字符串緩沖區(qū)中的常量的引用,s2根據(jù)字符串緩沖區(qū)中的常量作為構(gòu)造函數(shù)的參數(shù),新建了一個(gè)對(duì)象并存儲(chǔ)在內(nèi)存中的另一個(gè)位置。(如果常量不存在與字符串緩沖區(qū),則先在字符串緩沖區(qū)中建立常量,然后newString,這樣就創(chuàng)建了兩個(gè)對(duì)象?。└剑簶?gòu)造方法 original即為字符串緩沖池中得到的public String(String original) this.value = original.value; this.hash = original.hash; l java字符串緩沖池分析java字符串緩沖池分析:java的虛擬機(jī)在內(nèi)存中開(kāi)辟出一塊單獨(dú)的區(qū)域,用來(lái)存儲(chǔ)字符串對(duì)象,這塊內(nèi)存區(qū)域被稱為字符串緩沖池。到底創(chuàng)建了幾個(gè)對(duì)象?1,0,2,1,1 String a = abc; String b = abc; String c = new String(xyz); String d = new String(xyz); String e=ab+cd;為什么相等?public static void main(String args) String s1 = Monday; String s2 = new String(Monday); s2 = ern(); if (s1 = s2) System.out.println(s1 = s2); else System.out.println(s1 != s2); if (s1.equals(s2) System.out.println(s1 equals s2); else System.out.println(s1 not equals s2); Intern()方法返回的是在字符串緩沖池中的對(duì)象引用!對(duì)比: public static void main(String args) String Monday = Monday; String Mon = Mon; String day = day; System.out.println(Monday = Mon + day); System.out.println(Monday = Mon + day); 只有加號(hào)左右兩邊的都是字符串常量時(shí),才能在編譯階段指向緩沖池的常量,day是一個(gè)變量,在運(yùn)行時(shí)指向內(nèi)存中某個(gè)地址public static void main(String args) String Monday = Monday; String Mon = Mon; final String day = day; System.out.println(Monday = Mon + day); System.out.println(Monday = Mon + day); Final修飾的day變成一個(gè)常量,在編譯階段指向緩沖池。 4. Object有哪些公用方法? clone保護(hù)方法,實(shí)現(xiàn)對(duì)象的淺復(fù)制,只有實(shí)現(xiàn)了Cloneable接口才可以調(diào)用該方法,否則拋出CloneNotSupportedException異常 equals在Object中與=是一樣的,子類一般需要重寫該方法 hashCode該方法用于哈希查找,重寫了equals方法一般都要重寫hashCode方法。這個(gè)方法在一些具有哈希功能的Collection中用到 getClassfinal方法,獲得運(yùn)行時(shí)類型 wait使當(dāng)前線程等待該對(duì)象的鎖,當(dāng)前線程必須是該對(duì)象的擁有者,也就是具有該對(duì)象的鎖。wait()方法一直等待,直到獲得鎖或者被中斷。wait(long timeout)設(shè)定一個(gè)超時(shí)間隔,如果在規(guī)定時(shí)間內(nèi)沒(méi)有獲得鎖就返回。調(diào)用該方法后當(dāng)前線程進(jìn)入睡眠狀態(tài),直到以下事件發(fā)生:1. 其他線程調(diào)用了該對(duì)象的notify方法2. 其他線程調(diào)用了該對(duì)象的notifyAll方法3. 其他線程調(diào)用了interrupt中斷該線程4. 時(shí)間間隔到了此時(shí)該線程就可以被調(diào)度了,如果是被中斷的話就拋出一個(gè)InterruptedException異常 notify喚醒在該對(duì)象上等待的某個(gè)線程 notifyAll喚醒在該對(duì)象上等待的所有線程 toString轉(zhuǎn)換成字符串,一般子類都有重寫,否則打印句柄l Java中的深復(fù)制和淺復(fù)制?什么是影子clone?classUnCloneAprivateinti;publicUnCloneA(intii)i=ii;publicvoiddoublevalue()i*=2;publicStringtoString()returnInteger.toString(i);classCloneBimplementsCloneablepublicintaInt;publicUnCloneAunCA=newUnCloneA(111);publicObjectclone()CloneBo=null;tryo=(CloneB)super.clone();catch(CloneNotSupportedExceptione)e.printStackTrace();returno;publicclassObjRefpublicstaticvoidmain(Stringa)CloneBb1=newCloneB();b1.aInt=11;System.out.println(beforeclone,b1.aInt=+b1.aInt);System.out.println(beforeclone,b1.unCA=+b1.unCA);CloneBb2=(CloneB)b1.clone();b2.aInt=22;b2.unCA.doublevalue();System.out.println(=);System.out.println(afterclone,b1.aInt=+b1.aInt);System.out.println(afterclone,b1.unCA=+b1.unCA);System.out.println(=);System.out.println(afterclone,b2.aInt=+b2.aInt);System.out.println(afterclone,b2.unCA=+b2.unCA);原樣拷貝原始對(duì)象中的內(nèi)容。對(duì)基本數(shù)據(jù)類型,這樣的操作是沒(méi)有問(wèn)題的,但對(duì)非基本類型變量,我們知道它們保存的僅僅是對(duì)象的引用,這也導(dǎo)致clone后的非基本類型變量和原始對(duì)象中相應(yīng)的變量指向的是同一個(gè)對(duì)象。 輸出結(jié)果:before clone,b1.aInt = 11before clone,b1.unCA = 111=after clone,b1.aInt = 11after clone,b1.unCA = 222=after clone,b2.aInt = 22after clone,b2.unCA = 222深拷貝的改進(jìn)方法:改成深度clone很簡(jiǎn)單,需要兩個(gè)改變:一是讓UnCloneA類也實(shí)現(xiàn)和CloneB類一樣的clone功能(實(shí)現(xiàn)Cloneable接口,重載clone()方法)。二是在CloneB的clone()方法中加入一句o.unCA=(UnCloneA)unCA.clone();深拷貝:class UnCloneA implements Cloneable private int i; public UnCloneA(int ii) i = ii; public void doublevalue() i *= 2; public String toString() return Integer.toString(i); public Object clone() UnCloneA o = null; try o = (UnCloneA) super.clone(); catch (CloneNotSupportedException e) e.printStackTrace(); return o; class CloneB implements Cloneable public int aInt; public UnCloneA unCA = new UnCloneA(111); public Object clone() CloneB o = null; try o = (CloneB) super.clone(); catch (CloneNotSupportedException e) e.printStackTrace(); o.unCA = (UnCloneA) unCA.clone(); return o; l 注意:要知道不是所有的類都能實(shí)現(xiàn)深度clone的,StringBuffer沒(méi)有重載clone()方法,更為嚴(yán)重的是StringBuffer還是一個(gè)final類,這也是說(shuō)我們也不能用繼承的辦法間接實(shí)現(xiàn)StringBuffer的clone。l 我們有兩種選擇:要么只能實(shí)現(xiàn)影子clone,要么就在類的clone()方法中加一句(假設(shè)是SringBuffer對(duì)象,而且變量名仍為unCA):o.unCA=newStringBuffer(unCA.toString();l String對(duì)象是一個(gè)例外,它c(diǎn)lone后的表現(xiàn)好象也實(shí)現(xiàn)了深度clone,雖然這只是一個(gè)假象,但卻大大方便了我們的編程。class CloneC implements Cloneable public String str; public StringBuffer strBuff; public Object clone() CloneC o = null; try o = (CloneC) super.clone(); catch (CloneNotSupportedException e) e.printStackTrace(); return o; public class StrClone public static void main(String a) CloneC c1 = new CloneC(); c1.str = new String(initializeStr); c1.strBuff = new StringBuffer(initializeStrBuff); System.out.println(before clone,c1.str = + c1.str); System.out.println(before clone,c1.strBuff = + c1.strBuff); CloneC c2 = (CloneC) c1.clone(); c2.str = c2.str.substring(0, 5); c2.strBuff = c2.strBuff.append( change strBuff clone); System.out.println(=); System.out.println(after clone,c1.str = + c1.str); System.out.println(after clone,c1.strBuff = + c1.strBuff); System.out.println(=); System.out.println(after clone,c2.str = + c2.str); System.out.println(after clone,c2.strBuff = + c2.strBuff); 秘密就在于c2.str = c2.str.substring(0,5)這一語(yǔ)句!實(shí)質(zhì)上,在clone的時(shí)候c1.str與c2.str仍然是引用,而且都指向了同一個(gè)String對(duì)象。但在執(zhí)行c2.str = c2.str.substring(0,5)的時(shí)候,它作用相當(dāng)于生成了一個(gè)新的String類型,然后又賦回給c2.str。這是因?yàn)镾tring被Sun公司的工程師寫成了一個(gè)不可更改的類(immutable class),在所有String類中的函數(shù)都不能更改自身的值。 5. Java的四種引用,強(qiáng)弱軟虛,用到的場(chǎng)景。 四種引用類型包括:強(qiáng)引用、弱引用、軟引用、虛引用(幽靈引用),使程序能夠更靈活的控制對(duì)象的生命周期。1. 強(qiáng)引用(StrongReference):強(qiáng)引用不會(huì)被垃圾回收器回收,并且也沒(méi)有實(shí)際的對(duì)應(yīng)類型,平時(shí)接觸最多的就是強(qiáng)引用。例如Object obj = new Object();這里obj即為強(qiáng)引用。如果一個(gè)對(duì)象具有強(qiáng)引用,垃圾回收器絕不會(huì)回收它。當(dāng)內(nèi)存空間不足,java虛擬機(jī)寧愿拋出out of MemoryError錯(cuò)誤,是程序異常終止,也不會(huì)靠回收具有強(qiáng)引用的對(duì)象來(lái)解決內(nèi)存不足問(wèn)題。2. 軟引用(SoftReference)如果一個(gè)對(duì)象只具有軟引用,如果內(nèi)存空間足夠,垃圾回收器就不會(huì)回收它,如果內(nèi)存空間不足,就會(huì)回收這些對(duì)象的內(nèi)存。只要垃圾回收器沒(méi)有回收它,該對(duì)象就可以被程序使用。軟引用可以用來(lái)實(shí)現(xiàn)內(nèi)存敏感的高速緩存。軟引用可以和一個(gè)引用隊(duì)列(ReferenceQueue)聯(lián)合使用,如果軟引用所引用的對(duì)象被垃圾回收,java虛擬機(jī)就會(huì)把這個(gè)軟引用加入到與之關(guān)聯(lián)的引用隊(duì)列。/* * 只有當(dāng)內(nèi)存不夠的時(shí)候,才回收這類內(nèi)存,因此在內(nèi)存足夠的時(shí)候,它們通常不被回收 * * 無(wú)論是否發(fā)送GC,執(zhí)行結(jié)果都是: * java.lang.Objectf9f9d8 * null * java.lang.Objectf9f9d8 * null * * 可以看到:只有發(fā)送了GC,將對(duì)于從內(nèi)存中釋放的時(shí)候,JVM才會(huì)將reference假如引用隊(duì)列 */public static void soft() throws Exception Object obj = new Object(); ReferenceQueue refQueue = new ReferenceQueue(); SoftReference softRef = new SoftReference(obj, refQueue);System.out.println(softRef.get(); / java.lang.Objectf9f9d8 System.out.println(refQueue.poll();/ null / 清除強(qiáng)引用,觸發(fā)GC obj = null; System.gc(); System.out.println(softRef.get(); Thread.sleep(200); System.out.println(refQueue.poll(); 1 為什么需要使用軟引用 首先,我們看一個(gè)雇員信息查詢系統(tǒng)的實(shí)例。我們將使用一個(gè)Java語(yǔ)言實(shí)現(xiàn)的雇員信息查詢系統(tǒng)查詢存儲(chǔ)在磁盤文件或者數(shù)據(jù)庫(kù)中的雇員人事檔案信息。我們完全有可能需要回頭去查看幾分鐘甚至幾秒鐘前查看過(guò)的雇員檔案信息(同樣,我們?cè)跒g覽WEB頁(yè)面的時(shí)候也經(jīng)常會(huì)使用“后退”按鈕)。這時(shí)我們通常會(huì)有兩種程序?qū)崿F(xiàn)方式:一種是把過(guò)去查看過(guò)的雇員信息保存在內(nèi)存中,每一個(gè)存儲(chǔ)了雇員檔案信息的Java對(duì)象的生命周期貫穿整個(gè)應(yīng)用程序始終;另一種是當(dāng)用戶開(kāi)始查看其他雇員的檔案信息的時(shí)候,把存儲(chǔ)了當(dāng)前所查看的雇員檔案信息的Java對(duì)象結(jié)束引用,使得垃圾收集線程可以回收其所占用的內(nèi)存空間,當(dāng)用戶再次需要瀏覽該雇員的檔案信息的時(shí)候,重新構(gòu)建該雇員的信息。很顯然,第一種實(shí)現(xiàn)方法將造成大量的內(nèi)存浪費(fèi),而第二種實(shí)現(xiàn)的缺陷在于即使垃圾收集線程還沒(méi)有進(jìn)行垃圾收集,包含雇員檔案信息的對(duì)象仍然完好地保存在內(nèi)存中,應(yīng)用程序也要重新構(gòu)建一個(gè)對(duì)象。我們知道,訪問(wèn)磁盤文件、訪問(wèn)網(wǎng)絡(luò)資源、查詢數(shù)據(jù)庫(kù)等操作都是影響應(yīng)用程序執(zhí)行性能的重要因素,如果能重新獲取那些尚未被回收的Java對(duì)象的引用,必將減少不必要的訪問(wèn),大大提高程序的運(yùn)行速度。2 如果使用軟引用 SoftReference的特點(diǎn)是它的一個(gè)實(shí)例保存對(duì)一個(gè)Java對(duì)象的軟引用,該軟引用的存在不妨礙垃圾收集線程對(duì)該Java對(duì)象的回收。也就是說(shuō),一旦SoftReference保存了對(duì)一個(gè)Java對(duì)象的軟引用后,在垃圾線程對(duì)這個(gè)Java對(duì)象回收前,SoftReference類所提供的get()方法返回Java對(duì)象的強(qiáng)引用。另外,一旦垃圾線程回收該Java對(duì)象之后,get()方法將返回null??聪旅娲a:MyObject aRef = new MyObject();SoftReference aSoftRef = new SoftReference(aRef); 此時(shí),對(duì)于這個(gè)MyObject對(duì)象,有兩個(gè)引用路徑,一個(gè)是來(lái)自SoftReference對(duì)象的軟引用,一個(gè)來(lái)自變量aReference的強(qiáng)引用,所以這個(gè)MyObject對(duì)象是強(qiáng)可及對(duì)象。隨即,我們可以結(jié)束aReference對(duì)這個(gè)MyObject實(shí)例的強(qiáng)引用:aRef = null;此后,這個(gè)MyObject對(duì)象成為了軟可及對(duì)象。如果垃圾收集線程進(jìn)行內(nèi)存垃圾收集,并不會(huì)因?yàn)橛幸粋€(gè)SoftReference對(duì)該對(duì)象的引用而始終保留該對(duì)象。Java虛擬機(jī)的垃圾收集線程對(duì)軟可及對(duì)象和其他一般Java對(duì)象進(jìn)行了區(qū)別對(duì)待:軟可及對(duì)象的清理是由垃圾收集線程根據(jù)其特定算法按照內(nèi)存需求決定的。也就是說(shuō),垃圾收集線程會(huì)在虛擬機(jī)拋出OutOfMemoryError之前回收軟可及對(duì)象,而且虛擬機(jī)會(huì)盡可能優(yōu)先回收長(zhǎng)時(shí)間閑置不用的軟可及對(duì)象,對(duì)那些剛剛構(gòu)建的或剛剛使用過(guò)的“新”軟可反對(duì)象會(huì)被虛擬機(jī)盡可能保留。在回收這些對(duì)象之前,我們可以通過(guò):MyObject anotherRef=(MyObject)aSoftRef.get(); 重新獲得對(duì)該實(shí)例的強(qiáng)引用。而回收之后,調(diào)用get()方法就只能得到null了。3 使用ReferenceQueue清除失去了軟引用對(duì)象的SoftReference 作為一個(gè)Java對(duì)象,SoftReference對(duì)象除了具有保存軟引用的特殊性之外,也具有Java對(duì)象的一般性。所以,當(dāng)軟可及對(duì)象被回收之后,雖然這個(gè)SoftReference對(duì)象的get()方法返回null,但這個(gè)SoftReference對(duì)象已經(jīng)不再具有存在的價(jià)值,需要一個(gè)適當(dāng)?shù)那宄龣C(jī)制,避免大量SoftReference對(duì)象帶來(lái)的內(nèi)存泄漏。在java.lang.ref包里還提供了ReferenceQueue。如果在創(chuàng)建SoftReference對(duì)象的時(shí)候,使用了一個(gè)ReferenceQueue對(duì)象作為參數(shù)提供給SoftReference的構(gòu)造方法,如:ReferenceQueuequeue=newReferenceQueue();SoftReferenceref=newSoftReference(aMyObject,queue);那么當(dāng)這個(gè)SoftReference所軟引用的aMyOhject被垃圾收集器回收的同時(shí),ref所強(qiáng)引用的SoftReference對(duì)象被列入ReferenceQueue。也就是說(shuō),ReferenceQueue中保存的對(duì)象是Reference對(duì)象,而且是已經(jīng)失去了它所軟引用的對(duì)象的Reference對(duì)象。另外從ReferenceQueue這個(gè)名字也可以看出,它是一個(gè)隊(duì)列,當(dāng)我們調(diào)用它的poll()方法的時(shí)候,如果這個(gè)隊(duì)列中不是空隊(duì)列,那么將返回隊(duì)列前面的那個(gè)Reference對(duì)象。在任何時(shí)候,我們都可以調(diào)用ReferenceQueue的poll()方法來(lái)檢查是否有它所關(guān)心的非強(qiáng)可及對(duì)象被回收。如果隊(duì)列為空,將返回一個(gè)null,否則該方法返回隊(duì)列中前面的一個(gè)Reference對(duì)象。利用這個(gè)方法,我們可以檢查哪個(gè)SoftReference所軟引用的對(duì)象已經(jīng)被回收。于是我們可以把這些失去所軟引用的對(duì)象的SoftReference對(duì)象清除掉。常用的方式為:SoftReference ref =null;while(ref = (EmployeeRef)q.poll() !=null) /清除refReferenceQueue清除無(wú)用的引用ReferenceQueue q = new ReferenceQueue();/ 獲取數(shù)據(jù)并緩存Object obj = new Object();SoftReference sr = new SoftReference(obj, q);/ 下次使用時(shí)Object obj = (Object)sr.get();if (obj = null) / 當(dāng)軟引用被回收后才重新獲取 obj = new Object();/ 清理被收回后剩下來(lái)的軟引用對(duì)象SoftReference ref = null;while(ref = q.poll() != null) / 清理工作3. 弱引用:如果一個(gè)對(duì)象只具有弱引用,類似于可有可無(wú)的生活用品。弱引用和軟引用的區(qū)別:只具有弱引用的對(duì)象擁有更短的生命周期。在垃圾回收器線程掃描他所管轄的內(nèi)存區(qū)域過(guò)程中,一旦發(fā)現(xiàn)了只具有弱引用的對(duì)象,不管當(dāng)前內(nèi)存空間足夠與否,都會(huì)回收它的內(nèi)存。由于垃圾回收器是一個(gè)優(yōu)先級(jí)很低的線程,因此不一定會(huì)很快發(fā)現(xiàn)那些只具有弱引用的對(duì)象。弱引用可以和一個(gè)引用隊(duì)列(ReferenceQueue)聯(lián)合使用,如果弱引用所引用的對(duì)象被垃圾回收,java虛擬機(jī)就會(huì)把這個(gè)弱引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。/* * 弱引用: 當(dāng)發(fā)生GC的時(shí)候,Weak引用對(duì)象總是會(huì)內(nèi)回收回收。因此Weak引用對(duì)象會(huì)更容易、更快被GC回收。 * Weak引用對(duì)象常常用于Map數(shù)據(jù)結(jié)構(gòu)中,引用占用內(nèi)存空間較大的對(duì)象 * * 如果不發(fā)生垃圾回收: * java.lang.Objectf9f9d8 * null * java.lang.Objectf9f9d8 * null * * 如果發(fā)生垃圾回收: * java.lang.Objectf9f9d8 * null * null * java.lang.ref.WeakReference422ede * */public static void weak() throws Exception Object obj = new Object(); ReferenceQueue refQueue = new ReferenceQueue(); WeakReference weakRef = new WeakReference(obj, refQueue); System.out.println(weakRef.get(); /java.lang.Objectf9f9d8 System.out.println(refQueue.poll(); / null / 清除強(qiáng)引用,觸發(fā)GC obj = null;System.gc(); System.out.println(weakRef.get(); / 這里特別注意:poll是非阻塞的,remove是阻塞的. / JVM將弱引用放入引用隊(duì)列需要一定的時(shí)間,所以這里先睡眠一會(huì)兒 / System.out.println(refQueue.poll(); / 這里有可能是null Thread.sleep(200); System.out.println(refQueue.poll(); / System.out.println(refQueue.poll();/這里一定是null,因?yàn)橐呀?jīng)從隊(duì)列中移除 / System.out.println(refQueue.remove(); 什么是socket?用于在兩個(gè)的應(yīng)用程序之間相互通信,scoket是屬于TCPIP的上一層。最早出現(xiàn)在UNIX系統(tǒng)中,是UNIX系統(tǒng)主要的信息傳遞方式。在WINDOWS系統(tǒng)中,SOCKET稱為WINSOCK。兩個(gè)基本概念:客戶方和服務(wù)方。當(dāng)兩個(gè)應(yīng)用之間需要采用SOCKET通信時(shí),首先需要在兩個(gè)應(yīng)用之間(可能位于同一臺(tái)機(jī)器,也可能位于不同的機(jī)器)建立SOCKET連接,發(fā)起呼叫連接請(qǐng)求的一方為客戶方,接受呼叫連接請(qǐng)求的一方成為服務(wù)方??蛻舴胶头?wù)方是相對(duì)的,同一個(gè)應(yīng)用可以是客戶方,也可以是服務(wù)方。在客戶方呼叫連接請(qǐng)求之前,它必須知道服務(wù)方在哪里。所以需要知道服務(wù)方所在機(jī)器的IP地址或機(jī)器名稱,如果客戶方和服務(wù)方事前有一個(gè)約定就好了,這個(gè)約定就是PORT(端口號(hào))。也就是說(shuō),客戶方可以通過(guò)服務(wù)方所在機(jī)器的IP地址或機(jī)器名稱和端口號(hào)唯一的確定方式來(lái)呼叫服務(wù)方。在客戶方呼叫之前,服務(wù)方必須處于偵聽(tīng)狀態(tài),偵聽(tīng)是否有客戶要求建立連接。一旦接到連接請(qǐng)求,服務(wù)方可以根據(jù)情況建立或拒絕連接。連接方式有兩種,同步方式(Blocking)和(noBlocking).客戶方發(fā)送的消息可以是文本,也可以是二進(jìn)制信息流。當(dāng)客戶方的消息到達(dá)服務(wù)方端口時(shí),會(huì)自動(dòng)觸發(fā)一個(gè)事件(event),服務(wù)方只要接管該事件,就可以接受來(lái)自客戶方的消息了。l 使用弱引用構(gòu)建非敏感數(shù)據(jù)的緩存a) 全局Map造成的內(nèi)存泄漏public class SocketManager private Map m = new HashMap(); public void setUser(Socket s, User u) m.put(s, u); public User getUser(Socket s) return m.get(s); public void removeUser(Socket s) m.remove(s); b) 用WeakHashMap堵住泄漏public class SocketManager private Map m = new WeakHashMap(); public void setUser(Socket s, User u) m.put(s, u); public User getUser(Socket s) return m.get(s); 4. 虛引用(PhantomReference):“虛引用”顧名思義,就是形同虛設(shè),與其他幾種引用都不同,虛引用并不會(huì)決定對(duì)象的生命周期。如果一個(gè)對(duì)象僅持有虛引用,那么它就和沒(méi)有任何引用一樣,在任何時(shí)候都可能被垃圾回收器回收。虛引用主要用來(lái)跟蹤對(duì)象被垃圾回收器回收的活動(dòng)。虛引用與軟引用和弱引用的一個(gè)區(qū)別在于:虛引用必須和引用隊(duì)列 (ReferenceQueue)聯(lián)合使用。當(dāng)垃圾回收器準(zhǔn)備回收一個(gè)對(duì)象時(shí),如果發(fā)現(xiàn)它還有虛引用,就會(huì)在回收對(duì)象的內(nèi)存之前,把這個(gè)虛引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。程序可以通過(guò)判斷引用隊(duì)列中是否已經(jīng)加入了虛引用,來(lái)了解被引用的對(duì)象是否將要被垃圾回收。如果程序發(fā)現(xiàn)某個(gè)虛引用已經(jīng)被加入到引用隊(duì)列,那么就可以在所引用的對(duì)象的內(nèi)存被回收之前采取必要的行動(dòng)。GC一但發(fā)現(xiàn)了虛引用對(duì)象,將會(huì)將PhantomReference對(duì)象插入ReferenceQueue隊(duì)列. * 而此時(shí)PhantomReference所指向的對(duì)象并沒(méi)有被GC回收,而是要等到ReferenceQueue被你真正的處理后才會(huì)被回收l(shuí) 對(duì)象可及性的判斷 在很多時(shí)候,一個(gè)對(duì)象并不是從根集直接引用的,而是一個(gè)對(duì)象被其他對(duì)象引用,甚至同時(shí)被幾個(gè)對(duì)象所引用,從而構(gòu)成一個(gè)以根集為頂?shù)臉湫谓Y(jié)構(gòu)。如圖2所示 在這個(gè)樹形的引用鏈中,箭頭的方向代表了引用的方向,所指向的對(duì)象是被引用對(duì)象。由圖可以看出,從根集到一個(gè)對(duì)象可以由很多條路徑。比如到達(dá)對(duì)象5的路徑就有-,-兩條路徑。由此帶來(lái)了一個(gè)問(wèn)題,那就是某個(gè)對(duì)象的可及性如何判斷:單條引用路徑可及性判斷:在這條路徑中,最弱的一個(gè)引用決定對(duì)象的可及性。多條引用路徑可及性判斷:幾條路徑中,最強(qiáng)的一條的引用決定對(duì)象的可及性。 比如,我們假設(shè)圖2中引用和為強(qiáng)引用,為軟引用,為弱引用,對(duì)于對(duì)象5按照這兩個(gè)判斷原則,路徑-取最弱的引用,因此該路徑對(duì)對(duì)象5的引用為軟引用。同樣,-為弱引用。在這兩條路徑之間取最強(qiáng)的引用,于是對(duì)象5是一個(gè)軟可及對(duì)象。四種引用的應(yīng)用場(chǎng)景: 6. Hashcode的作用。Java中的集合(Collection)有兩類,一類是List,再有一類是Set。前者集合內(nèi)的元素是有序的,元素可以重復(fù);后者元素?zé)o序,但元素不可重復(fù)。那么這里就有一個(gè)比較嚴(yán)重的問(wèn)題了:要想保證元素不重復(fù),可兩個(gè)元素是否重復(fù)應(yīng)該依據(jù)什么來(lái)判斷呢?這就是Object.equals方法了。但是,如果每增加一個(gè)元素就檢查一次,那么當(dāng)元素很多時(shí),后添加到集合中的元素比較的次數(shù)就非常多了。也就是說(shuō),如果集合中現(xiàn)在已經(jīng)有1000個(gè)元素,那么第1001個(gè)元素加入集合時(shí),它就要調(diào)用1000次equals方法。這顯然會(huì)大大降低效率。 于是,Java采用了哈希表的原理。哈希算法也稱為散列算法,是將數(shù)據(jù)依特定算法直接指定到一個(gè)地址上。初學(xué)者可以這樣理解,hashCode方法實(shí)際上返回的就是對(duì)象存儲(chǔ)的物理地址(實(shí)際可能并不是)。 這樣一來(lái),當(dāng)集合要添加新的元素時(shí),先調(diào)用這個(gè)元素的hashCode方法,就一下子能定位到它應(yīng)該放置的物理位置上。如果這個(gè)位置上沒(méi)有元素,它就可以直接存儲(chǔ)在這個(gè)位置上,不用再進(jìn)行任何比較了;如果這個(gè)位置上已經(jīng)有元素了,就調(diào)用它的equals方法與新元素進(jìn)行比較,相同的話就不存了,不相同就散列其它的地址。所以這里存在一個(gè)沖突解決的問(wèn)題。這樣一來(lái)實(shí)際調(diào)用equals方法的次數(shù)就大大降低了,幾乎只需要一兩次。a) hashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode是用來(lái)在散列存儲(chǔ)結(jié)構(gòu)中確定對(duì)象的存儲(chǔ)地址的;b) 如果兩個(gè)對(duì)象相同,就是適用于equals(java.lang.Object) 方法,那么這兩個(gè)對(duì)象的hashCode一定要相同;c) 如果對(duì)象的equals方法被重寫,那么對(duì)象的hashCode也盡量重寫,并且產(chǎn)生hashCode使用的對(duì)象,一定要和equals方法中使用的一致,否則就會(huì)違反上面提到的第2點(diǎn);d) 兩個(gè)對(duì)象的hashCode相同,并不一定表示兩個(gè)對(duì)象就相同,也就是不一定適用于equals(java.lang.Object) 方法,只能夠說(shuō)明這兩個(gè)對(duì)象在散列存儲(chǔ)結(jié)構(gòu)中,如Hashtable,他們“存放在同一個(gè)籃子里”。 7. ArrayList、LinkedList、Vector的區(qū)別。l List接口下的實(shí)現(xiàn)類:l ArrayList:List 接口的大小可變數(shù)組的實(shí)現(xiàn),實(shí)現(xiàn)了所有可選列表操作,并允許包括 null 在內(nèi)的所有元素。除了實(shí)現(xiàn) List 接口外,此類還提供一些方法來(lái)操作內(nèi)部用來(lái)存儲(chǔ)列表的數(shù)組的大小。(此類大致上等同于 Vector 類,除了此類是不同步的。)size、isEmpty、get、set、iterator 和 listIterator 操作都以固定時(shí)間運(yùn)行。add 操作以分?jǐn)偟墓潭〞r(shí)間 運(yùn)行,也就是說(shuō),添加 n 個(gè)元素需要 O(n) 時(shí)間。其他所有操作都以線性時(shí)間運(yùn)行(大體上講)。與用于 LinkedList 實(shí)現(xiàn)的常數(shù)因子相比,此實(shí)現(xiàn)的常數(shù)因子較低。每個(gè) ArrayList 實(shí)例都有一個(gè)容量。該容量是指用來(lái)存儲(chǔ)列表元素的數(shù)組的大小。它總是至少等于列表的大小。在添加大量元素前,應(yīng)用程序可以使用 ensureCapacity 操作來(lái)增加 ArrayList 實(shí)例的容量。這可以減少遞增式再分配的數(shù)量。此實(shí)現(xiàn)不是同步的。如果多個(gè)線程同時(shí)訪問(wèn)一個(gè) ArrayList 實(shí)例,而其中至少一個(gè)線程從結(jié)構(gòu)上修改了列表,那么它必須 保持外部同步。(這一般通過(guò)對(duì)自然封裝該列表的對(duì)象進(jìn)行同步操作來(lái)完成。如果不存在這樣的對(duì)象,則應(yīng)該使用 Collections.synchronizedList 方法將該列表“包裝”起來(lái)。這最好在創(chuàng)建時(shí)完成,以防止意外對(duì)列表進(jìn)行不同步的訪問(wèn): List list = Collections.synchronizedList(new ArrayList(.);此類的 iterator 和 listIterator 方法返回的迭代器是快速失敗的:在創(chuàng)建迭代器之后,除非通過(guò)迭代器自身的 remove 或 add 方法從結(jié)構(gòu)上對(duì)列表進(jìn)行修改,否則在任何時(shí)間以任何方式對(duì)列表進(jìn)行修改,迭代器都會(huì)拋出 ConcurrentModificationException。因此,面對(duì)并發(fā)的修改,迭代器很快就會(huì)完全失敗,而不是冒著在將來(lái)某個(gè)不確定時(shí)間發(fā)生任意不確定行為的風(fēng)險(xiǎn)。l LinkedList:List 接口的鏈接列表實(shí)現(xiàn)。實(shí)現(xiàn)所有可選的列表操作,并且允許所有元素(包括 null)。除了實(shí)現(xiàn) List 接口外,LinkedList 類還為在列表的開(kāi)頭及結(jié)尾 get、remove 和 insert 元素提供了統(tǒng)一的命名方法。這些操作允許將鏈接列表用作堆棧、隊(duì)列或雙端隊(duì)列。此類實(shí)現(xiàn) Deque 接口,為 add、poll 提供先進(jìn)先出隊(duì)列操作,以及其他堆棧和雙端隊(duì)列操作。所有操作都是按照雙重鏈接列表的需要執(zhí)行的。在列表中編索引的操作將從開(kāi)頭或結(jié)尾遍歷列表(從靠近指定索引的一端)。使用 Collections.synchronizedList 方法將該列表“包裝”起來(lái)。這最好在創(chuàng)建時(shí)完成,以防止意外對(duì)列表進(jìn)行不同步的訪問(wèn): Lis
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度股東借款轉(zhuǎn)增注冊(cè)資本及利潤(rùn)分配調(diào)整合同
- 2025年度電力線路運(yùn)維風(fēng)險(xiǎn)管理與合同
- 2025年度電子產(chǎn)品退貨換貨服務(wù)合同范本
- 二零二五年度航空航天項(xiàng)目三方合同違約責(zé)任說(shuō)明
- 公共安全應(yīng)急救援預(yù)案制定指南
- 數(shù)據(jù)中心運(yùn)維服務(wù)合同及設(shè)備維護(hù)管理?xiàng)l款
- 中學(xué)生數(shù)學(xué)史故事征文
- 產(chǎn)品采購(gòu)及供應(yīng)保障協(xié)議合同
- 企業(yè)信息化建設(shè)實(shí)施細(xì)則
- 企業(yè)資源共享合作協(xié)議書
- 泰州職業(yè)技術(shù)學(xué)院?jiǎn)握小队⒄Z(yǔ)》考試參考題庫(kù)(含答案)
- 《食品衛(wèi)生與安全》課程標(biāo)準(zhǔn)
- 第7課《誰(shuí)是最可愛(ài)的人》公開(kāi)課一等獎(jiǎng)創(chuàng)新教學(xué)設(shè)計(jì)-2
- 骨盆骨折小講課護(hù)理課件
- 2016-2023年江蘇衛(wèi)生健康職業(yè)學(xué)院高職單招(英語(yǔ)/數(shù)學(xué)/語(yǔ)文)筆試歷年考點(diǎn)試題甄選合集含答案解析
- 渣土車司機(jī)安全培訓(xùn)
- 燃?xì)夤鞠琅嘤?xùn)課件
- 成事的時(shí)間管理
- 江西省2023年高等職業(yè)院校單獨(dú)招生考試-江西電力職業(yè)技術(shù)學(xué)院-樣卷
- 汽油安全技術(shù)說(shuō)明書(MSDS)
- 眼球摘除患者的護(hù)理病例討論
評(píng)論
0/150
提交評(píng)論