簡體   English   中英

包含Random對象變量的類(類的實例)是否可以是不可變的?

[英]Can a class (an instance of the class), containing Random object variable be immutable?

不變性的定義表明,在構造之后,對象的狀態(其數據)不能被改變。

這里提出了一個問題,在我看來,對象包含的狀態和數據是不同的東西。 也許狀態意味着通過getter提供的數據?

它並不意味着標記為私有且外部世界不可見的數據,這些數據確實可以改變而不會改變對象的狀態。

告訴我這是否正確:

final class Obj1 {
 private final  int i; 
 private final  Random rnd = new Random();
 private int j = rnd.nextInt(1000);
 public Obj1(int i) {
   this.i = i;
  }  
 public getI() {
  j = rnd.nextInt(1000);
  return i;
 }
}

Obj1一個實例是一個不可變對象。

final class Obj2 {
 private final int i; 
 private final Random rnd = new Random();
 private int j = rnd.nextInt(1000);
 public Obj1(int i) {
   this.i = i;
 }  
 public getI() {
   return i;
 }
 public getJ() {
   return j;
 }
}

Obj2的實例是一個可變或不可變的對象,為什么? 如果每次調用getter時我們在getJ體中得到下一個Random會怎么樣?

這樣的課程怎么樣? 可變/不可變,為什么?

final class Obj3 {
 private final  Random rnd = new Random();
 private int j = rnd.nextInt(1000);
 public Obj1() {
  }  
 public getJ() {
   return j;
 }
}

這個如何? 可變/不可變,為什么?

final class Obj4 {
 private final Random rnd = new Random();
 public Obj1() {
  }  
 public getRnd() {
   return rnd.nextInt(1000);
 }
}

關於不變性的一個重要觀點是,對象的可觀察狀態不得改變。

一個很好的例子是java.lang.String ,它經常被引用為不可變類的規范示例。 它有一個非final字段,即hash hash保存哈希碼,但默認為0 哈希碼是在第一次調用hashCode()並在該字段中緩存時延遲計算的。 這樣, String對象的內部狀態可以改變,但是可觀察狀態永遠不會改變(因為hashCode()總是返回相同的值,無論是計算還是只返回緩存的值)。

這意味着你提供的前三個樣本( Obj1Obj2Obj3 )是不可變的:它們沒有setter,並且在構造之后沒有其他任何東西可以改變它們的方法返回的值(最好將字段聲明為final ,但它不是不可變性的要求)。 另請注意,您也可以完全忽略這些類中的Random字段,因為它無論如何都不會在構造之后使用。

我說最后一個樣本( Obj4 )肯定是可變的,因為你每次讀取它時都會改變狀態(即下一個getRnd()調用返回的內容)(即每次調用getRnd() )。

因此,回答標題中的問題:是的,如果Random類的狀態在類本身的狀態下是不可觀察的,則引用Random對象的類可以是不可變的。

如果引用被識別為識別而不是保持有問題的對象,則不可變對象保持甚至公開對任意類型對象的引用是完全合法的。 例如,將對象引用視為類似於VIN(車輛標識號 - 唯一標識車輛的字母數字字符串,至少是美國制造或進口的車輛),並想象維修車間可能保留一個它所服務的汽車的VIN列表。 汽車本身幾乎不會成為不可改變的物品,但是這個列表不能存放汽車 - 它會識別汽車。 人們無法看到VIN並且知道汽車在維修時的顏色是什么,但是當汽車進入商店時,可以使用VIN列表來確定汽車之前是否已經訪問過汽車。

好問題。 但這是術語的問題,而不變性更多的是關於如何使用對象。 不可變對象的好處:

  • 你可以通過引用傳遞它們,並確保沒有人改變它的狀態;
  • 你不需要考慮同步;
  • 在哈希映射中用作密鑰更安全。

如果它在構造之后改變它的狀態,即使它必須設置,我也不會將對象聲明為不可變的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM