我理解不可变意味着它是一个在实例化后不会改变状态的对象。但是在这行代码中,我没有在声明数组值时看到Final。 这个类是不可变的吗?任何人都可以解释如何找出答案。谢谢
public class A {
private double[] values;
public double[] getValues(){
return values;
}
}
答案 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()返回数组的副本,则可以避免这种情况。