将java方法参数作为final

时间:2010-11-12 07:38:40

标签: java methods arguments final

final在下面的代码之间有什么不同。将参数声明为final是否有任何优势。

public String changeTimezone( Timestamp stamp, Timezone fTz, Timezone toTz){  
    return ....
}

public String changeTimezone(final Timestamp stamp, final Timezone fTz, 
        final Timezone toTz){
    return ....
}

11 个答案:

答案 0 :(得分:103)

由于正式方法参数是局部变量,因此只有在声明为final的情况下,才能从内部匿名类访问它们。

这样可以避免在方法体中声明另一个局部最终变量:

 void m(final int param) {
        new Thread(new Runnable() {
            public void run() {
                System.err.println(param);
            }
        }).start();
    }

答案 1 :(得分:36)

摘自The final word on the final keyword

  

最终参数

     

以下示例声明了最终参数:

public void doSomething(final int i, final int j)
{
  // cannot change the value of i or j here...
  // any change would be visible only inside the method...
}
  这里使用

final来确保两者   索引i和j不会意外   通过该方法重置。这是一种方便的方式   防止阴险的虫子   错误地改变了它的价值   你的参数。一般来说,   简短的方法是一种更好的方法   保护免受这类错误的影响,但是   最终参数可能很有用   除了你的编码风格。

     

请注意,最终参数不是   被认为是该方法的一部分   签名,并被忽略   解析方法调用时的编译器。   参数可以声明为final(或   不)对如何影响   方法被覆盖。

答案 2 :(得分:22)

最终会阻止您为变量分配新值,这有助于捕获拼写错误。从风格上讲,您可能希望保持接收的参数不变并仅分配给局部变量,因此最终将有助于强制执行该样式。

必须承认我很少记得使用final作为参数,也许我应该。

public int example(final int basicRate){
    int discountRate;

    discountRate = basicRate - 10;
    // ... lots of code here 
    if ( isGoldCustomer ) {
        basicRate--;  // typo, we intended to say discountRate--, final catches this
    }
    // ... more code here

    return discountRate;
}

答案 3 :(得分:13)

它并没有太大的区别。这只是意味着你不能写:

stamp = null;
fTz = new ...;

但你仍然可以写:

stamp.setXXX(...);
fTz.setXXX(...);

这主要是对维护程序员的一个暗示,即你不会在方法中间的某个地方为参数分配一个新值,因为它不明显,可能会引起混淆。

答案 4 :(得分:3)

用于Java中的参数/变量的final关键字将引用标记为final。在将对象传递给另一个方法的情况下,系统会创建引用变量的副本并将其传递给方法。通过将新引用标记为final,可以保护它们不被重新分配。它被认为有时是一种很好的编码实践。

答案 5 :(得分:2)

对于此方法的主体,final关键字将阻止意外重新分配参数引用,从而在这些情况下给出编译错误(大多数IDE会立即抱怨)。有些人可能会争辩说,尽可能使用final会加快速度,但最近的JVM并非如此。

答案 6 :(得分:0)

它只是Java中的一个构造,可以帮助您定义合同并坚持使用它。这里有类似的讨论:http://c2.com/cgi/wiki?JavaFinalConsideredEvil

BTW - (正如twiki所说),如果你遵循良好的编程原则并且重新分配/重新定义传入的参数引用,那么将args标记为final是通常多余的。

在最坏的情况下,如果你重新定义args引用,它不会影响传递给函数的实际值 - 因为只传递了一个引用。

答案 7 :(得分:0)

我说的是标记变量和字段的最终结果 - 不仅仅适用于方法参数。 (标记方法/类最终是完全不同的东西)。

这对您的代码的读者/未来维护者有利。与变量的合理名称一起,它对您的代码的读者有用并且让人放心,以查看/理解所讨论的变量代表什么 - 并且让读者放心,无论何时在同一范围内看到变量,其含义都保持不变同样,所以他不必挠头,总是弄清楚变量在每种情况下的含义。我们已经看到太多滥用“重复使用”变量的行为,这使得即使很短的代码片段难以理解。

答案 8 :(得分:0)

-过去(在Java 8之前:-))

快速使用“ final”关键字会影响内部匿名类的方法变量的可访问性。

-在现代(Java 8+)语言中,无需进行此类使用:

Java引入了“有效的最终”变量。如果代码不暗示变量值的更改,则将局部变量和方法参数假定为最终变量。因此,如果您在Java8 +中看到这样的关键字,则可以认为它是不必要的。引入“有效最终”使我们在使用lambda时键入的代码更少。

答案 9 :(得分:0)

列出了我看到的两个优点:

1 将方法参数标记为final可以防止在方法内部重新分配参数

从您的示例

public String changeTimezone(最终时间戳记,最终时区fTz,         最终时区toTz){

fTz = Calendar.getInstance()。getTimeZone(); //这会导致编译错误,因为fTz被标记为最终参数

返回..

}

在一个复杂的方法中,将参数标记为final将有助于意外地将这些参数解释为方法的局部变量,而重新分配为编译器将标记这些情况,如示例所示。

2 将参数传递给匿名内部类

由于形式方法的参数是局部变量,因此只有在内部匿名类中将它们声明为final时,您才可以访问它们。

答案 10 :(得分:-3)

final关键字会阻止您为参数指定新值。我想用一个简单的例子来解释这个

假设我们有一个方法

  

方法1(){

     

日期dateOfBirth =新日期(“1/1/2009”);

     

方法2(DATEOFBIRTH);

     

方法3(DATEOFBIRTH); }

     

public mehod2(Date dateOfBirth){
  ....
  ....
  ....
  }

     

public mehod2(Date dateOfBirth){
  ....
  ....
  ....
  }

在上面的情况下,如果在method2中为“dateOfBirth”分配了新值,则会导致method3输出错误。因为传递给method3的值不是传递给method2之前的值。所以要避免这个最终关键字用于参数。

这也是Java编码最佳实践之一。