将java方法参数作为最终参数

将java方法参数作为最终参数,java,methods,arguments,final,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 ...

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 ....
}

这没什么区别。这只是意味着你不能写:

stamp = null;
fTz = new ...;
但你仍然可以写:

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

<> P>这主要是对维护程序的提示,它告诉你,在你的方法中间某个地方不给参数分配新的值,因为它不明显,因此可能引起混淆。

< P>最后阻止你给变量分配新的值,这对捕获错误有帮助。从风格上来说,您可能希望保持接收到的参数不变,并且只分配给局部变量,因此final将有助于强制执行该风格

我必须承认我很少记得用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;
}

它只是Java中的一个构造,可以帮助您定义合同并遵守它。类似的讨论如下:

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


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

由于形式化方法参数是局部变量,因此只有当它们声明为final时,才能从内部匿名类访问它们

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

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

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

摘自

最终参数

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

这里使用final来确保 索引i和j不会意外地 通过该方法重置。这是一个方便的方法 为了防止潜在的错误 这会错误地改变 你的参数。一般来说,, 短方法是一种更好的方法 防止此类错误,但是 最终参数可能是有用的 除了你的编码风格

请注意,最终参数不是 被认为是方法的一部分 签名,并被 解析方法调用时使用编译器。 参数可以声明为final(或final) 不)不影响 方法被重写


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

我说的是将变量和字段标记为final,这不仅仅适用于方法参数。(将方法/类标记为final完全是另一回事)


这对您的代码的读者/未来的维护者是一种帮助。加上变量的合理名称,让代码的读者看到/理解所讨论的变量代表的内容是很有帮助和放心的,而且让读者放心的是,无论何时在同一范围内看到变量,其含义都是相同的,因此他不必绞尽脑汁去弄清楚变量在任何情况下都意味着什么。我们已经看到太多的“重复使用”变量的滥用,这使得即使是很短的代码片段也很难理解。

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

假设我们有一个方法

方法1(){

出生日期=新日期(“2009年1月1日”)

方法2(出生日期)

方法3(出生日期);}

公共mehod2(出生日期){
..
..
..
}

公共mehod2(出生日期){
..
..
..
}

在上述情况下,如果在method2中为“dateOfBirth”分配了新值,则这将导致method3的错误输出。因为传递给method3的值与传递给method2之前的值不同。因此,为了避免最后一个关键字用于参数

这也是Java编码的最佳实践之一。-过去(在Java 8:-)之前)

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

-在现代(Java 8+)语言中,不需要这样的用法:


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

我看到的两个优点如下:

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

    public String changeTimezone(final Timestamp stamp, final Timezone fTz, 
            final Timezone toTz){
    
    // THIS WILL CAUSE COMPILATION ERROR as fTz is marked as final argument

      fTz = Calendar.getInstance().getTimeZone();     
      return ..
    
    }
在复杂的方法中,将参数标记为final将有助于意外地将这些参数解释为方法局部变量,而重新指定为编译器将标记这些情况,如示例所示

2将参数传递给匿名内部类
由于形式化方法参数是一个局部变量,只有当它们声明为final时,才能从内部匿名类访问它们。

如果参数被重新使用或重新分配,代码分析器会发出警告。(与局部变量相同)嗯,如果你发现不希望更改这些参数,那么这是捕获这些参数的更好方法
    public String changeTimezone(final Timestamp stamp, final Timezone fTz, 
            final Timezone toTz){
    
    // THIS WILL CAUSE COMPILATION ERROR as fTz is marked as final argument

      fTz = Calendar.getInstance().getTimeZone();     
      return ..
    
    }