简体   繁体   English

将java方法参数设为final

[英]Making java method arguments as final

What difference that final makes between the code below. final在下面的代码之间有什么区别。 Is there any advantage in declaring the arguments as 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 ....
}

As a formal method parameter is a local variable, you can access them from inner anonymous classes only if they are declared as final.由于形式方法参数是一个局部变量,只有当它们声明为 final 时,您才能从内部匿名类访问它们。

This saves you from declaring another local final variable in the method body:这使您无需在方法主体中声明另一个局部最终变量:

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

Extract from The final word on the final keyword摘录自The final word on the final 关键字

Final Parameters最终参数

The following sample declares final parameters:以下示例声明了最终参数:

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 is used here to ensure the two indexes i and j won't accidentally be reset by the method.这里使用 final 来确保两个索引 i 和 j 不会被方法意外重置。 It's a handy way to protect against an insidious bug that erroneously changes the value of your parameters.这是防止错误更改参数值的潜在错误的一种方便方法。 Generally speaking, short methods are a better way to protect from this class of errors, but final parameters can be a useful addition to your coding style.一般来说,短方法是防止此类错误的更好方法,但最终参数可能是对您的编码风格的有用补充。

Note that final parameters are not considered part of the method signature, and are ignored by the compiler when resolving method calls.请注意,最终参数不被视为方法签名的一部分,并且在解析方法调用时被编译器忽略。 Parameters can be declared final (or not) with no influence on how the method is overriden.参数可以被声明为最终的(或不是),而不会影响方法被覆盖的方式。

The final prevents you from assigning a new value to the variable, and this can be helpful in catching typos. final 阻止您为变量分配新值,这有助于发现拼写错误。 Stylistically you might like to keep the parameters received unchanged and assign only to local variables, so final would help to enforce that style.从风格上讲,您可能希望保持接收的参数不变并仅分配给局部变量,因此 final 将有助于强制执行该风格。

Must admit I rarely remember to use final for parameters, maybe I should.必须承认我很少记得使用 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;
}

It doesn't make a lot of difference.它没有太大区别。 It just means that you can't write:这只是意味着你不能写:

stamp = null;
fTz = new ...;

but you can still write:但你仍然可以写:

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

It's mainly a hint to the maintenance programmer that follows you that you aren't going to assign a new value to the parameter somewhere in the middle of your method where it isn't obvious and might therefore cause confusion.这主要是对跟随您的维护程序员的一个提示,即您不会在方法中间的某个地方为参数分配一个新值,因为它不明显,因此可能会导致混淆。

The final keyword when used for parameters/variables in Java marks the reference as final.在 Java 中用于参数/变量的 final 关键字将引用标记为 final。 In case of passing an object to another method, the system creates a copy of the reference variable and passes it to the method.如果将对象传递给另一个方法,系统会创建引用变量的副本并将其传递给该方法。 By marking the new references final, you protect them from reassignment.通过将新引用标记为 final,您可以保护它们免于重新分配。 It's considered sometimes a good coding practice.它有时被认为是一种很好的编码实践。

For the body of this method the final keyword will prevent the argument references to be accidentally reassigned giving a compile error on those cases (most IDEs will complain straight away).对于此方法的主体, final关键字将防止意外重新分配参数引用,从而在这些情况下产生编译错误(大多数 IDE 会立即抱怨)。 Some may argue that using final in general whenever possible will speed things up but that's not the case in recent JVMs.有些人可能会争辩说,在可能的情况下一般使用final会加快速度,但在最近的 JVM 中情况并非如此。

Two advantages that I see are listed :列出了我看到的两个优点:

1 Marking the method argument as final prevents reassignment of the argument inside the method 1将方法参数标记为 final 可防止在方法内重新分配参数

From you example从你的例子

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

In a complicated method marking the arguments as final will help in accidental interpretation of these arguments as methods local variables and reassigning as compiler will flag these cases as shown in the example.在一个复杂的方法中,将参数标记为 final 将有助于将这些参数意外解释为方法局部变量,并且重新分配为编译器将标记这些情况,如示例所示。

2 Passing the argument to an anonymous inner class 2将参数传递给匿名内部类

As a formal method parameter is a local variable, you can access them from inner anonymous classes only if they are declared as final.由于形式方法参数是一个局部变量,只有当它们声明为 final 时,您才能从内部匿名类访问它们。

- In the past (before Java 8 :-) ) - 过去(在 Java 8 之前 :-) )

Explit use of "final" keyword affected accessibility of the method variable for internal anonymous classes.明确使用“final”关键字会影响内部匿名类的方法变量的可访问性。

- In modern (Java 8+) lanaguage there is no need for such usage: - 在现代(Java 8+)语言中,不需要这样的用法:

Java introduced "effectively final" variables. Java 引入了“有效最终”变量。 Local variables and method paramters are assummed final if the code does not imply changing of value of the variable.如果代码不暗示更改变量的值,则假定局部变量和方法参数是最终的。 So if you see such keyword in Java8+ you can assume it is unecessary.因此,如果您在 Java8+ 中看到这样的关键字,您可以认为它是不必要的。 Introduction of "effectively final" makes us type less code when using lambdas.引入“有效最终”使我们在使用 lambda 时键入更少的代码。

Its just a construct in Java to help you define a contract and stick to it.它只是 Java 中的一种结构,可帮助您定义契约并坚持下去。 A similar discussion here : http://c2.com/cgi/wiki?JavaFinalConsideredEvil这里有一个类似的讨论: http : //c2.com/cgi/wiki?JavaFinalConsideredEvil

BTW - (as the twiki says), marking args as final is generally redundant if you are following good programming principles and hance done reassign / redefine the incoming argument reference.顺便说一句 - (如 twiki 所说),如果您遵循良好的编程原则并且完成重新分配/重新定义传入参数引用,则将 args 标记为 final 通常是多余的。

In the worst case, if you do redefine the args reference, its not going to affect the actual value passed to the function - since only a reference was passed.在最坏的情况下,如果你重新定义了 args 引用,它不会影响传递给函数的实际值——因为只传递了一个引用。

I'm speaking of marking variables and fields final in general - doesn't just apply to method arguments.我说的是一般将变量和字段标记为 final - 不仅适用于方法参数。 (Marking methods/classes final is a whole different thing). (将方法/类标记为 final 是完全不同的事情)。

It's a favor to the readers/future maintainers of your code.这对你的代码的读者/未来的维护者有好处。 Together with a sensible name of the variable, it's helpful and reassuring to the reader of your code to see/understand what the variables in question represent - and it's reassuring to the reader that whenever you see the variable in the same scope, the meaning stays the same, so (s)he doesn't have to scratch his head to always figure out what a variable means in every context.再加上一个合理的变量名称,它有助于让代码的读者看到/理解所讨论的变量所代表的内容,并让他们放心——而且让读者放心,只要您在同一范围内看到变量,意义就会保持不变相同,因此(她)他不必总是挠头去弄清楚变量在每种情况下的含义。 We've seen too many abuses of "re-use" of variables, that makes even a short code snippet hard to understand.我们已经看到太多滥用变量“重用”的情况,这使得即使是简短的代码片段也难以理解。

The final keyword prevents you from assigning a new value to the parameter. final 关键字阻止您为参数分配新值。 I would like to explain this with a simple example我想用一个简单的例子来解释这一点

Suppose we have a method假设我们有一个方法

method1(){方法1(){

Date dateOfBirth =new Date("1/1/2009");日期 dateOfBirth =new Date("1/1/2009");

method2(dateOfBirth);方法2(出生日期);

method3(dateOfBirth);方法3(出生日期); } }

public mehod2(Date dateOfBirth) {公共方法2(出生日期){
.... ....
.... ....
.... ....
} }

public mehod2(Date dateOfBirth) {公共方法2(出生日期){
.... ....
.... ....
.... ....
} }

In the above case if the "dateOfBirth" is assigned new value in method2 than this would result in the wrong output from method3.在上述情况下,如果在方法 2 中为“dateOfBirth”分配了新值,那么这将导致方法 3 的输出错误。 As the value that is being passed to method3 is not what it was before being passed to method2.因为传递给method3的值不是传递给method2之前的值。 So to avoid this final keyword is used for parameters.所以为了避免这个 final 关键字用于参数。

And this is also one of the Java Coding Best Practices.这也是 Java 编码最佳实践之一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM