Java中的最终数组

Java中的以下代码使用Stringfinal数组,这是毫无疑问的。

 final public class Main { public static final String[] CONSTANT_ARRAY = {"I", "can", "never", "change"}; public static void main(String[] args) { for (int x = 0; x < CONSTANT_ARRAY.length; x++) { System.out.print(CONSTANT_ARRAY[x] + " "); } } } 

它在控制台上显示以下输出。

 I can never change 

下面的代码也没有任何问题。

 final public class Main { public static final String[] CONSTANT_ARRAY = {"I", "can", "never", "change"}; public static void main(String[] args) { //CONSTANT_ARRAY={"I", "can", "never", "change"}; //Error - can not assign to final variable CONSTANT_ARRAY. for (int x = 0; x < CONSTANT_ARRAY.length; x++) { System.out.print(CONSTANT_ARRAY[x] + " "); } } } 

显然,注释行会导致指定的错误,因为我们试图重新分配声明的Stringtypes的final数组。


那么下面的代码呢?

 final public class Main { public static final String[] CONSTANT_ARRAY = {"I", "can", "never", "change"}; public static void main(String[] args) { CONSTANT_ARRAY[2] = "always"; //Compiles fine. for (int x = 0; x < CONSTANT_ARRAY.length; x++) { System.out.print(CONSTANT_ARRAY[x] + " "); } } } 

它显示I can always change意味着我们可以设法修改final Stringtypes数组的值。 我们能否以这种方式修改整个arrays而不违反final的规则?

Java中的final影响variables ,它与你指定的对象无关。

 final String[] myArray = { "hi", "there" }; myArray = anotherArray; // Error, you can't do that. myArray is final myArray[0] = "over"; // perfectly fine, final has nothing to do with it 

编辑添加评论:请注意,我说的对象,你正在分配给它 。 在Java中,数组是一个对象。 同样的事情适用于任何其他对象:

 final List<String> myList = new ArrayList<String>(): myList = anotherList; // error, you can't do that myList.add("Hi there!"); // perfectly fine. 

你错误地解释了最后的实现。 final适用于数组对象引用,这意味着一旦启动,引用永远不会改变,但它自己可以填充的数组。 “它没有违反规则”,你只是指定了一个关于正在工作的参考变化的规则。 如果你想要的值也永远不会改变你应该去为不可变列表即

 List<String> items = Collections.unmodifiableList(Arrays.asList("I", "can", "never", "change")); 

你只能这样做,所以数组引用不能被改变。 如果你想要的元素无法改变,你需要使用某种不可修改的集合。

将数组声明为final时,可以更改数组中的元素,但不能更改此数组的引用。

最后只保证原始的不变性。 而且还保证一个variables只被赋值一次。 如果一个对象是可变的,你可以改变它定义为final的事件的内容。 您可以检查您的需求不可变的集合。 如Collections.unmodifiableList() http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#unmodifiableList ( java.util.List )

对数组对象的引用是final的(不能改变,例如,如果你试图将不同的Java数组对象(String []的实例)关联到同一个最终variables,你会得到一个编译时错误)。

但是在你的例子中最后的数组对象的字段不是最终的,所以你可以修改它们的值。 …当您创build的Java对象CONSTANT_ARRAY在接收到初始值之后,将永远具有该值==直到JVM停止。 :)这将是相同的string数组实例“永远”。

Java中的最终variables并不是什么大不了的,只是花点时间仔细地消化这个主题/想法。 🙂
我build议所有不确定要打坐的人,例如: https : //docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4

让我举出相应的部分:

一旦最后一个variables被赋值,它总是包含相同的值,如果最后一个variables持有一个对象的引用,那么该对象的状态可以通过对该对象的操作来改变,但是该variables总是会引用同一个对象。

这也适用于数组,因为数组是对象; 如果最后一个variables持有对数组的引用,那么数组中的组件可能会被数组上的操作所改变,但是variables将始终引用相同的数组。 “

variablesCONSTANT_ARRAY的值不能改变。 该variables包含(引用到)数组。 但是,数组的内容 可以更改。 当你声明任何types的最终variables不是一个简单的标量types(例如一个对象)时,会发生同样的事情。

要小心你如何命名你的variables。 :-)调用它一个CONSTANT_ARRAY不会使数组的内容不可更改。

这里有一个很好的参考: 最后的最后一句话

  final int[] res; int[] res1; int[] res2 = new int[1]; res2[0]=20; res1=res2; res1=res2;//no error System.out.println("res1:"+res1[0]); res = res2;//only once //res = res2;//error already initialised res2[0]=30; System.out.println("res:"+res[0]); 

输出:: res1:20 res:30