簡體   English   中英

為什么要使類最終成為不可變對象

[英]Why to make class final to create immutable object

我正在嘗試遵循以下代碼。 我不確定在第5行發生什么,為什么在第7行的語句將不可變類中的tmp值設置為10?

public class HelloWorld{ 
         public static void main(String []args){
            child c = new child(4);
            System.out.println(c.getTemp()); // line #4 prints 4
            immutable i = (immutable) c; //line #5
            System.out.println(i.getTemp()); // line #6 prints 4
            c.setTemp(10); //line #7
            System.out.println(i.getTemp()); // line 8 prints 10
         }
    }

    class immutable{
        private int tmp;       
        immutable(){              
        }
        immutable(int val){
            tmp = val;}
        public int getTemp(){
            return tmp; }        
     }

    class child extends immutable{
        private int tmp1;         
        child(){              
        }
        child(int y){
            super(y);
            tmp1= y;
        }
         public int getTemp(){
            return tmp1;}

         public void setTemp(int y){                 
            tmp1 = y;}
    }

忽略這里的樣式和約定錯誤,只關注您的問題。

如果您的課程不是最后的課程,則可能會有子類覆蓋不可變性。 這是一個例子。

這是不可變類

public class Immutable {
 private final int value;

 public Immutable(int value) {
     this.value = value;
 }

 public int getValue() {
     return value;
 }

}

“ Immutable”類不是最終的,因此我可以對其進行擴展。

public class Mutable extends Immutable {
 private int newValue;

 public Mutable(int value) {
     super(value);

     newValue = value;
 }

 public int getValue() {
     return newValue;
 }
 public void setValue(int newValue) {
     this.newValue = newValue;
 }


}

現在到主要班級,

public static void main(String[] arg){
    Immutable immutable = createImmutableObject(10)
    System.out.println(immutable.getValue()); //This prints 10
    mutable.setValue(100);
    System.out.println(immObj.getValue()); //This prints 100
}

private Immutable createImmutableObject(int val){
    return new Mutable(val);
}

在方法createImmutableObject中,我將返回類型為Immutable的引用。 因此,使用API​​的開發人員將假定返回的對象是不可變的。 但是,該對象的類型為Mutable(狀態可以更改),而引用僅是父類的。 我可以更改返回的對象的狀態,這會破壞“不變性”

使class成為final為了使其不可變,從而使其無法擴展並且其方法被覆蓋。 同樣,這也不是使類不可變的唯一方法。

所有Java函數都是虛擬的-意味着,不管變量的聲明類型是什么,您始終可以獲取該方法的基礎類的實現。

這意味着,無論聲明的類型是什么,對c任何引用都將使用c的方法實現。

因此,第5行實際上什么也沒做(如果c不擴展immutable ,它將拋出異常)。

當你調用getTempi ,你是在調用c類的( child的)實施getTemp ,即使類型iimmutable

暫無
暫無

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

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