在Java中使用“final”作为方法参数

时间:2012-07-31 08:59:38

标签: java methods parameters final

我感兴趣地阅读了这个问题: Can I pass parameters by reference in Java?

通过复制参考值传递参数(不是基元)。 因此,例子说明;你不能修改你给出的参数的参考:

Object o = "Hello";
mutate(o)
System.out.println(o); // Will print Hello

private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o!

使用final这样的问题可以避免这种问题:

private void mutate(final Object o) { o = "Goodbye"; } //Compilation error

问题:

  • 在这种情况下,final关键字是否仅用于抛出编译错误?
  • 如果最后你无法修改给定参数的引用,为什么final不是隐式或强制的?

我很少在Java中使用final作为方法参数,但现在我无法想到你会自愿省略将final放入方法参数的任何情况。

谢谢!

5 个答案:

答案 0 :(得分:4)

为避免这种情况:

public void searchBiggest(String startingWith) {
    for (String s : collection) {
        if (s.startsWith(startingWith)) {
            startingWith = s;
        }
    }
    return startingWith;
}

正如您所看到的,它使代码不直观,因为参数可能保持与传递的值不同的值。

来自Hard Core Java - Chapter 2

  像这样的小虫子往往是最难找到的。通过   墨菲定律,你绝对可以保证这段代码会在   项目的一大块中间,错误报告   不会直接带你到这里。更重要的是,你可能不会注意到   bug直到它投入生产和用户的影响   尖叫着修复。

     

一旦你写作,你就不能忘记   代码,故事还没有结束。人们会做出改变,补充和改变   代码中的错误。您将不得不查看代码并修复   一切都搞砸了。为防止此问题发生 -   戒指,请执行以下操作:

并使用参数完成类似的示例,并使用参数(已更改)另外调用其他方法。

答案 1 :(得分:3)

我通常这样做是为了防止此引用的意外或意外修改。例如

private String doSomething(final String arg) {
   // final to prevent me doing something stupid!
}

一个有趣的场景是制定者。您希望确保设置成员变量而不是中传递的arg。 e.g。

public void setArg(String arg) {
   _arg = arg;
}

在上面的场景中,如果方法参数不是 final,那么我可以设置

   arg = arg;

错误。以上是一个常见的拼写错误,或者可能由于搜索/替换重构而发生。通过arg最终,您不会意外地重新分配它。

答案 2 :(得分:3)

通常,您不应修改参数,因为它可能会导致很难找到错误。然而,有一些有用的习语和情况可能有用:

public void print(String msg, int count) {
    msg = (msg != null)? msg : "Default";
    while(--count >= 0) {
        System.out.println(msg);
    }
}

答案 3 :(得分:2)

Java按值传递。因此,当您调用mutate时,会传递o的副本。

在mutate中,然后将o的副本设置为指向“Goodbye”。原来的o没有变化。

将参数设置为final将不会更改此值,但正如您所见,它将停止重新分配原始引用的副本。然而,这不同于停止重新分配原始参考文献。

答案 4 :(得分:2)

1。当您通过调用方法调用该方法时,您将Object Reference Variable作为参数传递。

    mutate(o);

2。在方法定义中使用final上的Parameter关键字,使其成为最终,这意味着本地对象参考变量 o 类型的对象是最终的,因此此变量不能用于指向任何其他对象。

注意:Object Reference Variablefinal不是HEAP上的对象

mutate(final Object o)

3. 您可以将与对象引用变量o关联的对象分配给其他对象引用变量,然后进行更改

Object i = o;
 i = "GoodBye";