国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

《Effective Java》,關(guān)于方法

worldligang / 2068人閱讀

摘要:檢查參數(shù)的有效性每當(dāng)編寫方法或者構(gòu)造器時(shí),應(yīng)該考慮它的參數(shù)有哪些限制。為了保護(hù)實(shí)例的內(nèi)部信息避免受到這種攻擊,對(duì)于構(gòu)造器的每個(gè)可變參數(shù)進(jìn)行保護(hù)性拷貝是必要的,并且使用備份對(duì)象作為實(shí)例的組件,而不是使用原始的對(duì)象。

檢查參數(shù)的有效性

每當(dāng)編寫方法或者構(gòu)造器時(shí),應(yīng)該考慮它的參數(shù)有哪些限制。應(yīng)該把這些限制寫到文檔中,并且在這個(gè)方法體開(kāi)頭處,通過(guò)顯示的檢查來(lái)實(shí)施這些限制。養(yǎng)成這樣的習(xí)慣非常重要。

必要時(shí)進(jìn)行保護(hù)性拷貝
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;
    }
    
    public Date start() {
        return start;
    }
    
    public Date end() {
        return end;
    }

}

因?yàn)镈ate類本身時(shí)可變的,所以,

Date start = new Date();
Date end = new Date();
Period p = new Period(start, end);
end.setYear(78); // 這個(gè)操作把實(shí)例的內(nèi)部信息修改了。

為了保護(hù)Period實(shí)例的內(nèi)部信息避免受到這種攻擊,對(duì)于構(gòu)造器的每個(gè)可變參數(shù)進(jìn)行保護(hù)性拷貝是必要的,并且使用備份對(duì)象作為Period實(shí)例的組件,而不是使用原始的對(duì)象。

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

注意,保護(hù)性拷貝是在檢查參數(shù)的有效性之前進(jìn)行的,并且有效性檢查是針對(duì)拷貝之后的對(duì)象,而不是原始的對(duì)象。

但是改變Period實(shí)例仍然是有可能的,因?yàn)樗脑L問(wèn)方法提供了對(duì)其內(nèi)部成員的訪問(wèn)能力。

Date start = new Date();
Date end = new Date();
Period p = new Period(start, end);
p.end().setYear(78); // 這個(gè)操作把實(shí)例的內(nèi)部信息修改了。

為了防御這第二種攻擊,只需改這兩個(gè)訪問(wèn)方法,使它返回可變內(nèi)部域的保護(hù)性拷貝即可。

public Date start() {
    return new Date(start.getTime());
}

public Date end() {
    return new Date(end.getTime());
}

在內(nèi)部組件被返回給客戶端之前,對(duì)它們進(jìn)行保護(hù)性拷貝也是同樣的道理。

只要有可能,都應(yīng)該使用不可變的對(duì)象作為對(duì)象內(nèi)部的組件,這樣就不必再為保護(hù)性拷貝操心。

如果類具有從客戶端得到或者返回到客戶端的可變組件,類就必須保護(hù)性地拷貝這些組件。
如果拷貝的成本受到限制,并且類信任它的客戶端會(huì)恰當(dāng)?shù)匦薷慕M件,就可以在文檔中指明客戶端的職責(zé)使不得修改受到影響的組件,以此來(lái)代替保護(hù)性拷貝。

謹(jǐn)慎設(shè)計(jì)方法簽名 謹(jǐn)慎地選擇方法的名稱

首要目標(biāo)是選擇易于理解的。

第二目標(biāo)是選擇與大眾認(rèn)可的名稱相一致的名稱。

不要過(guò)于追求提供便利的方法

每個(gè)方法都應(yīng)該盡其所能。方法太多會(huì)使類難以學(xué)習(xí)、使用、文檔化、測(cè)試和維護(hù)。

對(duì)于類和接口所支持的每個(gè)動(dòng)作,都提供一個(gè)功能齊全的方法。

避免過(guò)長(zhǎng)的參數(shù)列表

目標(biāo)是四個(gè)參數(shù),或者更少。

有三種方法可以縮短過(guò)長(zhǎng)的參數(shù)列表。
第一種是把方法分解成多個(gè)方法,每個(gè)方法只需要這些參數(shù)的一個(gè)子集。
第二種是創(chuàng)建輔助類,用來(lái)保存參數(shù)的分組。
第三種是從對(duì)象構(gòu)建到方法調(diào)用都采用Builder模式。

對(duì)于參數(shù)類型,要優(yōu)先使用接口而不是類

如果使用的是類而不是接口,則限制了客戶端只能傳入特定的實(shí)現(xiàn),如果碰巧輸入的數(shù)據(jù)是以其他的形式存在,就會(huì)導(dǎo)致不必要的、可能非常昂貴的拷貝操作。

對(duì)于boolean參數(shù),要優(yōu)先使用兩個(gè)元素的枚舉類型

它是代碼更易于閱讀和編寫,也使以后更易于添加更多的選項(xiàng)。

慎用重載

下面的程序試圖根據(jù)一個(gè)集合是Set、List,還是其他的集合類型來(lái)分類。

public class CollectionClassifier {
    public static String classify(Set set) {
        return "Set";
    }
    
    public static String classify(List list) {
        return "List";
    }
    
    public static String classify(Collection collection) {
        return "Unknow Collection";
    }
    
    public static void main(String[] args) {
        Collection[] collections = {
            new HashSet(),
            new ArrayList(),
            new HashMap().values()
        };
        
        for(Collection collection : collections) {
            System.out.println(classify(collection));
        }
    }
}

可能期望會(huì)打印“Set”,接著是“List”,以及“Unknow Collection”,實(shí)際上不是這樣。而是“Unknow Collection”打印三次。

因?yàn)閏lassify方法被重載(overload)了,而要調(diào)用哪個(gè)重載方法是在編譯時(shí)做出決定的。對(duì)于for循環(huán)中的三次迭代,參數(shù)的編譯時(shí)類型都是相同的,Collection。每次迭代的運(yùn)行時(shí)類型都是不同的,但這并不影響對(duì)重載方法的選擇。因?yàn)樵搮?shù)的編譯時(shí)類型為Collection,所以,唯一合適的重載方法是第三個(gè),classify(Collection),在循環(huán)的每次迭代中,都會(huì)調(diào)用這個(gè)重載方法。

對(duì)于重載方法(overload method)的選擇是靜態(tài)的,而對(duì)于被覆蓋的方法(overriden method)的選擇則是動(dòng)態(tài)的。

選擇被覆蓋的方法的正確版本是在運(yùn)行時(shí)的,選擇的依據(jù)時(shí)被調(diào)用方法所在對(duì)象的運(yùn)行時(shí)類型。

再看看下面這個(gè)程序。

class Wine {
    String name() {
        return "wine";
    }
}

class SparklingWine extends Wine {
    @Override
    String name() {
        return "sparkling wine";
    }
}

class Champagne extends SparklingWine {
    @Override
    String name() {
        return "champagne";
    }
}

public class Overriding {
    public static void main(String[] args) {
        Wine[] wines = {
            new Wine(),
            new SparklingWine(),
            new Champagne()
        };
        
        for(Wine wine : wines) {
            System.out.println(wine.name());
        }
    }
}

這個(gè)程序打印“wine”、“sparkling wine”和“champagne”。

可以對(duì)第一個(gè)程序修改一下,用單個(gè)方法替換三個(gè)重載的classify方法,如下。

public static String classify(Collection collection) {
    return collection instanceof Set ? "Set" :
           collection instanceof List ? "List" : "Unknow Collection";
}

因?yàn)楦采w機(jī)制時(shí)規(guī)范,而重載機(jī)制是例外。

到底怎樣才算是胡亂使用重載機(jī)制呢?這個(gè)問(wèn)題仍有爭(zhēng)議。安全而保守的策略是,永遠(yuǎn)不要導(dǎo)出兩個(gè)具有相同參數(shù)數(shù)目的重載方法。

慎用可變參數(shù)

Java 1.5發(fā)行版本中增加了可變參數(shù)方法,一般稱作variable arity method(可匹配不同長(zhǎng)度的變量方法)[JLS,8.4.1]。

可變參數(shù)方法接受零個(gè)或者多個(gè)指定類型的參數(shù)。可變參數(shù)機(jī)制通過(guò)先創(chuàng)建一個(gè)數(shù)組,數(shù)組的大小為在調(diào)用位置所傳遞的參數(shù)數(shù)量,然后將參數(shù)值傳到數(shù)組中,最后將數(shù)組傳遞給方法。

static int sum(int... args) {
    int sum = 0;
    for (int arg : args) {
        sum += arg;
    }
    return sum;
}

當(dāng)真正需要讓一個(gè)方法帶有不定數(shù)量的參數(shù)時(shí),可變參數(shù)就非常有效。可變參數(shù)是為printf而設(shè)計(jì)的。printf和反射機(jī)制都從可變參數(shù)中極大地受益。

在重視性能地情況下,需要小心。可變參數(shù)方法的每次調(diào)用都會(huì)導(dǎo)致進(jìn)行一次數(shù)組分配和初始化。

需要可變參數(shù)的靈活性,但又無(wú)法承受性能成本,可以這么做。

public void foo() {}
public void foo(int a1) {}
public void foo(int a1, int a2) {}
public void foo(int a1, int a2, int a3) {}
public void foo(int a1, int a2, int a3, int... rest) {}

在定義參數(shù)數(shù)目不定的方法時(shí),可變參數(shù)方法是一種很方便的方式,但是不應(yīng)該被過(guò)度濫用。如果使用不當(dāng),會(huì)產(chǎn)生混亂的結(jié)果。

返回零長(zhǎng)度的數(shù)組或者集合,而不是null

對(duì)于一個(gè)返回null而不是零長(zhǎng)度數(shù)組或者集合的方法,幾乎每次調(diào)用該方法都需要曲折的處理方式。這樣很容易出錯(cuò),因?yàn)榫帉懣蛻舳顺绦虻某绦騿T可能會(huì)忘記寫專門的代碼來(lái)處理null返回值。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/70055.html

相關(guān)文章

  • Effective Java》,關(guān)于異常

    摘要:只針對(duì)異常的情況才使用異常下面展示兩種遍歷數(shù)組元素的實(shí)現(xiàn)方式。第一種方式在訪問(wèn)數(shù)組邊界之外的第一個(gè)數(shù)組元素時(shí),用拋出捕獲忽略異常的手段來(lái)達(dá)到終止無(wú)限循環(huán)的目的。這種做法被稱為異常轉(zhuǎn)譯。 只針對(duì)異常的情況才使用異常 下面展示兩種遍歷數(shù)組元素的實(shí)現(xiàn)方式。 try { int i = 0; while(true) range[i++].climb(); } c...

    CoorChice 評(píng)論0 收藏0
  • 學(xué)習(xí)Java必讀的10本書籍

    摘要:學(xué)習(xí)編程的本最佳書籍這些書涵蓋了各個(gè)領(lǐng)域,包括核心基礎(chǔ)知識(shí),集合框架,多線程和并發(fā),內(nèi)部和性能調(diào)優(yōu),設(shè)計(jì)模式等。擅長(zhǎng)解釋錯(cuò)誤及錯(cuò)誤的原因以及如何解決簡(jiǎn)而言之,這是學(xué)習(xí)中并發(fā)和多線程的最佳書籍之一。 showImg(https://segmentfault.com/img/remote/1460000018913016); 來(lái)源 | 愿碼(ChainDesk.CN)內(nèi)容編輯 愿碼Slo...

    masturbator 評(píng)論0 收藏0
  • Java 高效編程(Effective Java)中文第三版

    摘要:來(lái)源前條來(lái)源一書英文版已經(jīng)出版,這本書的第二版想必很多人都讀過(guò),號(hào)稱四大名著之一,不過(guò)第二版年出版,到現(xiàn)在已經(jīng)將近年的時(shí)間,但隨著,,,甚至的發(fā)布,語(yǔ)言發(fā)生了深刻的變化。譯者在這里第一時(shí)間翻譯成中文版。供大家學(xué)習(xí)分享之用。 來(lái)源:sjsdfg/effective-java-3rd-chinese前 51 條來(lái)源:Effective Java, Third Edition 《Effec...

    ysl_unh 評(píng)論0 收藏0
  • effective java 觀后感

    摘要:這本書是我第一次買的,從買來(lái)至今整本書還沒(méi)有看完,只看了一半,原因是個(gè)人比較懶,而且玩的心比較大,經(jīng)過(guò)這么多年的沉淀,終于可以偷點(diǎn)時(shí)間寫下對(duì)于這本書的觀后感了整本書給我的感覺(jué)不像是一個(gè)技術(shù)書,更多的是講解一些實(shí)用技巧,而對(duì)于我這個(gè)職場(chǎng)菜鳥來(lái) effective Java 這本書是我第一次買的, 從買來(lái)至今整本書還沒(méi)有看完, 只看了一半, 原因是個(gè)人比較懶,而且玩的心比較大,經(jīng)過(guò)這么多年...

    calx 評(píng)論0 收藏0
  • Java 學(xué)習(xí)資料總結(jié)

    摘要:三進(jìn)階階段這個(gè)階段主要是靠我們自己學(xué)習(xí)總結(jié),可以通過(guò)前輩們的博客或者自己研究源碼,這些非常有利于我們快速的成長(zhǎng)。讓自己保持永遠(yuǎn)學(xué)習(xí)的精神。五零基礎(chǔ)學(xué)習(xí)資料最后給大家準(zhǔn)備了一份不錯(cuò)的學(xué)習(xí)資源,里面有很多學(xué)習(xí)視頻和資料,后臺(tái)回復(fù)資源,即可獲取。 showImg(https://segmentfault.com/img/bVbauV8?w=1212&h=816); 前兩次給大家分享了關(guān)于 j...

    FleyX 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<