将方法参数声明为 final 的目的是啥? [复制]

Posted

技术标签:

【中文标题】将方法参数声明为 final 的目的是啥? [复制]【英文标题】:What is the purpose of declaring method parameters final? [duplicate]将方法参数声明为 final 的目的是什么? [复制] 【发布时间】:2017-10-05 07:43:31 【问题描述】:

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

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

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

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

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

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

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

【问题讨论】:

***.com/a/20795203/1008222 所有急于回应或标记为 dup 的人 - 你们的扳机很轻... OP 对参数旁边的 final 关键字的语义表现出完美的理解,他问道出于动机,因为这似乎是对 Java 的多余补充! 而且我相信唯一可能的答案是强制执行“良好做法”(而不是重新分配论点)。除此之外,我认为将论点定为最终论点没有任何附加价值。 @alfasin 您可以阅读骗局,而不是编写这些 cmets。链接的问题还表明您已经写过(例如Why should I use the keyword "final" on a method parameter in Java?)。 一个有趣的(相关的)讨论可以在这里找到:wiki.c2.com/?JavaFinalArguments 【参考方案1】:

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

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

除此之外,如果你需要在该方法中的任何匿名类中使用这个变量,除非它是final的,否则你不能使用它。

希望这会有所帮助。

【讨论】:

虽然重新分配参数是一种不好的做法 - 它在方法之外没有任何影响。如果你有一个 1000 行长的方法,你应该关心的是重构它,而不是最终确定一个参数。 同意。但问题是关于 final 和 final 变量在这种情况下会有所帮助。而且你不能说一个1000行的方法不存在。这取决于。正如我所说,它的信息目的是让第二个程序员不要在应用程序生命的漫长过程中更改变量。【参考方案2】:

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

方法参数是一个局部变量,其值由方法的调用者初始化。使其成为 final 意味着 方法的主体不能在本地为该变量分配新值,因此它只会在方法的主体中产生不同(因为在方法体对方法的调用者没有什么不同)。

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

【讨论】:

OP 明白了,他的问题是动机是什么。由于 Java 是“按 val 传递”并且参数是原始引用的副本(假设它是一个对象),因此重新分配对调用者来说并不重要 - 所以允许参数成为最终参数有什么意义。 参数和局部变量之间没有真正的区别,因为Java是PbV。所以这个问题可以扩展为“为什么要让局部变量成为final”,这个问题已经被问过很多次了。

以上是关于将方法参数声明为 final 的目的是啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Java里的final作用是啥?意思有是啥?大虾解决下

使用 OleDb 参数的目的是啥? [复制]

将 java 方法参数设为 final

Java final关键字

函数参数中裸星号的目的是啥? [复制]

argc 和 argv 的目的是啥? [复制]