为什么要使类最终创建不可变对象

时间:2018-04-05 02:40:42

标签: java data-structures

我正在尝试按照以下代码操作。我不确定第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;}
    }

3 个答案:

答案 0 :(得分:2)

忽略此处的样式和常规错误,只关注您的问题。

如果您的课程不是最终的,则子类可能会覆盖Immutability。这是一个例子。

这是Immutable类

public class Immutable {
 private final int value;

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

 public int getValue() {
     return value;
 }

}

班级"不变的"不是最终的,所以我可以扩展它。

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(其状态可以更改),并且该引用只是父类的引用。我可以改变返回对象的状态,这会破坏"不变性"

答案 1 :(得分:0)

使类final成为不可变的,这样它就无法扩展并覆盖其方法。此外,这不是您使该类不可变的唯一方法。

答案 2 :(得分:0)

所有Java函数都是虚函数 - 意思是,无论声明的变量类型是什么,您总是得到底层类的方法实现。

这意味着,无论声明的类型如何,您对c的任何引用都将使用c的方法实现。

因此,第5行实际上没有做任何事情(如果c没有扩展immutable,它会抛出异常。)

当您在getTemp上致电i时,您正在调用c类(childgetTemp的实施,即使类型为i immutableParameter 0 of constructor in com.kafkastreams.service.GreetingsSender required a bean of type 'com.kafkastreams.stream.GreetingsStreams' that could not be found.