欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(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í)看到一句話:

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)并沒有改變。

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

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

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

線程安全

易于理解

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

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

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

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

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

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

原始數(shù)據(jù)類型(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)鍵字還不能讓引用類型(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

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

Java mutable 和 immutable類型

含義解釋

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.

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

圖形化解釋 Snapshot Diagram

mutable:

mutable

immutable:

immutable

舉例

例如String和StringBuilder:

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

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

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

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

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

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

可變類型最 少化拷貝以提高效率。

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

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

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

深度拷貝

當(dāng)只是引用傳遞或者根據(jù)對(duì)象的值創(chuà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全局異常處理之解決404/500錯(cuò)誤

    SpringBoot全局異常處理之解決404/500錯(cuò)誤

    在搭建項(xiàng)目框架的時(shí)候用的是springboot,想統(tǒng)一處理異常,但是發(fā)現(xiàn)404的錯(cuò)誤總是捕捉不到,總是返回的是springBoot自帶的錯(cuò)誤結(jié)果信息,這篇文章主要給大家介紹了關(guān)于SpringBoot全局異常處理之解決404/500錯(cuò)誤的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • 總結(jié)十個(gè)實(shí)用但偏執(zhí)的Java編程技術(shù)

    總結(jié)十個(gè)實(shí)用但偏執(zhí)的Java編程技術(shù)

    Java是世界上最流行的程序語言,從1995年問世以來,Java的生態(tài)系統(tǒng)在一直在蓬勃的發(fā)展著。下面這篇文章主要總結(jié)了十個(gè)實(shí)用但偏執(zhí)的Java編程技術(shù),需要的朋友可以參考借鑒,下面來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-01-01
  • Java JVM原理與調(diào)優(yōu)_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java JVM原理與調(diào)優(yōu)_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    JVM是Java Virtual Machine(Java虛擬機(jī))的縮寫,JVM是一種用于計(jì)算設(shè)備的規(guī)范,它是一個(gè)虛構(gòu)出來的計(jì)算機(jī),是通過在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能來實(shí)現(xiàn)的。下面通過本文給大家介紹jvm原理與調(diào)優(yōu)相關(guān)知識(shí),感興趣的朋友一起學(xué)習(xí)吧
    2017-04-04
  • Spring boot 默認(rèn)靜態(tài)資源路徑與手動(dòng)配置訪問路徑的方法

    Spring boot 默認(rèn)靜態(tài)資源路徑與手動(dòng)配置訪問路徑的方法

    這篇文章主要介紹了Spring boot 默認(rèn)靜態(tài)資源路徑與手動(dòng)配置訪問路徑的方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-05-05
  • Maven將代碼及依賴打成一個(gè)Jar包的方式詳解(最新推薦)

    Maven將代碼及依賴打成一個(gè)Jar包的方式詳解(最新推薦)

    這篇文章主要介紹了Maven將代碼及依賴打成一個(gè)Jar包的方式,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • JVM角度調(diào)試優(yōu)化MyEclipse

    JVM角度調(diào)試優(yōu)化MyEclipse

    這篇文章主要介紹了從JVM角度對(duì)MyEclipse進(jìn)行調(diào)試優(yōu)化,為大家分析調(diào)試優(yōu)化MyEclipse的步驟,感興趣的小伙伴們可以參考一下
    2016-05-05
  • java利用oss實(shí)現(xiàn)下載功能

    java利用oss實(shí)現(xiàn)下載功能

    這篇文章主要為大家詳細(xì)介紹了java利用oss實(shí)現(xiàn)下載功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • java面向?qū)ο笤O(shè)計(jì)原則之接口隔離原則示例詳解

    java面向?qū)ο笤O(shè)計(jì)原則之接口隔離原則示例詳解

    這篇文章主要為大家介紹了java面向?qū)ο笤O(shè)計(jì)原則之接口隔離原則的示例詳解,有需要的朋友可以借鑒參考下希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2021-10-10
  • Java命名規(guī)范

    Java命名規(guī)范

    本文主要介紹了Java命名規(guī)范。具有一定的參考價(jià)值,下面跟著小編一起來看下吧
    2017-01-01
  • java 交換兩個(gè)數(shù)據(jù)的方法實(shí)例詳解

    java 交換兩個(gè)數(shù)據(jù)的方法實(shí)例詳解

    這篇文章主要介紹了java 交換兩個(gè)數(shù)據(jù)的方法實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2016-12-12

最新評(píng)論