成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

Java? 教程(不可變對(duì)象)

Songlcy / 1808人閱讀

不可變對(duì)象

如果一個(gè)對(duì)象的狀態(tài)在構(gòu)造后不能改變,則該對(duì)象被認(rèn)為是不可變的,對(duì)不可變對(duì)象的最大依賴(lài)被廣泛認(rèn)為是一種創(chuàng)建簡(jiǎn)單、可靠代碼的合理策略。

不可變對(duì)象在并發(fā)應(yīng)用程序中特別有用,由于它們不能改變狀態(tài),因此它們不會(huì)被線(xiàn)程干擾破壞或在不一致的狀態(tài)下觀察。

程序員通常不愿意使用不可變對(duì)象,因?yàn)樗麄儞?dān)心創(chuàng)建新對(duì)象的成本而不是就地更新對(duì)象的成本,對(duì)象創(chuàng)建的影響經(jīng)常被高估,并且可以通過(guò)與不可變對(duì)象相關(guān)聯(lián)的一些效率來(lái)抵消,這些包括由于垃圾收集而減少的開(kāi)銷(xiāo),以及消除保護(hù)可變對(duì)象免于損壞所需的代碼。

以下小節(jié)采用其實(shí)例可變的類(lèi),并從中派生出具有不可變實(shí)例的類(lèi),通過(guò)這樣做,它們?yōu)檫@種轉(zhuǎn)換提供了一般規(guī)則,并演示了不可變對(duì)象的一些優(yōu)點(diǎn)。

同步類(lèi)示例

SynchronizedRGB類(lèi)定義了表示顏色的對(duì)象,每個(gè)對(duì)象將顏色表示為代表主要顏色值的三個(gè)整數(shù)和一個(gè)給出顏色名稱(chēng)的字符串。

public class SynchronizedRGB {

    // Values must be between 0 and 255.
    private int red;
    private int green;
    private int blue;
    private String name;

    private void check(int red,
                       int green,
                       int blue) {
        if (red < 0 || red > 255
            || green < 0 || green > 255
            || blue < 0 || blue > 255) {
            throw new IllegalArgumentException();
        }
    }

    public SynchronizedRGB(int red,
                           int green,
                           int blue,
                           String name) {
        check(red, green, blue);
        this.red = red;
        this.green = green;
        this.blue = blue;
        this.name = name;
    }

    public void set(int red,
                    int green,
                    int blue,
                    String name) {
        check(red, green, blue);
        synchronized (this) {
            this.red = red;
            this.green = green;
            this.blue = blue;
            this.name = name;
        }
    }

    public synchronized int getRGB() {
        return ((red << 16) | (green << 8) | blue);
    }

    public synchronized String getName() {
        return name;
    }

    public synchronized void invert() {
        red = 255 - red;
        green = 255 - green;
        blue = 255 - blue;
        name = "Inverse of " + name;
    }
}

必須小心使用SynchronizedRGB以避免在不一致的狀態(tài)下被查看,例如,假設(shè)一個(gè)線(xiàn)程執(zhí)行以下代碼:

SynchronizedRGB color =
    new SynchronizedRGB(0, 0, 0, "Pitch Black");
...
int myColorInt = color.getRGB();      //Statement 1
String myColorName = color.getName(); //Statement 2

如果另一個(gè)線(xiàn)程在語(yǔ)句1之后但在語(yǔ)句2之前調(diào)用color.set,則myColorInt的值將與myColorName的值不匹配,為了避免這種結(jié)果,必須將兩個(gè)語(yǔ)句綁定在一起:

synchronized (color) {
    int myColorInt = color.getRGB();
    String myColorName = color.getName();
} 

這種不一致只適用于可變對(duì)象 — 對(duì)于不可變版本的SynchronizedRGB,它不會(huì)是一個(gè)問(wèn)題。

一種定義不可變對(duì)象的策略

以下規(guī)則定義了用于創(chuàng)建不可變對(duì)象的簡(jiǎn)單策略,并非所有記錄為“不可變”的類(lèi)都遵循這些規(guī)則。這并不一定意味著這些類(lèi)的創(chuàng)造者是草率的 — 他們可能有充分的理由相信他們類(lèi)的實(shí)例在構(gòu)造后永遠(yuǎn)不會(huì)改變,但是,這種策略需要復(fù)雜的分析,不適合初學(xué)者。

不要提供“setter”方法 — 修改字段或字段引用的對(duì)象的方法。

使所有字段為finalprivate。

不允許子類(lèi)重寫(xiě)方法,最簡(jiǎn)單的方法是將類(lèi)聲明為final,更復(fù)雜的方法是使構(gòu)造函數(shù)為private并在工廠(chǎng)方法中構(gòu)造實(shí)例。

如果實(shí)例字段包含對(duì)可變對(duì)象的引用,則不允許更改這些對(duì)象:

不要提供修改可變對(duì)象的方法。

不要共享對(duì)可變對(duì)象的引用,永遠(yuǎn)不要存儲(chǔ)對(duì)傳遞給構(gòu)造函數(shù)的外部可變對(duì)象的引用,如有必要,創(chuàng)建副本并存儲(chǔ)對(duì)副本的引用,同樣,必要時(shí)創(chuàng)建內(nèi)部可變對(duì)象的副本,以避免在方法中返回原始對(duì)象。

將此策略應(yīng)用于SynchronizedRGB會(huì)導(dǎo)致以下步驟:

這個(gè)類(lèi)中有兩個(gè)setter方法,第一個(gè)方法set,任意改變對(duì)象,在類(lèi)的不可變版本中不存在,第二個(gè)方法invert,可以通過(guò)讓它創(chuàng)建一個(gè)新對(duì)象而不是修改現(xiàn)有對(duì)象來(lái)進(jìn)行調(diào)整。

所有字段都已為private,他們進(jìn)一步獲得final。

該類(lèi)本身被聲明為final

只有一個(gè)字段引用一個(gè)對(duì)象,該對(duì)象本身是不可變的,因此,不需要防止改變“包含的”可變對(duì)象的狀態(tài)的保護(hù)措施。

在這些更改之后,我們有ImmutableRGB:

final public class ImmutableRGB {

    // Values must be between 0 and 255.
    final private int red;
    final private int green;
    final private int blue;
    final private String name;

    private void check(int red,
                       int green,
                       int blue) {
        if (red < 0 || red > 255
            || green < 0 || green > 255
            || blue < 0 || blue > 255) {
            throw new IllegalArgumentException();
        }
    }

    public ImmutableRGB(int red,
                        int green,
                        int blue,
                        String name) {
        check(red, green, blue);
        this.red = red;
        this.green = green;
        this.blue = blue;
        this.name = name;
    }


    public int getRGB() {
        return ((red << 16) | (green << 8) | blue);
    }

    public String getName() {
        return name;
    }

    public ImmutableRGB invert() {
        return new ImmutableRGB(255 - red,
                       255 - green,
                       255 - blue,
                       "Inverse of " + name);
    }
}
上一篇:守護(hù)阻塞

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

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

相關(guān)文章

  • Java? 教程(Date-Time)

    Date-Time Java SE 8發(fā)行版中引入的Date-Time包java.time提供了全面的日期和時(shí)間模型,是在JSR 310:Date and Time API下開(kāi)發(fā)的,盡管java.time基于國(guó)際標(biāo)準(zhǔn)化組織(ISO)日歷系統(tǒng),但也支持常用的全球日歷。 此課程介紹了使用基于ISO的類(lèi)來(lái)表示日期和時(shí)間以及操作日期和時(shí)間值的基本原理。 概述 時(shí)間似乎是一個(gè)簡(jiǎn)單的主題,即便是便宜的手表也能...

    AlphaGooo 評(píng)論0 收藏0
  • Java 11 教程

    摘要:原文鏈接已于成功發(fā)布,不過(guò)目前絕大多數(shù)人在生產(chǎn)環(huán)境仍舊使用的是。這篇以案例為主的教程涵蓋了從到的絕大多數(shù)重要的語(yǔ)法與特性。當(dāng)編譯器不能正確識(shí)別出變量的數(shù)值類(lèi)型時(shí),將不被允許使用。同步請(qǐng)求將會(huì)阻塞當(dāng)前的線(xiàn)程,直到返回響應(yīng)消息。 showImg(https://segmentfault.com/img/remote/1460000016575203); 原文鏈接:https://wangw...

    douzifly 評(píng)論0 收藏0
  • Java 8 并發(fā)教程:同步和鎖

    摘要:在接下來(lái)的分鐘,你將會(huì)學(xué)會(huì)如何通過(guò)同步關(guān)鍵字,鎖和信號(hào)量來(lái)同步訪(fǎng)問(wèn)共享可變變量。所以在使用樂(lè)觀鎖時(shí),你需要每次在訪(fǎng)問(wèn)任何共享可變變量之后都要檢查鎖,來(lái)確保讀鎖仍然有效。 原文:Java 8 Concurrency Tutorial: Synchronization and Locks譯者:飛龍 協(xié)議:CC BY-NC-SA 4.0 歡迎閱讀我的Java8并發(fā)教程的第二部分。這份指南將...

    wyk1184 評(píng)論0 收藏0
  • Java學(xué)習(xí)筆記3-Number,String,StringBuilder類(lèi)

    摘要:創(chuàng)建字符串教程字符串長(zhǎng)度用于獲取有關(guān)對(duì)象的信息的方法稱(chēng)為訪(fǎng)問(wèn)器方法。類(lèi)在中被提出,它和之間的最大不同在于的方法不是線(xiàn)程安全的不能同步訪(fǎng)問(wèn)。然而在應(yīng)用程序要求線(xiàn)程安全的情況下,則必須使用類(lèi)。 一般地,當(dāng)需要使用數(shù)字的時(shí)候,我們通常使用內(nèi)置數(shù)據(jù)類(lèi)型,如:byte、int、long、double 等。 在實(shí)際開(kāi)發(fā)過(guò)程中,我們經(jīng)常會(huì)遇到需要使用對(duì)象,而不是內(nèi)置數(shù)據(jù)類(lèi)型的情形。為了解決這個(gè)問(wèn)題,...

    pkhope 評(píng)論0 收藏0
  • Java? 教程(字符串)

    字符串 在Java編程中廣泛使用的字符串是一系列字符,在Java編程語(yǔ)言中,字符串是對(duì)象。 Java平臺(tái)提供String類(lèi)來(lái)創(chuàng)建和操作字符串。 創(chuàng)建字符串 創(chuàng)建字符串的最直接方法是編寫(xiě): String greeting = Hello world!; 在這種情況下,Hello world!是一個(gè)字符串文字 — 代碼中的一系列字符,用雙引號(hào)括起來(lái),每當(dāng)它在代碼中遇到字符串文字時(shí),編譯器就會(huì)創(chuàng)建一個(gè)帶...

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

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

0條評(píng)論

閱讀需要支付1元查看
<