繁体   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