目錄
String StringBuilder StringBuffer對(duì)比
內(nèi)部類(lèi)和匿名內(nèi)部類(lèi)
抽象類(lèi)的幾個(gè)小問(wèn)題
AssertionError的使用技巧
序列化
Serializable和Parceable對(duì)比
流的類(lèi)型
注解
ThreadLocal
進(jìn)程和線(xiàn)程
Java反射
String StringBuilder StringBuffer對(duì)比
String高帖、StringBuilder和StringBuffer都可以存儲(chǔ)和操作字符串
String會(huì)定義在常量池中则披,不方便進(jìn)行編輯操作芙扎。
StringBuilder和StringBuffer都可以直接操作字符串對(duì)象阳准,但是StringBuilder是單線(xiàn)程環(huán)境集索,沒(méi)有Synchronized同步鎖,不過(guò)效率比StringBuffer高郭厌。
在實(shí)際編碼中钞钙,如果字符串編輯操作較少,可以用+進(jìn)行連接刊侯,如果編輯操作較多章办,一般用StringBuffer,因?yàn)樗С侄嗑€(xiàn)程滨彻,是線(xiàn)程安全的藕届,未來(lái)擴(kuò)展容易。
Tips:string.intern()會(huì)得到對(duì)象在常量池中的引用亭饵。
java中String休偶、StringBuffer、StringBuilder
內(nèi)部類(lèi)和匿名內(nèi)部類(lèi)
內(nèi)部類(lèi)就是在外部類(lèi)里直接定義一個(gè)內(nèi)部類(lèi)
普通的內(nèi)部類(lèi)是一個(gè)語(yǔ)法糖冬骚,編譯后會(huì)把外部類(lèi)的實(shí)例對(duì)象作為參數(shù)椅贱,在構(gòu)造函數(shù)中傳給自己懂算,所以?xún)?nèi)部類(lèi)會(huì)持有外部類(lèi)的引用只冻。
靜態(tài)內(nèi)部類(lèi)直接在方法區(qū)分配內(nèi)存,不再持有外部類(lèi)的引用计技,相應(yīng)的也不能直接調(diào)用外部類(lèi)喜德,需要手動(dòng)引用外部類(lèi)的實(shí)例對(duì)象,為了避免內(nèi)存泄露垮媒,一般用WeakReference去處理外部類(lèi)的對(duì)象舍悯。
匿名內(nèi)部類(lèi)就是new一個(gè)抽象類(lèi)或接口航棱,然后直接在大括號(hào)里實(shí)現(xiàn)方法,然后調(diào)用萌衬,例如常見(jiàn)的thread寫(xiě)法
抽象類(lèi)的幾個(gè)小問(wèn)題
1.抽象類(lèi)是否可以沒(méi)有方法和屬性
一般來(lái)說(shuō)抽象類(lèi)總有方法和屬性給子類(lèi)去擴(kuò)展或使用饮醇,但是如果沒(méi)有方法和屬性也可以,這樣做一般是出于設(shè)計(jì)的角度秕豫,告訴用戶(hù)這個(gè)類(lèi)不能直接實(shí)例化朴艰,用戶(hù)必須自己去實(shí)現(xiàn)一個(gè)它的子類(lèi)。
2.abstrace和static能否共存
不能混移,static表示無(wú)需實(shí)例化即可調(diào)用祠墅,abstract則是必須覆蓋實(shí)現(xiàn),不能直接調(diào)用歌径,沖突
3.abstract和native能否共存
不能毁嗦,native本地方法表示一定有個(gè)實(shí)體來(lái)處理,abstract沒(méi)有實(shí)體回铛,不能處理
4.abstract和synchronized能否共存
不能狗准,synchronized需要鎖一個(gè)能直接調(diào)用的對(duì)象,abstract沒(méi)有實(shí)體對(duì)象茵肃。
AssertionError的使用技巧
我們自己寫(xiě)代碼框架時(shí)驶俊,有些函數(shù)是必須寫(xiě),但是不希望別人調(diào)用的免姿,比如靜態(tài)工具類(lèi)的構(gòu)造函數(shù)饼酿,為了在調(diào)用者寫(xiě)代碼時(shí)就給他提示錯(cuò)誤,我們可以使用throw new AssertionError()胚膊,在構(gòu)造函數(shù)里拋出異常故俐。
這樣就可以避免團(tuán)隊(duì)調(diào)用這個(gè)函數(shù)了。
序列化
序列化是處理對(duì)象流的機(jī)制紊婉,把對(duì)象轉(zhuǎn)為流药版,這樣在讀寫(xiě)、傳輸喻犁、持久化時(shí)方便操作槽片,且可以避免數(shù)據(jù)亂序等問(wèn)題。
Serializable和Parceable對(duì)比
Android序列化有Serializable和Parceable兩種接口肢础,都能實(shí)現(xiàn)序列化
Serializable會(huì)把對(duì)象序列化為字節(jié)流还栓,Parceable則是把對(duì)象分解為Intent能識(shí)別的基本類(lèi)型;
Parceable效率更高更快(一般是10倍传轰,1個(gè)數(shù)量級(jí))
Serializable會(huì)產(chǎn)生大量變量剩盒,需要頻繁GC
Serializable只是一種標(biāo)識(shí)接口,無(wú)需實(shí)現(xiàn)方法(如果有不要序列化的字段慨蛙,用transient修飾)辽聊;Parceable中除了getter和setter之外纪挎,還需要自己寫(xiě)describeContents和writeToParcel方法把數(shù)據(jù)類(lèi)轉(zhuǎn)為Parcel,并實(shí)現(xiàn)一個(gè)Creator<T>實(shí)例對(duì)象跟匆,以實(shí)現(xiàn)createFromParcel把parcel轉(zhuǎn)回?cái)?shù)據(jù)類(lèi)异袄。
Serializable可以網(wǎng)絡(luò)傳輸和持久化保存文件,Parceable則適用于進(jìn)程間通信玛臂。
Parceable不像Serializable通用隙轻,適合在內(nèi)存中保存,難以持久化垢揩。
Tips:序列化除了可以通過(guò)流傳輸和持久化之外玖绿,還可以用于深拷貝。
流的類(lèi)型
對(duì)流的類(lèi)型有三種劃分維度:
按照傳輸方向叁巨,分為輸入流和輸出流
按照數(shù)據(jù)的單位斑匪,分為字節(jié)流和字符流,在java.io包里锋勺,byte字節(jié)流就是InputStream/OutputStream蚀瘸,文字字符流就是Reader和Writer。
按照功能庶橱,分為節(jié)點(diǎn)流和處理流贮勃,節(jié)點(diǎn)流是直接操作文件和網(wǎng)絡(luò)的,直接讀出或?qū)懭胱止?jié)流苏章;處理流是對(duì)已經(jīng)存在的節(jié)點(diǎn)流或處理流進(jìn)行處理的寂嘉,包括緩沖流、轉(zhuǎn)換流枫绅、數(shù)據(jù)流泉孩、對(duì)象流等。
緩沖流如BufferedInputStream提供帶緩沖的讀寫(xiě)
轉(zhuǎn)換流只有InputStreamReader/OutputStreamWriter并淋,用來(lái)套在InputStream/OutputStream外面寓搬,把字節(jié)流轉(zhuǎn)為字符流
數(shù)據(jù)流如DataInputStream提供java的數(shù)據(jù)流讀寫(xiě)功能
對(duì)象流是實(shí)現(xiàn)了Serializable的對(duì)象,可以轉(zhuǎn)換為ObjectInputStream
三個(gè)維度是可以重合的县耽,比如FileReader是輸入流句喷、字符流、節(jié)點(diǎn)流兔毙;BufferedOutputStream是輸出流唾琼、字節(jié)流、處理流瞒御。
流常用兩種設(shè)計(jì)模式:
1.裝飾者模式對(duì)流進(jìn)行擴(kuò)展父叙,比如先用FileOutputStream讀文件,然后用BufferedOutputStream加緩沖肴裙,然后用DataOutputStream讀出文件中的字節(jié)流趾唱。InputStream/OutputStream外面,把字節(jié)流轉(zhuǎn)換為字符流蜻懦。
2.適配器模式把字符流和字節(jié)流進(jìn)行轉(zhuǎn)換甜癞,就是轉(zhuǎn)換流InputStreamReader/OutputStreamWriter。
java IO 流Stream 序列化Serializable 文件File
注解
為Java源程序中的元素關(guān)聯(lián)任何信息或者任何元數(shù)據(jù)宛乃,可以反射獲取注解對(duì)象和注解中的元數(shù)據(jù)悠咱。
注解不可以影響程序代碼的執(zhí)行,java解釋器會(huì)忽略注解征炼。
系統(tǒng)內(nèi)置標(biāo)準(zhǔn)注解
Override Deprecated SurppressWarning
元注解
@Target 注解修飾的對(duì)象的范圍 如ElementType.Field析既、Type
@Rentation 保留時(shí)間的長(zhǎng)短,源代碼\class文件\類(lèi)加載運(yùn)行時(shí)等 RentationPolicy.RUNTIME
@Documented 描述API 沒(méi)有成員
@Inherited 可以被繼承
Android support annotation
從android-19開(kāi)始提供
1.Nulless注解 @NonNull @Nullable
2.ResourceType注解 @StringRes
3.Threading注解 @WorkerThread @UIThread 指定工作的線(xiàn)程
4.OverrideMethods注解 @CallSuper 調(diào)用父類(lèi)的方法
注解的處理
編譯器的插件來(lái)處理注解谆奥,注解的元數(shù)據(jù)放進(jìn)class文件
提供程序之外的信息眼坏,幫助處理數(shù)據(jù),不直接影響代碼
ThreadLocal
ThreadLocal<T>是線(xiàn)程本地變量酸些,僅使用線(xiàn)程自己的內(nèi)存宰译,這樣可以在線(xiàn)程間隔離數(shù)據(jù),不做線(xiàn)程間數(shù)據(jù)同步魄懂,就是說(shuō)同一個(gè)ThreadLocal對(duì)象沿侈,在不同線(xiàn)程中操作,會(huì)分別提供互不干擾的內(nèi)存市栗。
ThreadLocal只有set缀拭、get、remove和initalValue四個(gè)函數(shù)填帽。
ThreadLocal持有一個(gè)threadlocals對(duì)象智厌,指向Thread的ThreadLocalMap,在ThreadLocalMap里key值為T(mén)hreadLocal對(duì)象盲赊,value值為T(mén)的具體值铣鹏。一個(gè)Thread里可以有多個(gè)ThreadLocal對(duì)象。
所以哀蘑,通過(guò)ThreadLocal取值诚卸,其實(shí)就是通過(guò)Thread里的Map去取值,所以?xún)H與當(dāng)前線(xiàn)程有關(guān)绘迁。
Java并發(fā)編程:深入剖析ThreadLocal
進(jìn)程和線(xiàn)程
一個(gè)進(jìn)程內(nèi)存空間一般是2G合溺,一個(gè)線(xiàn)程棧空間的大小一般是1M缀台,這樣算的話(huà)1個(gè)進(jìn)程最多有2048個(gè)線(xiàn)程棠赛。
一個(gè)進(jìn)程可以創(chuàng)建的線(xiàn)程數(shù)由可用虛擬空間和線(xiàn)程的棧的大小共同決定,只要虛擬空間足夠,那么新線(xiàn)程的建立就會(huì)成功睛约。如果需要?jiǎng)?chuàng)建超過(guò)2K以上的線(xiàn)程鼎俘,減小你線(xiàn)程棧的大小就可以實(shí)現(xiàn)了。
Java反射
Java 中的反射首先是能夠獲取到Java 中要反射類(lèi)的字節(jié)碼辩涝, 獲取字節(jié)碼有三種方法贸伐,
1.Class.forName(className)
2.類(lèi)名.class
3.this.getClass()。
然后將字節(jié)碼中的方法怔揩,變量捉邢,構(gòu)造函數(shù)等映射成相應(yīng)的Method、Filed商膊、Constructor 等類(lèi)伏伐,這些類(lèi)提供了豐富的方法可以被我們所使用