将方法参数声明为 final 的目的是什么?

What is the purpose of declaring method parameters final?

所以我完全可以理解为什么您可能想要 class final。想象一下 String class 不是最终的,并且您有一个库,其中有一个方法将 String 作为参数并依赖于 length() 方法进行某些操作,但是有人扩展了 String class 并将长度覆盖为 return -1 always..

但我不明白为什么有人会声明方法的参数为 final。 Java 无论如何都是按值传递的,所以如果参数是原始参数,它已经是最终的(在某种意义上)。如果你传递的是引用类型,它会向方法的调用者保证任何事情吗?我不这么认为..

void foo(final List<Object> o) {
    o.add(new Object());
} // oops?

所以 final 可以防止以下情况:

void foo(final List<Object> o) {
    o = new ArrayList();
}

但我为什么要这样做呢?我总是可以创建一个新变量,并且它不会将新对象分配给调用者的变量吗? (我的意思是,无论如何我都无法更改调用者引用所指的内容,即使参数未声明为 final..)

我的问题是,方法声明中最终参数的用途是什么?是给来电者的吗?它能保证什么吗?

我也觉得奇怪的是下面的代码可以正常编译:

public interface MyInterface {
    void foo(final Object o);
}

class MyImpl implements MyInterface {
    @Override
    public void foo(Object o) { // final in interface, not final in impl..
    }
}

但一旦我理解了我的主要问题,也许它会有意义。

它不向调用者保证任何方式(无论参数是原始类型还是引用类型)。

方法参数是一个局部变量,其值由方法的调用者初始化。使其最终化意味着 方法主体无法在本地为该变量分配新值 ,因此它只会在方法主体内产生不同(因为为这样的变量分配新值方法体内的变量对方法的调用者没有影响)。

它确保方法主体中使用参数值的任何代码都将使用调用者传递的原始值,而不是在方法主体中分配给它的其他值。

有时,这有助于其他程序员或维护人员不应该更改该变量的值。

例如:想象一个方法接受一个字符串参数。想象一下,这是一个具有 1000 行代码的非常长的方法。如果参数未标记为最终参数,则第二个程序员会看到更改其中值的机会。第一个程序员在不知道变量被分配了新值的情况下恢复了方法的工作。 使其成为最终版本将充分确保第一个程序员的意图传递给第二个。

除此之外,如果您需要在该方法中的任何匿名class中使用此变量,除非它是最终的,否则您不能使用它。

希望对您有所帮助。