private final List<KeyListener> keyListeners= new CopyOnWriteArrayList<KeyListener>();
public void addKeyListener(KeyListener keyListener){
keyListeners.add(keyListener);
}
在上面的代码中,我将keyListeners声明为final,也是线程安全的。我假设最终我的意思是听众的状态在施工后无法改变。但是我在addKeyListener()方法中没有做同样的事情吗?为什么编译器没有给我一个警告?我在这里缺少什么?
答案 0 :(得分:5)
添加final
关键字意味着keyListeners
将在整个程序中指向相同的CopyOnWriteArrayList
。这样做是违法的:
keyListeners = null
但是,keyListeners
的方法仍然可以自由调用。它们是否会影响底层数据结构并不是编译器所关心的。
class Foo {
public int bar = 1;
public static void test() {
final Foo x = new Foo();
//This is perfectly legal:
x.bar = 2;
//This is not:
x = new Foo();
}
}
答案 1 :(得分:3)
Final关键字用于表示该变量只能分配给一次。但即使它“改变”了对象属性,你也可以调用它。
来自JLS:
一旦指定了最终变量,它总是包含相同的值。如果最终变量包含对对象的引用,则可以通过对对象的操作来更改对象的状态,但该变量将始终引用同一对象。
答案 2 :(得分:0)
仅仅因为最终引用了keyListeners的内部地址而不是列表本身。