不可变类怎么说

时间:2013-10-17 17:05:31

标签: java class immutability

我理解不可变意味着它是一个在实例化后不会改变状态的对象。但是在这行代码中,我没有在声明数组值时看到Final。 这个类是不可变的吗?任何人都可以解释如何找出答案。谢谢

public class A {
private double[] values;
public double[] getValues(){
return values;
 }
}

4 个答案:

答案 0 :(得分:1)

正如其他人所写,这个对象在其状态下被认为是可变的。不可变的是你不能交换它拥有的数组。但是你可以改变数组的内容(getValues()[0] = 10;)。

要将其转换为不可变对象,必须使用List而不是数组。使用列表,您可以使用Collections'方法unmodifiableList将给定列表转换为可以保存到外部的版本。如果getValues()的调用者在不可修改的列表上使用add或remove,则会导致UnsupportedOpertionException,从而使对象保存不被修改。

如果您需要坚持使用数组,则需要提供数组的副本(System.arraycopy)或克隆(clone())。

如果你不能改变它的属性(包括超类中的继承属性),通常认为一个对象是不可变的。这通常包括属性值,但这是一个模糊的定义。

例如,如果您有一个类,其中包含指向文档文件的File实例,并且此File实例无法更改,则该类被视为不可变(它提供的信息永远不会更改),但它指向的文档可以每次都要变异和改变。所以它实际上是一条模糊的线(记住在你的例子中你不能改变数组但是数组的内容)。

答案 1 :(得分:0)

是粘贴的代码没有任何关联的最终关键字,并且没有不可变的行为。

我想提出一些与在java中编写不可变类相关的关键指南:

1。)确保不能覆盖类 - 使类最终,或使用静态工厂并使构造函数保持私有

2。)将字段设为私有和最终字段 强制调用者完全在一个步骤中构造一个对象,而不是使用无参数构造函数和后续调用setXXX方法(即避免Java Beans约定)

3.。)不要提供任何可以以任何方式改变对象状态的方法 - 不仅仅是setXXX方法,还有任何可以改变状态的方法

4。)如果类有任何可变对象字段,那么当它们在类和它的调用者之间传递时,它们必须被防御性地复制

答案 2 :(得分:0)

A a = new A();
a.getValues()[0] = 1.2;

只要值不为空,这将起作用。但是,您无法将值重新分配给新数组。那就是:a.getValues() = new double[5];无效。

该类不是不可变的,因为我可以更改值,而不是重新分配它。

答案 3 :(得分:0)

这是一个简单的验证。值初始化为1,2。

使用getter和引用,可以在创建对象后更改数组中第一项内的值

public class A {
    private double[] values;

    public double[] getValues() {
        return values;
    }

    public static void main(String[] args) {
        A test = new A();
        test.values= new double[]{1, 2};

        double[] valuesref = test.getValues();
        valuesref[0] = 10;

        for (int i = 0; i < test.values.length; i++) {

            System.out.println(test.values[i]);    
        }
    }
}

如果getValues()返回数组的副本,则可以避免这种情况。