Synapse
如果我在一个抽象类型的类中有以下语句:
private final List<Synapse> synapses;
是否final
允许我仍然能够更改 中Synapse
对象的状态List
,但阻止我将新Synapse
对象添加到列表中?如果我错了,您能否解释一下我final
在做什么以及何时应该使用关键字final
。
不,final 关键字不会使列表或其内容不可变。如果你想要一个不可变的列表,你应该使用:
List<Synapse> unmodifiableList = Collections.unmodifiableList(synapses);
final 关键字的作用是阻止您为“突触”变量分配新值。即,你不能写:
final List<Synapse> synapses = createList();
synapses = createNewList();
但是,您可以编写:
List<Synapse> synapses = createList();
synapses = createNewList();
本质上,您仍然可以更改、添加和删除列表的内容,但不能创建分配给变量突触的新列表。
final
阻止您在分配 synapses
一次后重新分配 - 您仍然可以像往常一样添加/删除元素。您可以在此处阅读有关该final
关键字的更多信息。
您仍然可以更改、添加和删除列表的内容,但不能创建分配给变量的新列表。
Java 语言规范写道:
变量可以声明为final。最终变量只能分配一次。声明一个变量 final 可以作为有用的文档,说明它的值不会改变,并且可以帮助避免编程错误。
如果最终变量被分配给它是一个编译时错误,除非它在分配之前立即被明确地未分配(第 16 节)。
空白 final 是一个 final 变量,其声明缺少初始化程序。
一旦分配了最终变量,它总是包含相同的值。如果最终变量持有对对象的引用,则对象的状态可能会通过对对象的操作而改变,但变量将始终引用同一个对象。
因此,如果您希望强制通过变量可访问的状态不会改变,您必须声明变量final
,使用不可修改的列表(例如Collections.unmodifiableList),并使Synapse
对象不可变。
最终实现意味着对象引用一旦启动,引用本身就永远不能改变,但内容当然可以。它根本不违反规则。您只指定了一个关于参考更改的规则,该规则正在相应地起作用。如果您希望这些值也永远不会改变,您应该选择不可变列表,即
List<String> items = Collections.unmodifiableList(Arrays.asList("a", "b", "c"));
请参阅以下相关问题。
以上答案在理论上解释了所有here你可以找到运行代码并查看实际差异,建议使用本地变量
package exp_test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class testList {
final static List<String> synapses = new ArrayList();;
public static void main(String[] args) {
synapses.add("A");
System.out.println(synapses);
//
System.out.println(finalLisTest(synapses));
//
System.out.println(synapses);
//
synapses.add("B");
List<String> unmodifiableList = Collections.unmodifiableList(synapses);
System.out.println(finalLisTest(unmodifiableList));
//
System.out.println(unmodifiableList);
}
private static List finalLisTest(List<String> list) {
list.remove(0);
return null;
}
}
结果 :
[A]
null
[]
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableList.remove(Collections.java:1317)
at exp_test.testList.finalLisTest(testList.java:29)
at exp_test.testList.main(testList.java:22)