Item 15: Minimize mutability

不可變類是其實例不能被修改的類
比如String、基本數(shù)據(jù)類型的包裝類(String的基本數(shù)據(jù)類型就是String)律姨、BigIntegerBigDecimal臼疫。

要使一個類變成不可變的择份,要遵守下面的規(guī)則:

  1. 不提供任何修改對象狀態(tài)的方法。比如setter getter中的setter(也稱作mutator)就不能提供烫堤。

  2. 保證類不被擴展荣赶。通常用finla class實現(xiàn)(也可以用private構造函數(shù)的方法,也就是靜態(tài)工廠方法里提到的)鸽斟。

  3. 所有的fileds都設成私有的拔创、final的。

4富蓄、 Ensure exclusive access(互斥訪問) to any mutable components.

下面貼一段很長的代碼剩燥,是一個復數(shù)運算的類:

public final class Complex {
    private final double re;
    private final double im;

    public Complex(double re, double im) {
        this.re = re;
        this.im = im;
    }

    // Accessors with no corresponding mutators
    public double realPart() {
        return re;
    }

    public double imaginaryPart() {
        return im;
    }

    public Complex add(Complex c) {
        return new Complex(re + c.re, im + c.im);
    }

    public Complex subtract(Complex c) {
        return new Complex(re - c.re, im - c.im);
    }

    public Complex multiply(Complex c) {
        return new Complex(re * c.re - im * c.im,
                re * c.im + im * c.re);
    }

    public Complex divide(Complex c) {
        double tmp = c.re * c.re + c.im * c.im;
        return new Complex((re * c.re + im * c.im) / tmp,
                (im * c.re - re * c.im) / tmp);
    }

    @Override
    public boolean equals(Object o) {
        if (o == this)
            return true;
        if (!(o instanceof Complex))
            return false;
        Complex c = (Complex) o;
// See page 43 to find out why we use compare instead of ==
        return Double.compare(re, c.re) == 0 &&
                Double.compare(im, c.im) == 0;
    }

    @Override
    public int hashCode() {
        int result = 17 + hashDouble(re);
        result = 31 * result + hashDouble(im);
        return result;
    }

    private int hashDouble(double val) {
        long longBits = Double.doubleToLongBits(re);
        return (int) (longBits ^ (longBits >>> 32));
    }

    @Override
    public String toString() {
        return "(" + re + " + " + im + "i)";
    }
}

可以看到這個類符合了上面列出來的要求。有個特點,每次計算完成之后都new一個實例灭红,而不是修改傳進來的侣滩。不可變類可以只有一種狀態(tài),就是創(chuàng)建時的狀態(tài)变擒。

不可變類天生就是線程安全的君珠,不要求同步。多個線程并發(fā)訪問的時候不會遭到破壞娇斑。所以可以被自由地共享策添。所以你根本不需要給不可變類提供拷貝構造器

堅決不要為每個getter都配置一個setter毫缆。除非有很好的理由讓類變成可變的唯竹,不然他就應該是不可變的。

缺點

不可變類唯一的缺點是悔醋,對于每一個類不同的值都需要一個但對的對象鸟雏。比如要創(chuàng)建幾百萬個BigInteger鲤脏。

BONUS:

我一直疑惑為什么String可以用=來初始化,而不用new蹋半;后來想了想鹦聪,因為String是符合類型呀账阻,它的基本數(shù)據(jù)類型和包裝數(shù)據(jù)類型都是String。
引用

String password="ok";利用到了字符串緩沖池泽本,也就是說如果緩沖池中已經(jīng)存在了相同的字符串淘太,就不會產(chǎn)生新的對象,而直接返回緩沖池中的字符串對象的引用规丽。
如:
String a = "ok";
String b = "ok";
String c = new String("ok");
String d = new String("ok");
System.out.println(a==b);//將輸出"true";因為兩個變量指向同一個對象蒲牧。
System.out.println(c==d);//將輸出"flase";因為兩個變量不指向同一個對象。雖然值相同赌莺,只有用c.equals(d)才能返回true.

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末冰抢,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子艘狭,更是在濱河造成了極大的恐慌挎扰,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件巢音,死亡現(xiàn)場離奇詭異遵倦,居然都是意外死亡,警方通過查閱死者的電腦和手機官撼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門梧躺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人傲绣,你說我怎么就攤上這事掠哥〖辏” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵龙致,是天一觀的道長蛀缝。 經(jīng)常有香客問我,道長目代,這世上最難降的妖魔是什么屈梁? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮榛了,結果婚禮上在讶,老公的妹妹穿的比我還像新娘。我一直安慰自己霜大,他們只是感情好构哺,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著战坤,像睡著了一般曙强。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上途茫,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天碟嘴,我揣著相機與錄音,去河邊找鬼囊卜。 笑死娜扇,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的栅组。 我是一名探鬼主播雀瓢,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼玉掸!你這毒婦竟也來了刃麸?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤排截,失蹤者是張志新(化名)和其女友劉穎嫌蚤,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體断傲,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡脱吱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了认罩。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片箱蝠。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出宦搬,到底是詐尸還是另有隱情牙瓢,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布间校,位于F島的核電站矾克,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏憔足。R本人自食惡果不足惜胁附,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望滓彰。 院中可真熱鬧控妻,春花似錦、人聲如沸揭绑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽他匪。三九已至菇存,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間诚纸,已是汗流浹背撰筷。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工陈惰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留畦徘,地道東北人。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓抬闯,卻偏偏與公主長得像井辆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子溶握,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎部分 基礎部分的順序:基本語法杯缺,類相關的語法,內(nèi)部類的語法睡榆,繼承相關的語法萍肆,異常的語法,線程的語...
    子非魚_t_閱讀 31,623評論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理胀屿,服務發(fā)現(xiàn)塘揣,斷路器,智...
    卡卡羅2017閱讀 134,652評論 18 139
  • 這個系列面試題主要目的是幫助你拿輕松到offer宿崭,同時還能開個好價錢亲铡。只要能夠搞明白這個系列的絕大多數(shù)題目,在面試...
    獨念白閱讀 338評論 0 3
  • 1、一個".java"源文件中是否可以包括多個類(不是內(nèi)部類)奖蔓?有什么限制赞草?答:可以有多個類,但只能有一個publ...
    岳小川閱讀 927評論 0 2
  • 今天的晨讀文章是介紹日本銷量No.1 的奢侈品店店長寫的《聰明女人背小包》吆鹤,這對做為一個恨不得拎麻包袋上班...
    一只想開悟的豬閱讀 153評論 1 1