Java中的以下代码使用final
String
数组,对此毫无疑问。
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] + " ");
}
}
}
显然,注释行会导致指定的错误,因为我们正在尝试重新分配类型为final
的声明的String
数组。
以下代码如何。
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
类型String
数组的值。我们能否以这种方式修改整个数组而不违反final
的规则?
答案 0 :(得分:87)
final
会影响变量,它与您分配给它的对象无关。
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.
答案 1 :(得分:15)
您误解了最终的实施。 final
适用于数组对象引用,这意味着一旦启动它,引用就永远不会改变,但可以填充其自身的数组。 “它没有违反规则”你只指定了一个关于参考变化的规则,它正在相应地工作。如果你想要值也应该永远不会改变,你应该选择不可变列表,即
List<String> items = Collections.unmodifiableList(Arrays.asList("I", "can", "never", "change"));
答案 2 :(得分:10)
您只能使它无法更改数组引用。如果您希望无法更改元素,则需要使用某种类型的不可修改的集合。
答案 3 :(得分:3)
将数组声明为final时,可以更改数组中的元素,但不能更改此数组的引用。
答案 4 :(得分:3)
final只保证原语的不变性。并且还保证变量仅分配一次。如果一个对象是可变的,你可以改变它定义为final的事件的内容。您可以根据需要检查不可变集合。例如Collections.unmodifiableList() http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#unmodifiableList(java.util.List)
答案 5 :(得分:2)
对数组对象的引用是final(无法更改,例如,如果您尝试将不同的Java数组对象(String []的实例)关联到同一个最终变量...您将获得一个编译时错误。)
但是示例中最终数组对象的字段不是final,因此您可以修改它们的值。 ...当您创建的Java对象CONSTANT_ARRAY收到初始值后,将具有该值&#34; forever&#34; ==直到JVM停止。 :)它将是相同的String Array实例&#34; forever&#34;。
Java中的最终变量并不是什么大不了的事,只是花一些时间仔细消化主题/想法。 :-)
我建议所有那些不确定冥想这个页面的人,例如:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4
让我引用相应的部分:
&#34; 一旦分配了最终变量,它总是包含相同的值。如果final变量保存对象的引用,则对象的状态可能会被对象上的操作更改,但变量将始终引用同一对象。
这也适用于数组,因为数组是对象;如果最终变量包含对数组的引用,则数组的组件可能会被数组上的操作更改,但变量将始终引用相同的数组。&#34;
答案 6 :(得分:1)
变量CONSTANT_ARRAY的值不能更改。该变量包含(引用)数组。但是,数组的内容可以更改。当您声明任何不是简单标量类型的最终变量(例如对象)时,也会发生同样的事情。
小心如何命名变量。 :-)将其称为CONSTANT_ARRAY不会使数组的内容不可更改。
这是一个很好的参考:The final word on final
答案 7 :(得分:0)
使用final关键字声明变量时,其值本质上不能修改为常量。这也意味着您必须初始化一个最终变量。如果最终变量是引用,则意味着该变量不能重新绑定以引用另一个对象,而是内部状态可以更改该引用变量指向的对象,即可以在最终数组或最终集合中添加或删除元素。
答案 8 :(得分:-1)
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