&引用;“最后的”;在java中复制二维数组
我在理解Java中“final”的概念时有点困难 我的课程如下:&引用;“最后的”;在java中复制二维数组,java,clone,final,multidimensional-array,Java,Clone,Final,Multidimensional Array,我在理解Java中“final”的概念时有点困难 我的课程如下: public class MyClass { private int[][] myArray; // intended to be changed private final int[][] MYARRAY_ORIGINAL; // intended to be unchangable public MyClass(int[][] array) { myArray
public class MyClass
{
private int[][] myArray; // intended to be changed
private final int[][] MYARRAY_ORIGINAL; // intended to be unchangable
public MyClass(int[][] array)
{
myArray = array;
MYARRAY_ORIGINAL = array;
}
}
我的理解是“final”将使我的数组成为只读的。但我试过编辑myArray,它也会编辑myArray_ORIGINAL。我的问题是,在这种情况下,“最终”到底是做什么的?为了获得额外的积分,我如何将通过构造函数传递的数组复制到MYARRAY_ORIGINAL中,这样我就可以有两个数组,一个要编辑,另一个要保留
感谢高级。对于
对象
,最终
使引用无法更改,但对象状态可以更改
这就是为什么您能够更改
final MYARRAY\u ORIGINAL
的值的原因。您的final MYARRAY\u ORIGINAL
实际上是只读的:除了类构造函数或属性声明之外,您不能将新值分配给MYARRAY\u ORIGINAL
引用:
public void someMethod() {
//it won't compile
MYARRAY_ORIGINAL = new int[X][];
}
数组中的值不是最终值。这些值可以在代码中随时更改
public void anotherMethod() {
MYARRAY_ORIGINAL[0][0] = 25;
//later in the code...
MYARRAY_ORIGINAL[0][0] = 30; //it works!
}
如果您确实需要一个最终元素列表,换句话说,一个元素无法修改的列表,您可以使用:
List items=Collections.unmodifiableList(Arrays.asList(0,1,2,3));
最后一段代码取自此处:
MYARRAY\u ORIGINAL
确实是只读变量。不能为数组引用指定新值,也不能更改其数组长度。最终的变量初始化可以推迟到调用构造函数。如果试图修改最终变量的引用,编译器将抛出错误消息。但可能的是,可以编辑MYARRAY\u ORIGINAL
和MYARRAY
的元素,即可以更改分配给最终变量的对象的状态。比如说
甲级{
最终int[]数组
public A() {
array = new int[10] // deferred initialization of a final variable
array[0] = 10;
}
public void method() {
array[0] = 3; // it is allowed
array = new int[20] // not allowed and compiler will throw an error
}
}
要了解有关final的更多信息,请查看on final变量。final本身并不意味着“只读”,但对于定义它的线程以外的其他线程来说更是“安全发布”。final的另一个目的是确保在多线程环境中提供最新的对象 其次,如果您将某事物定义为“最终”,例如:
private final int[][] MYARRAY_ORIGINAL;
参考是“最终的”,但不是对象本身。更好的理解方法是:
public static final List myList = new ArrayList();
现在我可以从任何其他线程访问myList—我可以修改它(添加到它);但我不能
(a) 再次声明-myList=newarraylist();
(b) 给它分配另一个列表-myList=anotherList
在多线程场景中,我最了解final的上下文
奖励:要回答您的问题,您不能创建“只读”数组,您必须自己管理该数组(最终,只维护“只读”以引用非对象)您可以使用该方法创建数组的副本,如下所示-
int[][] source = {{1,2},{3,4}};
int[][] copy = new int[source.length][];
System.arraycopy(source, 0, copy, 0, source.length);
此外,您的代码在尝试执行的操作方面也存在一些问题
public MyClass(int[][] array) { //something else passes the array
myArray = array;
MYARRAY_ORIGINAL = array; // you are just keeping a reference to it can be modified from outside
}
如果您真的不希望任何人修改该数组中的值MYARRAY\u ORIGINAL
,您应该制作一份来自外部的源数组的副本
public MyClass(int[][] array) {
myArray = array; //make a copy here also if you don't want to edit the argument array
MYARRAY_ORIGINAL = new int[array.length][];
System.arraycopy(array, 0, MYARRAY_ORIGINAL, 0, array.length);
}
现在,您不必担心数组被从外部修改。感谢您的回答Luiggi。另一个快速跟进问题是,您认为我应该怎么做才能实现两个数组,一个用于编辑,一个用于原始?有没有比循环二维数组并复制所有值更方便的方法?@DavisSmith使用上一次编辑中显示的不可修改列表,或为不可修改数组创建类包装器,并确保此类永远不会修改数组元素。如果您想要简单的方法,请使用第一个选项,如果您无法使用
列表
界面,请使用第二个选项。
public MyClass(int[][] array) {
myArray = array; //make a copy here also if you don't want to edit the argument array
MYARRAY_ORIGINAL = new int[array.length][];
System.arraycopy(array, 0, MYARRAY_ORIGINAL, 0, array.length);
}