2012-07-31 72 views
2

方法参数使用“最终”我认真阅读了这个问题: Can I pass parameters by reference in Java?在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隐式或强制?

我很少用final在Java方法参数,但现在我不能想,你会主动忽略把final的方法参数的任何情况。

谢谢!

+0

您避免使用该参数作为方法中的变量,让它简单的读/理解 – 2012-07-31 09:02:09

+1

当您在方法内部创建匿名内部类,你需要做的参数作为'final'在为了在该匿名类中使用它。 – 2012-07-31 09:03:41

回答

3

通常,您不应该修改参数,因为它可能会导致难以找到错误。但也有一些有用的成语和情况也可以是有用的:

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

好吧,所以绝对只是为了避免在某些情况下创建新变量。要么你对其他开发者有信心,要么让它像那样,要么强迫他们随着时间而变化。 – 2012-07-31 09:11:08

+0

谢谢大家,我随着这个答案走,因为它更接近“哪里不用最后?”。其他答案给了我我已经知道的“final”的好处。 – 2012-07-31 09:17:23

3

我通常这样做是为了防止意外或意外的修改这个参考。例如

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

一个有趣的场景是在setter中。你想确保你设置的成员变量和不是在中传递的参数。例如

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

在上述情况下,如果该方法的参数是决赛,那么我可能设置

arg = arg; 

错误。以上是常见的错字,或者可能因搜索/替换重构而发生。通过最终制定arg,您不会无意中重新分配它。

+0

我同意这一点,但最后为什么有人想改变引用,因为它只会在方法上下文中修改? – 2012-07-31 09:02:49

+0

我已经看到他们使用参数作为变量的代码,他们用参数值做了一些事情,并且在它覆盖它之后用于方法本身 – 2012-07-31 09:04:07

+0

可能避免声明新变量的痛苦吗?这很懒,但有时候人们会做懒惰的事情! – 2012-07-31 09:05:25

2

Java按值传递。所以当你调用mutate时,会传递一个o的副本。

在mutate内部,o的副本被设置为指向“再见”。原始的o不变。

将参数设置为最终不会改变这一点,但正如您所见,它将停止重新分配原始引用的副本。然而,这不同于停止重新分配原始参考。

4

为了避免这种情况:

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

正如你可以看到它使代码不够直观,因为该参数可以持有不同通过的价值。

Hard Core Java - Chapter 2

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

你不能忘记,一旦你写了 的代码,故事还没有结束。人们会在您的代码中进行更改,添加和 错误。你将不得不查看代码并修复一切搞砸了的东西。为了防止occur- 环此问题,执行下列操作:

和类似的样品使用的参数,并且附加地调用其他的方法与所述参数进行(已经改变)。

2

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

mutate(o); 

2.通过使用在Parameterfinal关键字的方法定义,你有使它最终,因此,这意味着本地对象参考变o这是Object类型最后是,所以这个变量不能用来指向任何其他的对象。

注:及其对HEAP的Object Reference Variable这是final不是对象)

mutate(final Object o)

可以分配与对象引用相关的对象。将变量o赋予其他一些对象引用变量,然后将其更改为

Object i = o; 
i = "GoodBye";