我將文章拆成了兩部分季二,繼續(xù)來(lái)寫(xiě)Effective Java中的內(nèi)容。
有效的檢驗(yàn)參數(shù),如果參數(shù)調(diào)用錯(cuò)誤琳疏,則拋出異常粪般,常用的異常包括:
IllegalArgumentException / IndexOutofBoundsException / NullPointException
避免參數(shù)過(guò)多拼余,可以通過(guò)檢查輔助類(lèi),可以配合builder模式使用亩歹。
在Java中匙监,程序是靜態(tài)多分派,動(dòng)態(tài)單分派的小作。
能夠重載不意味著應(yīng)該重載亭姥。
可變參數(shù)的設(shè)計(jì),應(yīng)該至少保證有一個(gè)參數(shù)顾稀,應(yīng)該不傳參數(shù)會(huì)導(dǎo)致程序報(bào)錯(cuò)达罗。
函數(shù)的返回值不應(yīng)該是null,返回零長(zhǎng)度的數(shù)組或者集合静秆。
使程序局部變量作用域最小化粮揉,不要過(guò)早聲明巡李。
基本類(lèi)型優(yōu)于裝箱基本類(lèi)型,裝箱類(lèi)型的非功能值null會(huì)增加很多編程心智負(fù)擔(dān)滔蝉,在集合類(lèi)中應(yīng)該使用裝箱類(lèi)型击儡。
StringBuilder連接字符串優(yōu)于字符串拼接,優(yōu)于StringBuffer.
通過(guò)接口引用對(duì)象蝠引,使用接口類(lèi)型作為參數(shù)阳谍,可以讓程序更加靈活。
盡可能的避免使用反射螃概,反射的問(wèn)題:
1. 喪失了編譯時(shí)的類(lèi)型檢查矫夯。
2. 執(zhí)行反射的代碼冗長(zhǎng)。
3. 反射性能較差吊洼。
不要將異常用于控制流训貌,對(duì)可恢復(fù)的情況使用受檢異常,避免不必要的受檢異常冒窍,例如null
雖然Java支持異常鏈轉(zhuǎn)譯递沪,但是低層和高層還是應(yīng)該可能的隔離開(kāi),如果低層能處理掉那么自己處理掉異常综液。
并發(fā)
synchronized可以保證在同一時(shí)刻款慨,只有一個(gè)線程可以執(zhí)行某一個(gè)方法或者代碼塊。
volatile不執(zhí)行互斥訪問(wèn)谬莹,但是可以保證每一個(gè)線程在讀取該域獲取的都是最新的值檩奠。
增量操作符++不是原子的,首先讀取舊值附帽,然后寫(xiě)回新值埠戳,在這個(gè)過(guò)程中間可能會(huì)出現(xiàn)問(wèn)題,需要借助synchronized同步蕉扮。
synchronized可能會(huì)造成死鎖整胃,要盡量限制內(nèi)部區(qū)域內(nèi)部的工作量。
線程池Executor
ExecutorSerivce executor= Executors.newSingleThreadExecutor();
executor.execute(runnable);
executor.shudown();
同步器 Synchronizer是一些使線程能夠等待另一個(gè)線程的對(duì)象慢显,允許他們協(xié)調(diào)工作
常用的有:CountDownLatch和Semaphore
不常用的有:CyclicBarrier和Exchanger
倒計(jì)數(shù)鎖存器是一次性障礙CountDownLatch爪模,一個(gè)使用場(chǎng)景就是Spring異步初始化,加快啟動(dòng)速度荚藻。
線程安全的級(jí)別:
1. 不可變的屋灌,不需要同步。
2. 無(wú)條件的線程安全应狱,這個(gè)類(lèi)有內(nèi)部同步共郭,可以無(wú)條件的被并發(fā)使用。
3. 有條件的線程安全,例如Collections.synchronized包裝返回的集合除嘹,它們的迭代器需要外部同步写半。
4. 非線程安全,比如ArrayList和HashMap尉咕,需要自己外部同步叠蝇。
5. 線程對(duì)立的,外部同步也不能保證線程安全年缎。
延遲初始化:
對(duì)于實(shí)例域悔捶,使用雙重檢查模式
對(duì)于靜態(tài)域,使用lazy initalization holder class idiom
對(duì)于可以接受重復(fù)初始化的實(shí)例域单芜,可以考慮單重檢查模式
這里一些內(nèi)容寫(xiě)的太粗蜕该,需要細(xì)化。