欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Effective Java
第一條:
內容:靜態(tài)工廠(chǎng)替代構造函數
例子:String.valueOf()   getInstance()等
靜態(tài)工廠(chǎng)方法優(yōu)點(diǎn):
1,可以隨意起名字,更好的描述返回對象
2,每次調用的時(shí)候不一定要創(chuàng )建一個(gè)新對象
3,可以返回一個(gè)原返回類(lèi)型的子類(lèi)型對象
靜態(tài)工廠(chǎng)方法的缺點(diǎn):
1,如果類(lèi)沒(méi)有公有或者受保護的構造函數就不能被子類(lèi)化
2,不符合規范,破壞規范。在A(yíng)PI文檔中不會(huì )被那么明確的標識出來(lái)。

第二條:使用私有構造函數強化單態(tài)
單態(tài)的模式大家都知道了,但是使用單態(tài)的時(shí)候記住要使用私有的構造函數。
原因很簡(jiǎn)單,如果不如此很難保證單態(tài)。只要new一下另一個(gè)對象就生成了

第三條:有些類(lèi)是不能實(shí)例化的,如果你要做到這點(diǎn),記得使用私有的構造函數。
例如:java.util.Collections        java.lang.Math 等

第四條:避免創(chuàng )造重復的對象
特別是這樣的代碼不要寫(xiě): String str = new String("a string");
因為這樣每次執行的時(shí)候都創(chuàng )建了一個(gè)"a string"對象。
可以寫(xiě)成這樣:String str = "a string ";
另外順便說(shuō)一句,這個(gè)時(shí)候你再次定義String  str2 = "a string";會(huì )復用上邊的字符串.

第五條:在有些情況下手動(dòng)消除對象的引用
public class Stack{
    
private Object[] elements;
    
private int size = 0;
    
public Stack(int initialCapacity){
        
this.elements = new Object[initialCapacity];
    }

    
public void push(Object e){
        ensureCapacity();
        elements[size
++= e;
    }

    
public Object pop(){
        
if (size == 0)
            
throw new EmptyStackException();
        
return elements[--size];
    }

    
private void ensureCapacity(){
        
if (elements.length == size){
            Object[] oldElements 
= elements;
            elements 
= new Object[2*element.length+1];
        System.arraycopy(oldElements,
0,elements,0,size);
        }

    }

}
如果這個(gè)Stack先大量增長(cháng),然后收縮,然后在比較小的范圍內使用,必定造成大量的不可回收的對象,造成內存泄漏.。
解決辦法:改造一下pop()方法
public Object pop(){
       
if(size = = 0)
           
throw new EmptyStackException();
        Object result 
= elements[--size];
                 //加上這一句
        elements.[size]
=null;
        
return result;
}

六,避免使用終結(finalizer)函數
原因:終結函數通常是不可預測的,一般情況下不要使用,使用的結果會(huì )帶來(lái)很多問(wèn)題,不穩定,性能差,移植問(wèn)題等等。
分析原因:
1,從一個(gè)對象不可到達到它的終結函數被執行,這段時(shí)間是任意的,不確定的,所以時(shí)間關(guān)鍵的系統不應該使用終結函數。
2,及時(shí)的執行終結函數是垃圾回收算法決定的,這種算法在不同的JVM實(shí)現中會(huì )大相徑庭,使用終結函數的結果就是導致移植性問(wèn)題
3,如果執行終結函數的線(xiàn)程一直低于當前的線(xiàn)程的優(yōu)先級,很可能造成占用大量?jì)却?,極端情況是出現OutOfMemoryError
4,JSL不保證終結函數一定被執行,所以不要依賴(lài)終結函數來(lái)更新關(guān)鍵性的永久狀態(tài),例如數據庫的永久鎖
5,不要相信System.gc()    System.runFinalization這兩個(gè)函數,它們只能提高終結函數的執行機會(huì ),并不保證一定執行。唯一保證一定執行的是System.runFinalizersOnExit喝Runtime.runFinalizersONExit()但這兩個(gè)方法已經(jīng)被聲明不建議使用.
6,一個(gè)在終結函數中的一場(chǎng)不會(huì )打出任何信息
七:在改寫(xiě)equals方法的時(shí)候遵守通用約定
分析:
1,有些情況下不要隨意改寫(xiě)equals
(1),一個(gè)類(lèi)的每個(gè)實(shí)例本質(zhì)上是唯一的,例如Thread
(2),不管新一個(gè)類(lèi)是否提供了“邏輯相等”的測試功能,例如java.util.Random
(3),超類(lèi)已經(jīng)改寫(xiě)了equals,從超類(lèi)繼承過(guò)來(lái)的行為對于子類(lèi)也是適合的 例如Set從AbstractSet繼承了equals
(4),一個(gè)類(lèi)是私有的,或者是包級私有的,并且確定它的equals方法永遠不會(huì )被調用
2, 通用的約定
自反性:  對于任意的引用值x ,x.equals(x)一定為true
對稱(chēng)性:  對于任意的引用值x,y  x.equals(y)返回true是 y.equals(x)也一定返回true
傳遞性:對于任意的引用值x,y,z  如果x.equals(y)返回true 并且y.equals(z)返回true 那么 x.equals(z)也一定是true
一致性:對于任意的x,y如果x,y沒(méi)有被更改,調用任意多次x.equals(y)返回的結果應該一樣。
非空性:對任意的引用x ,x.equals(null)一定返回false
3不要將equals聲明中的Object對象換成別的類(lèi)型
4,不要讓equals方法依賴(lài)不可靠資源
八:改寫(xiě)equals方法時(shí)總要改寫(xiě)hashCode
原因:來(lái)自java.lang.Object關(guān)于hashCode的規范
1,在一個(gè)應用執行期間,如果一個(gè)對象的equals方法比較所用到的信息沒(méi)有修改的話(huà),那么對該對象調用hashCode多次,比如如一的返回同一個(gè)數
2,如果兩個(gè)對象的equals方法返回true,那么分別調用hashCode方法返回的值應該相等
3,在兩個(gè)兌現的equals方法返回false時(shí),盡可能的讓hashCode方法返回的值不相等,提高散列表的性能
分析:如果改寫(xiě)了equals沒(méi)有改寫(xiě)hashCode在使用map等集合類(lèi)的時(shí)候會(huì )出現問(wèn)題。
九:盡可能的改寫(xiě)toString方法,并在顯示內容中盡可能的包括令人感興趣的信息。并且在注釋中表示出你的意圖。
十:謹慎的改寫(xiě)clone方法,改寫(xiě)前考慮淺拷貝和全拷貝
十一:考慮實(shí)現Comparable接口,如果你的對象要排序,那么記得實(shí)現這個(gè)方法
十二:使類(lèi)和成員的可訪(fǎng)問(wèn)能力最小化,
十三:支持非可變性
非可變性遵循以下的原則:
1,不提供任何改變對象的方法
2,保證沒(méi)有可被子類(lèi)改寫(xiě)的方法
3,保證所有的域都使final
4,使所有的域都成為私有的
5,保證任何可變組件互斥訪(fǎng)問(wèn)
6,非可變對象本質(zhì)是線(xiàn)程安全的,不需要同步

十四:復合優(yōu)于繼承(Think in java中有不少說(shuō)明)
十五:要們專(zhuān)門(mén)為繼承而設計,并給出文檔說(shuō)明,要么禁止繼承
十六:接口優(yōu)于抽象類(lèi)(參考一下GOF的設計模式)
十七:接口只是被定義類(lèi)型,不要試圖使用常量接口
十八:優(yōu)先考慮靜態(tài)成員類(lèi)
說(shuō)明:嵌套類(lèi)有四種
靜態(tài)成員類(lèi) , 非靜態(tài)成員類(lèi),   匿名類(lèi),  局部類(lèi)  除了第一種之外,其它三種都被稱(chēng)為內部類(lèi)
1,靜態(tài)成員類(lèi)是一種最簡(jiǎn)單的嵌套類(lèi),最好把它看成一個(gè)普通類(lèi),只是碰巧被聲明在另一個(gè)類(lèi)內部而已,
它可以訪(fǎng)問(wèn)外圍類(lèi)的所有成員,包括那些生民為私有的成員。靜態(tài)成員類(lèi)是外圍類(lèi)的一個(gè)靜態(tài)成員,也遵守同樣的可訪(fǎng)問(wèn)性規則,如果它被聲明為私有的,那么它只能在外圍類(lèi)內部可以訪(fǎng)問(wèn)。靜態(tài)成員類(lèi)的一個(gè)用法是公有的輔助類(lèi)。例如HashMap的  static class Entry

非靜態(tài)成員類(lèi)和靜態(tài)成員類(lèi)的區別主要是非靜態(tài)成員類(lèi)需要一個(gè)外圍類(lèi)實(shí)例的引用,如果你不需要訪(fǎng)問(wèn)外圍類(lèi)的實(shí)例的話(huà),記得使用靜態(tài)成員類(lèi)。

匿名類(lèi)被使用的相對多一些,但是大量的使用匿名類(lèi)會(huì )讓你的代碼比較亂,作過(guò)GUI開(kāi)發(fā)的人多會(huì )有所感觸。并且記住,盡可能的讓你的匿名類(lèi)短小。

局部類(lèi),局部類(lèi)的使用是最少的,很少會(huì )使用到這個(gè),如果用到記得使局部類(lèi)盡可能的短小

對于C語(yǔ)言用戶(hù)的部分
十九:用類(lèi)代替結構
二十:用類(lèi)層次代替聯(lián)合
二十一:用類(lèi)來(lái)代替enum,但是在jdk1.5的時(shí)候提供了enum的支持,有些東西不一樣了
二十二:用類(lèi)和接口代替函數指針

二十三、在函數的開(kāi)始檢查參數的有效性
如果函數對參數有要求,例如不接受Null ,不接受負數等等,應該盡可能在函數的最開(kāi)始給出校驗,如果發(fā)現錯誤拋出異常
二十四、在需要的時(shí)候使用保護性拷貝
1,假設類(lèi)的客戶(hù)會(huì )盡一切手段來(lái)破壞這個(gè)類(lèi)的約束條件,在這樣的前提下,你必須保護性的設計程序。
2,實(shí)例

import java.util.Date;

public final class Period {
    
private final Date start;
    
private final Date end;
    
public Period(Date start,Date end){
        
if (start.compareTo(end)>0){
            
throw new IllegalArgumentException(start+"after"+end);
        }

        
this.start = start;
        
this.end = end;
    }

    
//.other code
}

//這個(gè)函數看似沒(méi)有問(wèn)題,實(shí)際上存在著(zhù)漏洞,如下使用方法
Date start = new Date();
Date end 
= new Date();
Period p 
= new Period(start,end);
//如果加上這句,檢驗就失效了。
end.setYear(78);

//為了對應這個(gè)問(wèn)題,更改構造函數:

public Period(Date start,Date end){
    
this.start = new Date(start.getTime());
    
this.end = new Date(end.getTime());
    
if (start.compareTo(end)>0){
        
throw new IllegalArgumentException(start+"after"+end);
    }

}

注意,拷貝要在檢驗之前進(jìn)行
3,參數類(lèi)型可以被不可信任方子類(lèi)化的情形,清不要使用clone方法進(jìn)行參數的保護化拷貝
二十五、謹慎的設計方法的原型
1,謹慎的選擇方法的名字,一個(gè)好的方法名字可以讓人很快記住
2,不要過(guò)于追求提供便利的方法,如果方法太多會(huì )增加使用者的學(xué)習負擔,只有當一個(gè)操作被頻繁使用的時(shí)候再添加一個(gè)對應的方法。
3,避免太長(cháng)的參數列表,盡量讓你的參數不大于三個(gè)
4,對于參數類(lèi)型,優(yōu)先使用接口,而不是類(lèi)。
原因:如果使用接口,你可以隨意的替換實(shí)現,或者同時(shí)存在多個(gè)實(shí)現。
使用類(lèi)沒(méi)有這個(gè)優(yōu)勢。
5,謹慎的使用函數對象(一個(gè)類(lèi)中一堆靜態(tài)函數)
二十六、謹慎的使用重載
1,實(shí)例

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


public class CollectionClassifier {
    
public static String classify(Set s){
        
return "Set";
    }

    
public static String classify(List s){
        
return "List";
    }

    
public static String classify(Collection s){
        
return "Unknow Collection";
    }

    
    
public static void main(String[] args) {
        Collection[] tests 
= new Collection[]{
            
new HashSet(),
            
new ArrayList(),
            
new HashMap().values()
        }
;
        
for(int i=0;i<tests.length;i++){
            System.out.println(classify(tests[i]));
        }

    }

}

結果是打印出三個(gè)unknown
這個(gè)程序的行為是違反直覺(jué)的,對弈重載方法的選擇是靜態(tài)的,而對于被改寫(xiě)的方法的選擇是動(dòng)態(tài)的
(這個(gè)可以參考我的另一篇文章)
2,盡量不要使用兩個(gè)參數數目相同的重載方法

二十七、使用零長(cháng)度數組代替Null作為返回值
原因:返回Null會(huì )造成使用者每次使用的時(shí)候都要作一次判斷,但有人會(huì )說(shuō)返回一個(gè)零長(cháng)度數組會(huì )產(chǎn)生new的開(kāi)銷(xiāo),不如Null性能好。這個(gè)不是一定的,因為我們可以這樣來(lái)作
private final static Cheese[]  NULL_CHESE_ARRAY = new Cheese[0];
每次需要的時(shí)候返回這個(gè)數組就好了。

二十八、為所有的導出Api元素編寫(xiě)文檔注釋
二十九、使一個(gè)局部變量的作用域最小化,最好的辦法使在第一次使用的時(shí)候聲明
1,幾乎每一個(gè)局部變量的聲明都應該包含一個(gè)初始化表達式,如果你還沒(méi)有足夠的信息來(lái)初始化那就推遲聲明。
2,for循環(huán)優(yōu)先于while循環(huán),見(jiàn)下邊的例子

//        for循環(huán)
        for(Iterator ie = list.iterator();ie.hasNext()){
            doSomething(ie.next());
        }

//        while循環(huán)
        
        Iterator ie1 
= list1.iterator();
        
while(ie1.hasNext()){
            doSomething(ie1.next());
        }

        Iterator ie2 
= list2.iterator();
        
while(ie1.hasNext()){     //bug
            doSomething(ie2.next());
        }

這個(gè)問(wèn)題源于復制粘貼,在編碼的過(guò)程中復制粘貼幾乎是不可避免的,使用for循環(huán)當你出錯的時(shí)候可以在編譯器發(fā)生錯誤,而使用while則不會(huì )發(fā)現。盡早發(fā)現錯誤總是好的。
三十、了解和使用庫(產(chǎn)生隨機數)
詳細:如果你希望產(chǎn)生一個(gè)位于0-某個(gè)上界的隨機數,大多數的人的寫(xiě)法如下

static Random rnd = new Random();
    
static int random(int n){
        
return Math.abs(rnd.nextInt())%n;
    }

這個(gè)方法存在三個(gè)缺點(diǎn):
缺點(diǎn)一:
如果n是一個(gè)比較小的2的乘方 那么經(jīng)過(guò)一段相當短的周期后它產(chǎn)生的隨即數序列將會(huì )重復
缺點(diǎn)二:
如果n不是2的乘方,那么平均起來(lái)某些數比另外一些數出現的更為頻繁,如果n比較大則這個(gè)問(wèn)題更加顯著(zhù)如果產(chǎn)生100萬(wàn)范圍內的隨機數,你會(huì )發(fā)現數字幾乎全部在0-666 666 ,前2/3的數字
缺點(diǎn)三:
在有些情況下會(huì )災難性失敗,返回一個(gè)落在范圍之外的數字。原因是使用了Math.abs來(lái)得到一個(gè)非負數。
如果nextInt()返回 Integer.MIN_VALUE,那么abs后也會(huì )返回Integer.MIN_VALUE ,假設n不是2的乘方,那么取模操作符%將返回一個(gè)負數,這幾乎肯定造成你的程序失敗,而且這個(gè)失敗很難重現。

為了編寫(xiě)一個(gè)避免上邊三個(gè)缺點(diǎn)的random,你必須了解線(xiàn)性同于偽隨機發(fā)生器、數論、和2的求補運算知識。不過(guò)Jdk已經(jīng)實(shí)現了一個(gè)現成的可以使用,那就是Random.nextInt(int)

這一段很多比較簡(jiǎn)單,簡(jiǎn)單羅列一下,部分重要的做了解釋
三十一、如果要求精確的答案,盡量避免使用float 和double,這個(gè)可以參照我的一片文章
貨幣尤其不合適??梢允褂肂igDecimal代替
三十二、如果其它類(lèi)型更適合,盡量避免使用字符串
1,字符串不能替代其它的值類(lèi)型
2,字符串不適合代替枚舉類(lèi)型
3,字符串不適合代替聚集類(lèi)型
4,字符串也不是和代替能力表
因為有些時(shí)候,使用字符串會(huì )大大降低性能
三十三、了解字符串連接的性能
說(shuō)明:使用StringBuffer代替 +來(lái)連接字符串
三十四、通過(guò)接口來(lái)引用對象,這能讓你的程序更加靈活
三十五、接口優(yōu)先于反射。
使用反射會(huì )帶來(lái)很多問(wèn)題,例如:
1,不能編譯期發(fā)現錯誤
2,代碼混亂
3,調試困難
4,性能損失。
除非必須,否則不使用反射
三十六、謹慎的使用本地方法JNI
三十七、謹慎的進(jìn)行優(yōu)化,有三條優(yōu)化格言:
1,很多計算上的過(guò)失都被歸咎于效率原因(沒(méi)有獲得必要的效率),而不是其它的原因--甚至包括盲目的作傻事.   ---William A.Wulf [Wulf72]
2,不要去計較一些小的效率上的得失,在97%的情況下,不成熟的優(yōu)化是一切問(wèn)題的根源。
            ------Donald E.Knuth[Knuth74]
3,在優(yōu)化方面要遵守兩個(gè)原則:
規則一:不要做優(yōu)化
規則二:還是不要做優(yōu)化--也就是說(shuō),在你還沒(méi)有絕對清晰的未優(yōu)化方案前,請不要優(yōu)化。
            -----M.A.Jackson[Jackson75]
每次試圖做優(yōu)化之前和之后請對性能進(jìn)行測試
三十八:遵守普遍接受的命名規則
三十九:值針對不正常的條件才使用異常,也就是說(shuō)不要在正常的情況下使用異常來(lái)控制流程,活著(zhù)解決某些已知的問(wèn)題。因為會(huì )大量的損失性能
四十、對于可恢復的條件使用被檢查的異常,對于程序錯誤使用運行時(shí)異常
詳細:Java提供了三種可拋出結構,checked Exception,  run-time exception , error
什么時(shí)候使用什么很容易讓人混淆,下邊是一個(gè)簡(jiǎn)單的區分原則
1,如果期望調用者能夠恢復,那么對于這樣的條件應該使用被檢查異常
2,你所實(shí)現的所有未檢查的拋出結構都是run time exception ,而不是Error
四十一:避免不必要的使用被檢查異常
四十二:盡可能的使用標準異常,例如IllegalArgumentException ,NullPointerException ,IndexOutOfBoundsException等等
四十三:拋出異常要適合于相應的抽象。
高層實(shí)現應該捕獲異常,同時(shí)拋出一個(gè)可以按照高層抽象解釋的異常(業(yè)務(wù)邏輯上符合高層邏輯),這種做法叫做異常轉譯
四十四:每個(gè)方法拋出的異常都應改有文檔
四十五:在細節消息中包含失?。东@信息
詳細:在異常字符串中應包含有用的信息,例如IndexOutOfBoundsException異常的細節消息應該包括下界、上界以及沒(méi)有落在其中的實(shí)際下標

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Effective Java 筆記(三)
Java面試題集(1-50)
Java經(jīng)典面試題答案解析(1-80題)
Comparator用法總結 - ★yesjoy★ - BlogJava
【讀書(shū)筆記】《寫(xiě)給大忙人看的Java SE 8》
JAVA核心技術(shù)學(xué)習筆記| 備考
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久