一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - Java不可變類機制淺析

Java不可變類機制淺析

2020-08-03 16:22fuzhongmin05 Java教程

所謂的不可變類是指這個類的實例一旦創(chuàng)建完成后,就不能改變其成員變量值。如JDK內(nèi)部自帶的很多不可變類:Interger、Long和String等。接下來通過本文給大家介紹Java不可變類機制,需要的朋友參考下

 不可變類(Immutable Class):所謂的不可變類是指這個類的實例一旦創(chuàng)建完成后,就不能改變其成員變量值。如JDK內(nèi)部自帶的很多不可變類:Interger、Long和String等。

可變類(Mutable Class):相對于不可變類,可變類創(chuàng)建實例后可以改變其成員變量值,開發(fā)中創(chuàng)建的大部分類都屬于可變類。

不可變類的特性對JAVA來說帶來怎樣的好處?

1)線程安全:不可變對象是線程安全的,在線程之間可以相互共享,不需要利用特殊機制來保證同步問題,因為對象的值無法改變。可以降低并發(fā)錯誤的可能性,因為不需要用一些鎖機制等保證內(nèi)存一致性問題也減少了同步開銷。

2)易于構(gòu)造、使用和測試。

不可變類的設(shè)計原則

如何在Java中寫出Immutable的類?要寫出這樣的類,需要遵循以下幾個原則:

1)immutable對象的狀態(tài)在創(chuàng)建之后就不能發(fā)生改變,任何對它的改變都應(yīng)該產(chǎn)生一個新的對象。

2)Immutable類的所有的成員都應(yīng)該是private final的。通過這種方式保證成員變量不可改變。但只做到這一步還不夠,因為如果成員變量是對象,它保存的只是引用,有可能在外部改變其引用指向的值,所以第5點彌補這個不足

3)對象必須被正確的創(chuàng)建,比如:對象引用在對象創(chuàng)建過程中不能泄露。4)只提供讀取成員變量的get方法,不提供改變成員變量的set方法,避免通過其他接口改變成員變量的值,破壞不可變特性。

5)類應(yīng)該是final的,保證類不被繼承,如果類可以被繼承會破壞類的不可變性機制,只要繼承類覆蓋父類的方法并且繼承類可以改變成員變量值,那么一旦子類以父類的形式出現(xiàn)時,不能保證當(dāng)前類是否可變。

6)如果類中包含mutable類對象,那么返回給客戶端的時候,返回該對象的一個深拷貝,而不是該對象本身(該條可以歸為第一條中的一個特例)

如果將構(gòu)造器傳入的對象直接賦值給成員變量,還是可以通過對傳入對象的修改進而導(dǎo)致改變內(nèi)部變量的值。例如:

?
1
2
3
4
5
6
public final class ImmutableDemo {
  private final int[] myArray;
  public ImmutableDemo(int[] array) {
    this.myArray = array;  // wrong
  }
}

這種方式不能保證不可變性,myArray和array指向同一塊內(nèi)存地址,用戶可以在ImmutableDemo之外通過修改array對象的值來改變myArray內(nèi)部的值。為了保證內(nèi)部的值不被修改,可以采用深度copy來創(chuàng)建一個新內(nèi)存保存?zhèn)魅氲闹怠U_做法:

?
1
2
3
4
5
6
public final class MyImmutableDemo {
  private final int[] myArray;
  public MyImmutableDemo(int[] array) {
    this.myArray = array.clone(); 
  
}

String類的不可變實現(xiàn)

String對象在內(nèi)存創(chuàng)建后就不可改變,不可變對象的創(chuàng)建一般滿足以上原則,我們看看String代碼是如何實現(xiàn)的。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public final class String
  implements java.io.Serializable, Comparable<String>, CharSequence
{
  private final char value[]; /** The value is used for character storage. */
  /** The offset is the first index of the storage that is used. */
  private final int offset;
  /** The count is the number of characters in the String. */
  private final int count;
  private int hash; // Default to 0
  ....
  public String(char value[]) {
     this.value = Arrays.copyOf(value, value.length); // deep copy操作
   }
   public char[] toCharArray() {
    char result[] = new char[value.length];
    System.arraycopy(value, 0, result, 0, value.length);
    return result;
  }
  ...
}

如代碼所示,可以觀察到String類的設(shè)計符合上面總結(jié)的不變類型的設(shè)計原則。雖然String對象將value設(shè)置為final,并且還通過各種機制保證其成員變量不可改變。但是還是可以通過反射機制改變其值。例如:

?
1
2
3
4
5
6
7
8
9
10
String s = "Hello World"; //創(chuàng)建字符串"Hello World", 并賦給引用s
System.out.println("s = " + s);  
//獲取String類中的value字段
Field valueFieldOfString = String.class.getDeclaredField("value");
valueFieldOfString.setAccessible(true); //改變value屬性的訪問權(quán)限
char[] value = (char[]) valueFieldOfString.get(s);
value[5] = '_'; //改變value所引用的數(shù)組中的第5個字符
System.out.println("s = " + s);   //Hello_World打印結(jié)果為:
s = Hello World
s = Hello_World

發(fā)現(xiàn)String的值已經(jīng)發(fā)生了改變。也就是說,通過反射是可以修改所謂的“不可變”對象的。

不可變類是實例創(chuàng)建后就不可以改變成員遍歷的值。這種特性使得不可變類提供了線程安全的特性,但同時也帶來了對象創(chuàng)建的開銷,每更改一個屬性都是重新創(chuàng)建一個新的對象。JDK內(nèi)部也提供了很多不可變類如Integer、Double、String等。String的不可變特性主要為了滿足常量池、線程安全、類加載的需求。合理使用不可變類可以帶來極大的好處。

以上所述是小編給大家介紹的Java不可變類機制淺析,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復(fù)大家的!

原文鏈接:http://blog.csdn.net/fuzhongmin05/article/details/54880139

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美日韩国产一区二区三区伦 | 人禽l交视频在线播放 视频 | 人人人人人看碰人人免费 | 欧美香蕉 | 扒开老女人 | 操操综合网 | 美女被狂揉下部羞羞动漫 | 韩国三级年轻小的胰子完整 | 亚洲第一福利网 | 国产成人在线免费观看 | 欧美人成绝费网站色www吃脚 | 四虎国产免费 | ysav67| 欧美伦乱 | 亚洲精品一区二区久久这里 | 日本五级床片全都免费播放 | 全黄h全肉细节文在线观看 全彩成人18h漫画 | 无人在线视频高清免费播放 | 亚洲AV福利天堂一区二区三 | 久久精品观看影院2828 | 亚洲 日韩 自拍 视频一区 | 激情视频网址 | 日本一区二区三区国产 | 窝窝色资源站 | 99热久久这里只精品国产www | 四虎影视4hu最新地址在线884 | 国产射频放大器 | 欧美同性videos| 亚洲成年www| 三星w699 | 18xxxx中国 | 韩国女主播在线大尺无遮挡 | 亚洲AV精品一区二区三区不卡 | aⅴ视频在线免播放观看 | 国产日韩精品一区二区 | 久久99精品久久久久久园产越南 | 国产一卡2卡3卡4卡公司科普 | 国产精品视频第一区二区三区 | 我半夜摸妺妺的奶C了她软件 | 国产青色 | 国产日韩精品一区二区在线观看播放 |