[英]My Face class does not seem to be immutable even though I already declared it as final, how do I correct it?
I am trying to make my Face class immutable such that my Face object will not change once it has been initialized. 我正在尝试使我的Face类不可变,以使Face对象一旦初始化就不会更改。 This is what I have so far:
这是我到目前为止的内容:
public class Face{
protected final int[][] grid;
protected Face half;
public Face(int[][] grid){
this.grid = grid;
}
public Face rotateRight(){
int rows = 3;
int cols = 3;
int[][] transposedArray = new int[3][3];
for (int i = 0; i<rows; i++){
for (int j = 0; j<cols; j++){
transposedArray[i][j]=grid[rows-j-1][i];
}
}
return new Face(transposedArray);
}
public Face rotateLeft(){
int rows = 3;
int cols = 3;
int[][] transposedArray = new int[3][3];
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
transposedArray[2-j][i] = grid[i][j];
}
}
return new Face(transposedArray);
}
public Face rotateHalf(){
half = this.rotateRight();
half = half.rotateRight();
return half;
}
public int[][] getGrid(){
return (this.grid).clone();
}
public String toString(){
String str = "";
for (int i = 0; i<3;i++){
for (int j = 0; j<3; j++){
str += String.format("%02d",grid[i][j]);
}
}
String str1 = str.substring(0,6);
String str2 = str.substring(6,12);
String str3 = str.substring(12,18);
return str1+"\n"+str2+"\n"+str3;
}
}
However, when I try to run the following: 但是,当我尝试运行以下命令时:
int[][] g = f.getGrid();
g[1][1] = 9;
I expect f to remain as 我希望f保持为
010203
040507
070809
but I end up getting 但我最终得到
010203
040906
070809
instead. 代替。 Is my Face object not made immutable even though I have already declared the class as final?
即使我已经将该类声明为final,我的Face对象也不会保持不变吗?
You need to make a defensive copy of the input grid
in the constructor. 您需要在构造函数中创建输
grid
的防御性副本。
Also, the fields should be private
as well, and the class should be final
too, although I suspect those last two points are not the cause of your problem. 同样,这些字段也应该是
private
,并且该类也应该是final
,尽管我怀疑最后两点不是造成问题的原因。
Not tested: 未经测试:
public Face(int[][] grid){
int temp[][] = new int[ grid.length ][];
for( int i = 0; i < temp.length; i++ )
temp[i] = Arrays.copyOf( grid[i], grid[i].length );
this.grid = temp;
}
Your problem could be that your constructor doesn't clone the incoming array. 您的问题可能是您的构造函数没有克隆传入的数组。 So maybe the code that creates the Face class instance later manipulates the array it passed to the new Face object!
因此,也许创建Face类实例的代码稍后会操纵它传递给新Face对象的数组!
Unfortunately, there is no way to create truly immutable arrays in the Java. 不幸的是,没有办法在Java中创建真正的不可变数组。 Declaring an array as final only prevents you from changing the array as a whole, it is still possible to change individual rows, columns, slots in that array.
将数组声明为final只会阻止您整体更改数组,仍然可以更改该数组中的各个行,列,插槽。
If you want immutable collections, you need to turn actual Collection classes and then use the methods within the Collections class to create unmodifiable views over them. 如果要使用不可变的集合,则需要打开实际的Collection类,然后使用Collections类中的方法在其上创建不可修改的视图。
Be careful when using clone
. 使用
clone
时要小心。
On arrays, it does a shallow copy. 在阵列上,它会进行浅表复制。 The following snippet explains it better:
以下代码片段对其进行了更好的解释:
int[] c0 = new int[]{1, 2, 3};
int[] c1 = new int[]{4, 5, 6};
int[] c2 = new int[]{7, 8, 9};
int[][] grid = new int[][]{c0, c1, c2};
int[][] cloned = grid.clone();
assert cloned[0] == c0;
assert cloned[1] == c1;
assert cloned[2] == c2;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.