日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

如果對象的狀態在構造后無法更改,則該對象是不可變的。不可變的對象不會讓其他對象修改其狀態。對象的字段在構造函數內部僅初始化一次,以后再也不會更改。

在本文中,我們將定義在JAVA中創建不可變類的典型步驟,并闡明開發人員在創建不可變類時遇到的常見錯誤。

1.不可變類的用法

如今,每個軟件應用程序的“必備”規范都將被分發和使用多線程。多線程應用程序總是使開發人員感到頭疼,因為要求開發人員保護其對象的狀態,以防止同時修改多個線程。同時,為此,開發人員通常在修改對象狀態時使用“ 同步”塊。

對于不可變的類,狀態永遠不會被修改。狀態的每次修改都會產生一個新實例,因此每個線程將使用不同的實例,并且開發人員不必擔心并發修改。

2.一些流行的不可變類

字符串 是Java中最流行的不可變類。初始化后,其值將無法修改。操作像修剪(),子串(),替換()總是返回一個新的實例,并不會影響當前的實例,這就是為什么我們通常所說的修剪() ,如下所示:

String alex = "Alex";

alex = alex.trim();

JDK的另一個示例是包裝器類,例如:Integer,Float,Boolean……這些類不會修改其狀態,但是,每次您嘗試對其進行修改時,它們都會創建一個新實例。

Integer a =3;

a += 3;

調用+ = 3之后,將創建一個新實例,其值保持為:6,并且第一個實例丟失。

3.我們如何創建一個不可變的類

為了創建一個不可變的類,您應該遵循以下步驟:

1.

將您的班級定為最終以便其他班級無法對其進行擴展。

2.

3. 將所有字段定為最終字段以使它們在構造函數中僅初始化一次,之后再也不會修改。

4. 不要公開setter方法。

5. 在公開修改類狀態的方法時,必須始終返回該類的新實例。

6. 如果該類包含一個可變對象:

1. 在構造函數內部,請確保使用傳遞的參數的克隆副本,并且切勿將可變字段設置為通過構造函數傳遞的真實實例,這是為了防止傳遞對象的客戶端事后對其進行修改。

2. 確保始終返回該字段的副本,而不返回真實對象實例。

3.1簡單不可變類

讓我們按照上述步驟操作,并創建自己的不可變類(ImmutableStudent.java)。

package com.programmer.gate.beans;

public final class ImmutableStudent {

private final int id;

private final String name;

public ImmutableStudent(int id, String name) {

this.name = name;

this.id = id;

}

public int getId() {

return id;

public String getName() {

return name;

}

上面的類是一個非常簡單的不可變類,它不包含任何可變對象,并且從不以任何方式公開其字段;這些類型的類通常用于緩存。

3.2將可變對象傳遞給不可變類

現在,讓我們的示例復雜一點,我們創建一個名為Age的可變類,并將其作為字段添加到ImmutableStudent中:

public class Age {

private int day;

private int month;

private int year;

public int getDay() {

return day;

public void setDay(int day) {

this.day = day;

public int getMonth() {

return month;

public void setMonth(int month) {

this.month = month;

public int getYear() {

return year;

public void setYear(int year) {

this.year = year;

private final Age age;

public ImmutableStudent(int id, String name, Age age) {

this.name = name;

this.id = id;

this.age = age;

return id;

return name;

public Age getAge() {

return age;

因此,我們在不可變類中添加了類型為Age的新可變字段,并在構造函數中按常規分配了該字段。

讓我們創建一個簡單的測試類,并驗證ImmutableStudent是否不再不可變:

public static void main(String[] args) {

Age age = new Age();

age.setDay(1);

age.setMonth(1);

age.setYear(1992);

ImmutableStudent student = new ImmutableStudent(1, "Alex", age);

System.out.println("Alex age year before modification = " + student.getAge().getYear());

age.setYear(1993);

System.out.println("Alex age year after modification = " + student.getAge().getYear());

運行上面的測試后,我們得到以下輸出:

Alex age year before modification = 1992

Alex age year after modification = 1993

我們聲稱ImmutableStudent是一個不可變的類,其狀態在構造之后就不會修改,但是在上面的示例中,即使在構造Alex對象之后,我們也能夠修改Alex的年齡。如果我們返回ImmutableStudent構造函數的實現,則會發現age字段已分配給Age參數的實例,因此,只要在類外部修改了引用的Age,該更改就會直接反映在Alex的狀態上請查看我的“ 按價值傳遞”或“按參考傳遞”文章,以更深入地了解此概念。

為了解決這個問題并使我們的類再次變得不可變,我們遵循上面提到的創建不可變類的步驟中的步驟5。因此,我們修改了構造函數,以克隆傳遞的Age參數并使用其實例。

public ImmutableStudent(int id, String name, Age age) {

Age cloneAge = new Age();

cloneAge.setDay(age.getDay());

cloneAge.setMonth(age.getMonth());

cloneAge.setYear(age.getYear());

this.age = cloneAge;

現在,如果運行測試,將得到以下輸出:

Alex age year after modification = 1992

正如您現在所看到的,Alex的年齡在構建之后再也不會受到影響,我們的班級又回到了不變的狀態。

3.3從不可變類返回可變對象

但是,我們的類仍然有泄漏,并且不是完全不變的,讓我們采取以下測試方案:

student.getAge().setYear(1993);

輸出:

再次根據步驟4,從不可變對象返回可變字段時,您應該返回它們的克隆實例,而不是該字段的真實實例。

因此,我們修改了getAge()以便返回該對象年齡的副本:

public Age getAge() {

cloneAge.setDay(this.age.getDay());

cloneAge.setMonth(this.age.getMonth());

cloneAge.setYear(this.age.getYear());

return cloneAge;

現在,該類變得完全不可變,并且沒有為其他對象提供任何方法或方法來修改其狀態。

4.結論

不可變的類具有很多優點,尤其是在多線程環境中正確使用時。唯一的缺點是它們比傳統類消耗更多的內存,因為每次對其進行修改后,都會在內存中創建一個新對象...但是,與這些類提供的優點相比,開發人員不應高估內存消耗,因為它可以忽略不計類的類型。

最后,如果一個對象僅能向其他對象呈現一種狀態,則無論它們如何以及何時調用其方法,該對象都是不可變的。如果是這樣,則通過任何線程安全的定義都是線程安全的。

分享到:
標簽:可變 Java
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定