如果我在Synapse
是抽象类型的类中有以下语句:
private final List<Synapse> synapses;
final
是否允许我仍然能够更改Synapse
中List
个对象的状态,但阻止我向列表中添加新的Synapse
个对象?如果我错了,请您解释final
正在做什么以及何时应该使用关键字final
。
答案 0 :(得分:30)
不,final关键字不会使列表或其内容不可变。如果你想要一个不可变的List,你应该使用:
List<Synapse> unmodifiableList = Collections.unmodifiableList(synapses);
最终关键字的作用是阻止您为“synapses”变量分配新值。即,你不能写:
final List<Synapse> synapses = createList();
synapses = createNewList();
但是,您可以写道:
List<Synapse> synapses = createList();
synapses = createNewList();
答案 1 :(得分:5)
final
阻止您在分配一次后重新分配 synapses
- 您仍然可以像平常一样添加/删除元素。您可以详细了解final
关键字here。
答案 2 :(得分:3)
Java语言规范writes:
变量可以声明为final。最终变量只能分配一次。声明变量final可以作为有用的文档,它的值不会改变,可以帮助避免编程错误。
如果分配了最终变量,那么这是一个编译时错误,除非在分配之前它是明确未分配的(§16)。
空白决赛是一个最终变量,其声明缺少初始值。
一旦指定了最终变量,它总是包含相同的值。如果最终变量包含对对象的引用,则可以通过对对象的操作来更改对象的状态,但该变量将始终引用同一对象。
因此,如果您希望强制通过变量可以访问的状态不会更改,则必须声明变量final
,使用不可修改的List(例如使用Collections.unmodifiableList),并且make Synapse
个对象是不可变的。
答案 3 :(得分:2)
您仍然可以更改,添加和删除列表的内容,但无法创建分配给变量的新列表。
答案 4 :(得分:1)
最终实现意味着对象引用一旦启动,引用本身就永远不会改变,但内容当然可以。它根本没有违反规则。您只指定了一个有关相应工作的引用更改的规则。如果你想要值也应该永远不会改变你应该去不可变列表,即
List<String> items = Collections.unmodifiableList(Arrays.asList("a", "b", "c"));
请参阅以下相关问题。
答案 5 :(得分:0)
以上答案从理论上解释了全部,您可以找到要运行的代码并查看实际差异,建议使用局部变量
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)