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

Java mutable對(duì)象和immutable對(duì)象的區(qū)別說(shuō)明

 更新時(shí)間:2021年06月10日 15:19:24   作者:zhongrui_fzr  
這篇文章主要介紹了Java mutable對(duì)象和immutable對(duì)象的區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Java mutable對(duì)象和immutable對(duì)象的區(qū)別

今天讀jdk源碼中Map.java時(shí)看到一句話(huà):

great care must be exercised if mutable objects are used as map keys;

第一次知道m(xù)utable對(duì)象這個(gè)概念,google了一下,維基百科定義如下:

“In object-oriented and functional programming, an immutable object (unchangeable[1] object) is an object whose state cannot be modified after it is created.[2] This is in contrast to a mutable object (changeable object) , which can be modified after it is created. In some cases, an object is considered immutable even if some internally used attributes change but the object's state appears to be unchanging from an external point of view. For example, an object that uses memoization to cache the results of expensive computations could still be considered an immutable object.”

在面向?qū)ο蠛秃瘮?shù)式編程中,一個(gè)immutable對(duì)象(不可變對(duì)象)是指一旦創(chuàng)建之后狀態(tài)不可改變的對(duì)象。

mutable對(duì)象(可變對(duì)象)是指創(chuàng)建之后也可以修改的對(duì)象。

在有些情況下,對(duì)象也被認(rèn)為是不可變的(immutable),即,一個(gè)對(duì)象包含的內(nèi)部使用的屬性改變了,但從外部看對(duì)象的狀態(tài)并沒(méi)有改變。

例如,一個(gè)使用memoization來(lái)緩存復(fù)雜計(jì)算結(jié)果的對(duì)象仍然被看作是不可變(immutable)對(duì)象.

在面向?qū)ο缶幊讨?,String 以及其他的具體對(duì)象都被看作是不可變(immutable)對(duì)象,以提高可讀性和運(yùn)行效率。

不可變對(duì)象有幾個(gè)優(yōu)點(diǎn):

線(xiàn)程安全

易于理解

比可變對(duì)象有更高的安全性

Java中不可變對(duì)象的經(jīng)典例子就是String類(lèi)的實(shí)例:

String s = "ABC";
s.toLowerCase();

toLowerCase()方法不會(huì)改變s中包含的數(shù)據(jù)“ABC”。而是創(chuàng)建一個(gè)新的String對(duì)象并將其初始化為“abc”,然后返回這個(gè)新對(duì)象的引用。

盡管String類(lèi)聲明中沒(méi)有提供讓它成為不可變對(duì)象的語(yǔ)法,但是,String類(lèi)的方法中沒(méi)有方法去改變一個(gè)String包含的數(shù)據(jù),這就使得它是不可變的。

Java中關(guān)鍵字final用于聲明原始數(shù)據(jù)類(lèi)型(primitive types)和對(duì)象引用為不可變對(duì)象,但是它不能使對(duì)象本身變?yōu)椴豢勺儗?duì)象。

原始數(shù)據(jù)類(lèi)型(primitive types)變量(int, long, short等)定義之后還可以再重新賦值,可以使用final阻止這樣的賦值。

int i = 42; //int is of primitive type
i = 43; // OK
final int j = 42;
j = 43; // does not compile. j is final so can't be reassigned

僅僅使用final關(guān)鍵字還不能讓引用類(lèi)型(reference types)成為不可變對(duì)象,final只能阻止重新賦值。

final MyObject m = new MyObject(); //m is of reference type
m.data = 100; // OK. We can change state of object m (m is mutable and final doesn't change this fact)
m = new MyObject(); // does not compile. m is final so can't be reassigned

原始類(lèi)型包裝類(lèi)(primitive wrappers)(Integer,Long, Short, Double, Float, Character, Byte, Boolean)也都是不可變的。

Java mutable 和 immutable類(lèi)型

含義解釋

immutable : variables that are assigned once and never reassigned.

mutable : When you assign to a variable or a field, you're changing where the variable's arrow points. You can point it to a different value. When you assign to the contents of a mutable value – such as an array or list – you're changing references inside that value.

基本類(lèi)型及其封裝對(duì)象類(lèi)型都是不可變的

圖形化解釋 Snapshot Diagram

mutable:

mutable

immutable:

immutable

舉例

例如String和StringBuilder:

1. String是immutable的,每次對(duì)于String對(duì)象的修改都將產(chǎn)生一個(gè)新的String對(duì)象,而原來(lái)的對(duì)象保持不變。

2. StringBuilder是mutable,因?yàn)槊看螌?duì)于它的對(duì)象的修改都作用于該對(duì)象本身,并沒(méi)有產(chǎn)生新的對(duì)象。

如何保證自己創(chuàng)建的類(lèi)是immutable類(lèi)

  • 所有成員都是private final。
  • 不提供對(duì)成員的改變方法,setXX
  • 確保所有的方法不會(huì)被重寫(xiě)。手段有兩種:使用final Class(強(qiáng)不可變類(lèi)),或者將所有類(lèi)方法加上final(弱不可變類(lèi))。
  • 如果某一個(gè)類(lèi)成員不是原始變量(例如int,double)或者不可變類(lèi),必須通過(guò)在成員初始化或者使用get方法時(shí)要通過(guò)深度拷貝方法,來(lái)確保類(lèi)的不可變。

優(yōu)缺點(diǎn)

使用不可變類(lèi)型,對(duì)其頻繁修改會(huì)產(chǎn)生大量的臨時(shí)拷貝(需要垃圾回收) ;

可變類(lèi)型最 少化拷貝以提高效率。

使用可變數(shù)據(jù)類(lèi)型,可獲得更好的性能 ,也適合于在多個(gè)模塊之間共享數(shù)據(jù) 。例如全局變量。

不可變類(lèi)型更“安全”, 在其他質(zhì)量指標(biāo)上表現(xiàn)更好。

對(duì)可變類(lèi)型可能造成的風(fēng)險(xiǎn),我們通過(guò)防御式拷貝(深度拷貝),給客戶(hù)端返回一個(gè)全新的可變類(lèi)型的對(duì)象,大部分時(shí)候該拷貝不會(huì)被客戶(hù)端修改, 可能造成大量的內(nèi)存浪費(fèi)。

深度拷貝

當(dāng)只是引用傳遞或者根據(jù)對(duì)象的值創(chuàng)建新的值,稱(chēng)為“淺復(fù)制”,當(dāng)原對(duì)象的發(fā)生改變時(shí),根據(jù)上面方式創(chuàng)建的新對(duì)象的也會(huì)隨之改變;

而如果采用深度復(fù)制,那是真正的復(fù)制了一份新的對(duì)象,新對(duì)象的與原對(duì)象不存在任何關(guān)聯(lián),原對(duì)象發(fā)生改變不會(huì)影響新對(duì)象。

相關(guān)文章

  • SpringBoot啟動(dòng)報(bào)錯(cuò)Whitelabel Error Page: This application has no explicit mapping for的解決方法

    SpringBoot啟動(dòng)報(bào)錯(cuò)Whitelabel Error Page: This&nbs

    當(dāng)我們使用Spring Boot框架開(kāi)發(fā)Web應(yīng)用時(shí),有時(shí)會(huì)遇到啟動(dòng)報(bào)錯(cuò)信息為"Whitelabel Error Page: This application has no explicit mapping for",種報(bào)錯(cuò)信息意味著我們的應(yīng)用缺少某個(gè)URL映射的配置,導(dǎo)致請(qǐng)求無(wú)法處理,在本篇文章中,我們將詳細(xì)討論如何解決這個(gè)問(wèn)題
    2024-03-03
  • java多線(xiàn)程消息隊(duì)列的實(shí)現(xiàn)代碼

    java多線(xiàn)程消息隊(duì)列的實(shí)現(xiàn)代碼

    本篇文章主要介紹了java多線(xiàn)程消息隊(duì)列的實(shí)現(xiàn)代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • shuffle的關(guān)鍵階段sort(Map端和Reduce端)源碼分析

    shuffle的關(guān)鍵階段sort(Map端和Reduce端)源碼分析

    今天小編就為大家分享一篇關(guān)于shuffle的關(guān)鍵階段sort(Map端和Reduce端)源碼分析,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01
  • 基于SpringAop中JoinPoint對(duì)象的使用說(shuō)明

    基于SpringAop中JoinPoint對(duì)象的使用說(shuō)明

    這篇文章主要介紹了基于SpringAop中JoinPoint對(duì)象的使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • SpringBoot配置開(kāi)發(fā)環(huán)境的詳細(xì)步驟(JDK、Maven、IDEA等)

    SpringBoot配置開(kāi)發(fā)環(huán)境的詳細(xì)步驟(JDK、Maven、IDEA等)

    文章介紹了如何配置SpringBoot開(kāi)發(fā)環(huán)境,包括安裝JDK、Maven和IDEA,并提供了詳細(xì)的步驟和配置方法,感興趣的朋友一起看看吧
    2024-12-12
  • 基于Java回顧之反射的使用分析

    基于Java回顧之反射的使用分析

    本篇文章是對(duì)Java反射的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 解決@Cacheable在同一個(gè)類(lèi)中方法調(diào)用不起作用的問(wèn)題

    解決@Cacheable在同一個(gè)類(lèi)中方法調(diào)用不起作用的問(wèn)題

    這篇文章主要介紹了解決@Cacheable在同一個(gè)類(lèi)中方法調(diào)用不起作用的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 詳解Java事件編程的使用

    詳解Java事件編程的使用

    Java事件在很多地方都可以使用,合理的使用事件編程,相比常規(guī)邏輯的編程,這可達(dá)到主次分明,讓程序吞吐量即處理能力更強(qiáng),改動(dòng)更少,下面我們舉一個(gè)例子說(shuō)明如何使用Java使用,需要的朋友可以參考下
    2021-06-06
  • SpringBoot中Dozer的使用小結(jié)

    SpringBoot中Dozer的使用小結(jié)

    dozer是用來(lái)兩個(gè)對(duì)象之間屬性轉(zhuǎn)換的工具,有了這個(gè)工具之后,我們將一個(gè)對(duì)象的所有屬性值轉(zhuǎn)給另一個(gè)對(duì)象時(shí),就不需要再去寫(xiě)重復(fù)的set和get方法了,下面介紹下SpringBoot中Dozer的使用,感興趣的朋友一起看看吧
    2022-03-03
  • SpringBoot新特性之全局懶加載機(jī)制

    SpringBoot新特性之全局懶加載機(jī)制

    這篇文章主要介紹了SpringBoot新特性之全局懶加載機(jī)制,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評(píng)論

武威市| 镇沅| 墨玉县| 新丰县| 丹凤县| 东山县| 福清市| 武城县| 防城港市| 香港| 鱼台县| 黄大仙区| 杂多县| 洛浦县| 大方县| 聂拉木县| 阿坝县| 张家港市| 洪洞县| 崇州市| 静安区| 镇巴县| 龙游县| 富川| 拉萨市| 玉环县| 泾川县| 瓦房店市| 武强县| 长丰县| 昂仁县| 明水县| 威远县| 元朗区| 万荣县| 石屏县| 新河县| 徐水县| 汾西县| 体育| 安阳市|