最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java不可變類機(jī)制淺析

 更新時(shí)間:2017年02月05日 11:54:06   作者:fuzhongmin05  
所謂的不可變類是指這個(gè)類的實(shí)例一旦創(chuàng)建完成后,就不能改變其成員變量值。如JDK內(nèi)部自帶的很多不可變類:Interger、Long和String等。接下來(lái)通過(guò)本文給大家介紹Java不可變類機(jī)制,需要的朋友參考下

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

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

不可變類的特性對(duì)JAVA來(lái)說(shuō)帶來(lái)怎樣的好處?

1)線程安全:不可變對(duì)象是線程安全的,在線程之間可以相互共享,不需要利用特殊機(jī)制來(lái)保證同步問(wèn)題,因?yàn)閷?duì)象的值無(wú)法改變??梢越档筒l(fā)錯(cuò)誤的可能性,因?yàn)椴恍枰靡恍╂i機(jī)制等保證內(nèi)存一致性問(wèn)題也減少了同步開(kāi)銷。

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

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

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

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

2)Immutable類的所有的成員都應(yīng)該是private final的。通過(guò)這種方式保證成員變量不可改變。但只做到這一步還不夠,因?yàn)槿绻蓡T變量是對(duì)象,它保存的只是引用,有可能在外部改變其引用指向的值,所以第5點(diǎn)彌補(bǔ)這個(gè)不足

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

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

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

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

public final class ImmutableDemo { 
  private final int[] myArray; 
  public ImmutableDemo(int[] array) { 
    this.myArray = array;  // wrong 
  } 
}

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

public final class MyImmutableDemo { 
  private final int[] myArray; 
  public MyImmutableDemo(int[] array) { 
    this.myArray = array.clone();  
  }  
}

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

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

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è)計(jì)符合上面總結(jié)的不變類型的設(shè)計(jì)原則。雖然String對(duì)象將value設(shè)置為final,并且還通過(guò)各種機(jī)制保證其成員變量不可改變。但是還是可以通過(guò)反射機(jī)制改變其值。例如:

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屬性的訪問(wèn)權(quán)限
char[] value = (char[]) valueFieldOfString.get(s);
value[5] = '_'; //改變value所引用的數(shù)組中的第5個(gè)字符
System.out.println("s = " + s);   //Hello_World打印結(jié)果為:
s = Hello World
s = Hello_World

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

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

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

相關(guān)文章

  • 快速解決List集合add元素,添加多個(gè)對(duì)象出現(xiàn)重復(fù)的問(wèn)題

    快速解決List集合add元素,添加多個(gè)對(duì)象出現(xiàn)重復(fù)的問(wèn)題

    這篇文章主要介紹了快速解決List集合add元素,添加多個(gè)對(duì)象出現(xiàn)重復(fù)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • 使用@TableField(updateStrategy=FieldStrategy.IGNORED)遇到的坑記錄

    使用@TableField(updateStrategy=FieldStrategy.IGNORED)遇到的坑記錄

    這篇文章主要介紹了使用@TableField(updateStrategy=FieldStrategy.IGNORED)遇到的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • 詳細(xì)解讀JAVA多線程實(shí)現(xiàn)的三種方式

    詳細(xì)解讀JAVA多線程實(shí)現(xiàn)的三種方式

    本篇文章主要介紹了詳細(xì)解讀JAVA多線程實(shí)現(xiàn)的三種方式,主要包括繼承Thread類、實(shí)現(xiàn)Runnable接口、使用ExecutorService、Callable、Future實(shí)現(xiàn)有返回結(jié)果的多線程。有需要的可以了解一下。
    2016-11-11
  • Flink狀態(tài)和容錯(cuò)源碼解析

    Flink狀態(tài)和容錯(cuò)源碼解析

    這篇文章主要為大家介紹了Flink狀態(tài)和容錯(cuò)源碼示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • SpringBoot2學(xué)習(xí)之springboot與spring區(qū)別分析

    SpringBoot2學(xué)習(xí)之springboot與spring區(qū)別分析

    這篇文章主要為大家介紹了SpringBoot2學(xué)習(xí)之springboot與spring區(qū)別分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • java中Hutool包的常用方法總結(jié)

    java中Hutool包的常用方法總結(jié)

    這篇文章主要為大家詳細(xì)介紹了java在工作中中Hutool包的一些常用方法總結(jié),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-12-12
  • 使用spring攔截器實(shí)現(xiàn)日志管理實(shí)例

    使用spring攔截器實(shí)現(xiàn)日志管理實(shí)例

    本篇文章主要介紹了使用spring攔截器實(shí)現(xiàn)日志管理實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-03-03
  • IDEA配置Tomcat創(chuàng)建web項(xiàng)目的詳細(xì)步驟

    IDEA配置Tomcat創(chuàng)建web項(xiàng)目的詳細(xì)步驟

    Tomcat是一個(gè)Java?Web應(yīng)用服務(wù)器,實(shí)現(xiàn)了多個(gè)Java?EE規(guī)范(JSP、Java?Servlet等),這篇文章主要給大家介紹了關(guān)于IDEA配置Tomcat創(chuàng)建web項(xiàng)目的詳細(xì)步驟,需要的朋友可以參考下
    2023-12-12
  • MybatisPlus逆向工程的項(xiàng)目實(shí)踐

    MybatisPlus逆向工程的項(xiàng)目實(shí)踐

    Mybatis-Plus逆向工程,是MP官方提供的一款代碼生成器,可以自動(dòng)生成對(duì)應(yīng)的實(shí)體類、Mapper接口和配置文件,,本文主要介紹了MybatisPlus逆向工程的項(xiàng)目實(shí)踐,感興趣的可以了解一下
    2024-03-03
  • 基于UDP實(shí)現(xiàn)聊天室功能

    基于UDP實(shí)現(xiàn)聊天室功能

    這篇文章主要為大家詳細(xì)介紹了基于UDP實(shí)現(xiàn)聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04

最新評(píng)論

武夷山市| 黄浦区| 苍梧县| 方正县| 海城市| 西城区| 宣威市| 天等县| 准格尔旗| 抚顺市| 桑日县| 揭西县| 平邑县| 剑川县| 白银市| 湘乡市| 通江县| 治多县| 兴城市| 辉县市| 蒙山县| 平南县| 宁明县| 浦北县| 桃源县| 应城市| 新邵县| 惠安县| 西丰县| 任丘市| 时尚| 新竹县| 霍林郭勒市| 阿合奇县| 濉溪县| 通化市| 桃园县| 广元市| 湖口县| 客服| 疏勒县|