【问题标题】:Why is it considered good practice to mark method parameters as final? [duplicate]为什么将方法参数标记为 final 被认为是一种好习惯? [复制]
【发布时间】:2014-03-01 02:50:26
【问题描述】:

假设我有一个通过传递对象来调用的方法。

public String retrieveXyz(Criteria criteria){

//get some info out of criteria and do something.

}

将标准设为最终标准是否是一种好习惯,以便此处理程序不能用于针对传递的对象以外的其他对象或其开销,因为这不能保护对象状态不被更改。

public String retrieveXyz(final Criteria criteria){

//get some info out of criteria and do something.

}

【问题讨论】:

  • 我从来不用final方法参数。我很好奇为什么它们实际上是为了。
  • 如果您在函数内更改criteria 中保存的引用,它不会更改所保存的函数外部变量的引用。
  • @Antoniossss 当您需要在接口的匿名实现中使用此参数时,它很有用,例如实现Runnable 以在您的方法中使用线程。
  • stackoverflow.com/questions/316352/… duplicate 如果您尝试修改引用,这允许编译器优化以及有用的警告。您当然应该这样做,并在您的 IDE 中打开自动为您执行此操作的设置。
  • @Stretch 你真的在你的代码中这样做了吗?冗长的代价很高,这是我不使用它的唯一原因。许多人会同意 final 应该是默认值,并且必须使用 var 或类似名称将变量标记为非最终变量。

标签: java oop final


【解决方案1】:

如果将方法参数标记为final,则不能在方法范围内修改参数的值:

public void xyz(final String parameter) {
    parameter = "..." //compiler error!
}

明白parameter的值是对传递给方法的对象的引用,而不是对象本身的值。

通过将方法参数标记为final,编译器将在编译时抛出错误。这提醒您不要在方法中修改参数的值。

在您的方法中修改原始参数被认为是一种不好的做法。[1]

如果参数的值可以更改以引用另一个对象,则可能无法立即清楚地在方法主体内的任何给定点引用哪个对象。

考虑以下几点:

public void xyz(String parameter) {
    //Complicated logic that might span 20-30 lines.

    parameter = "Joe";

    //More complicated logic that might span a few lines.

    //New logic being added that needs reference to the value of the parameter.
}

在像上面这样的复杂方法中,程序员可能很难识别parameter 引用的对象。此外,如果程序员需要对parameter 的引用,他就不再拥有了。


  1. Is it a good practice to change arguments in Java

【讨论】:

  • 这似乎是这里最准确的答案,不过,我相信它可以使用一点语言清理。你介意我们帮助@AlfredoCasado 吗?
  • 非常感谢任何对我英语的帮助!谢谢。
  • 我已经编辑了答案,希望它用英文写得更清楚。如果我说的不正确,请更改它!谢谢。
  • 另外,如果有人能帮我找到一个可靠的参考资料,说明更改原始参数是不好的做法,那就太好了。
【解决方案2】:

方法参数中的final在大多数情况下没有区别,你仍然不能在方法内部改变它的地址,但它的属性是可以改变的。

你可能需要使用final 有时当你有类似下面的东西时,除非a 是最终的,否则不会编译运行方法,虽然你可以将它分配给其他最终对象等,但为什么要这么麻烦。

public void foo(final String a) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            System.out.print(a);
        }
    }); 
}

【讨论】:

  • 在下面借用@delnan 的评论:“嗯,呵呵。使 x 不可变并不能防止 y 的突变。这并不意味着它没有意义。”
  • 首先,你并没有让它不可变,不可变肯定会阻止改变,final关键字只是让它你不能改变它在内存中的地址。我实际上无法理解您在此评论中想要表达的意思。
  • 重点是没有人应该指望final 会阻止修改对象的字段。应该只期望防止重新分配final 应用的变量。因此,您关于 “您仍然无法在方法内更改其地址,但可以更改其属性。” 的言论并没有为对话添加任何有意义的内容。
  • 正在使“它”不可变。其中“它”指的是参考。是的,对象仍然是可变的,是的,这并不理想,但还有其他一些东西的可变性是令人感兴趣的。
  • @crush,只是仔细检查了这个问题,你是对的,问题已经提到了我错过的对象状态。
【解决方案3】:

PMD 建议您这样做:http://pmd.sourceforge.net/pmd-4.3/rules/optimizations.html

这允许进行有用的优化,并在您可能在代码中做一些不受欢迎的事情时发出警告。像 Eclipse 和 Intellij 这样的 IDE 可以选择自动执行此操作,这样做是明智的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-04
    • 2012-12-01
    • 2014-08-12
    • 1970-01-01
    • 2018-05-18
    相关资源
    最近更新 更多