简体   繁体   English

Java和Final关键字的使用

[英]Java and the use of the Final keyword

I'm new to Java having programmed in Delphi and C# for some time,. 我是Java新手,已经在Delphi和C#中编程了一段时间。 My question relates to the usage of the "final" keyword on a variable that holds an instantiated class when the variable declaration and instantiation both happen within the scope of the same method. 我的问题涉及当变量声明和实例化都发生在同一方法的范围内时,变量上使用“final”关键字,该变量包含实例化类。 eg 例如

private String getDeviceID() {
   //get the android device id
   final TelephonyManager tm =                
     (TelephonyManager)GetBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
   final String deviceID = tm.getDeviceId();

   // log debug message containing device ID
   Log.d(LOG_CAT, "getDeviceID: " + deviceID);        

   return deviceID;
}

okay so I think I get the fact that "final" variables can only ever be assigned to once and cannot be changed due to the "final" keyword on each declaration, but don't both variables go out of scope when the method exits? 好吧所以我认为我得到的事实是“最终”变量只能分配给一次,并且由于每个声明上的“final”关键字而无法更改,但是当方法退出时,两个变量都不会超出范围吗? and calling the method again will simply reallocate 2 new final variables that once again will go out of scope on method exit? 并再次调用该方法将简单地重新分配2个新的最终变量,这些变量在方法退出时将再次超出范围?

To me it seems kinda odd to be using the "final" keyword on these variables? 对我来说,在这些变量上使用“final”关键字似乎有点奇怪? unless I don't understand how they impact on local variables within a method's scope? 除非我不理解它们如何影响方法范围内的局部变量?

Can someone enlighten me as to what the impact of "final" is with regard to method scope, or is declaring these particular variables as final just a dumb ass thing that someone did? 有人可以告诉我“最终”对方法范围的影响是什么,或者将这些特定变量声明为最终只是某人做的蠢事?

final has no effect on scope. final对范围没有影响。
It just prevents the variable from being re-assigned. 它只是阻止重新分配变量。

It serves as a signal to other developers that these variables will never change, and it prevents you from changing them by accident. 它向其他开发人员发出信号,告知这些变量永远不会改变,并且它会阻止您意外更改它们。
This is particularly useful in longer methods. 这在较长的方法中特别有用。

final is also required in order to use a variable in an anonymous inner class, since Java does not support true closures. 为了在匿名内部类中使用变量,还需要final ,因为Java不支持真正的闭包。

These variables will indeed be garbage collected as soon as the GC will run when the method exits. 一旦GC退出时GC就会运行,这些变量确实会被垃圾收集。

The final keyword is really there as a hint: this variable is instantiated once, you should not touch it in the body of the method itself. final关键字实际上是一个提示:这个变量被实例化一次,你不应该在方法体的主体中触摸它。 Similarly, declaring method parameters final forbids their reuse (which, imho, is a good thing). 同样,声明方法参数final禁止重复使用(imho,这是一件好事)。

Note however that the keyword only affects the object reference: it does not mean that methods on this object reference which modify its internal state will cease to work (typical example: setters). 但请注意,关键字仅影响对象引用:它并不意味着此对象引用上修改其内部状态的方法将停止工作(典型示例:setter)。

Another note: when you omit the final keyword, and you don't modify the variable in the body of your method, the JVM is smart enough to optimize this case. 另一个注意事项:当您省略final关键字,并且不修改方法体中的变量时,JVM足够智能以优化此情况。 So, you may omit it. 所以,你可以省略它。 Whether or not you use it, and where you use it, is a matter of taste/coding style. 无论您是否使用它,以及您使用它,都是品味/编码风格的问题。

And finally, it is good practice to declare public static variables as final: otherwise, anything can modify it! 最后,将public static变量声明为final是一个好习惯:否则,任何东西都可以修改它! Think string constants etc. 想想字符串常量等

There's nothing special about the scope of a final local variable or parameter. final局部变量或参数的范围没有什么特别之处。

Declaring a local variable or parameter as final doesn't really do much and is rarely necessary. 将局部变量或参数声明为final并不是很有用,并且很少需要。 There are basically two reasons for it: 基本上有两个原因:

  1. Some developers believe that anything that doesn't need to be mutable should be immutable. 一些开发人员认为,任何不需要变量的东西都应该是不可变的。 While I agree in principle (immutability is a good thing in many respects), I think that for a language like Java, declaring everything final is going overboard. 虽然我原则上同意(不变性在很多方面都是好事),但我认为对于像Java这样的语言来说, final宣布一切都是过分的。
  2. If your method contains a local or anonymous inner class and you want any of its local variables or parameters to be accessible to code in the inner class, you have to declare them final . 如果您的方法包含本地或匿名内部类,并且您希望其内部类中的代码可以访问其任何局部变量或参数,则必须将它们声明为final This is a kluge in the Java language; 这是Java语言中的一个方面; its purpose is to prevent code in the inner class from trying to modify the variables or parameters after they are no longer alive. 其目的是防止内部类中的代码在变量或参数不再存活后尝试修改它们。

They're final to the scope they're in. That's just the way it works. 他们是他们所处的范围的最终决定。这就是它的工作方式。

I imagine the point of making them final in this instance is to prevent future developers from changing them when they shouldn't be changed. 我想在这种情况下让它们成为最终版本的目的是防止未来的开发人员在不应该更改时更改它们。 It's just defensive coding in this case. 在这种情况下,这只是防御性编码。

对于基元和引用, final就像是const in c。

Readability 可读性


When it comes to local scope, I find that its usage is variable. 说到本地范围,我发现它的用法是可变的。 That is, some programmers will elect to use it (and abuse it...like me) and some will use it sparingly (eg to ensure a class cannot be subclassed, immutability, and etc.). 也就是说,一些程序员会选择使用它(并且像我一样滥用它),有些程序员会谨慎地使用它(例如,确保一个类不能被子类化,不变性等等)。

I find that when working with a group of developers, it's either all, or nothing. 我发现在与一组开发人员合作时,它要么全部要么全无。 Once you start including final modifiers in the local scope, you know that you're hooked and there's not much your team can do (except get you fired...somehow...for being an effective developer). 一旦你开始在本地范围内包含final修饰符,你知道你被迷住了,你的团队可以做的并不多(除了让你解雇......不知怎的......作为一个有效的开发者)。

My perspective 我的观点

It is a good practice (for better maintenance etc) to make the local variables as final. 将局部变量作为最终变量是一种很好的做法(为了更好的维护等)。 This is one way of reducing the side effects . 这是减少副作用的一种方法。 Side-effect free code is easy to reason about and hence more readable and easy to maintain. 无副作用的代码易于推理,因此更易读,易于维护。

Overly religious programmers would tell you to mark final on local variables (including method parameters) whenver you can. 过度宗教的程序员会告诉你尽可能在局部变量(包括方法参数)上标记final

In practice nobody does that, including those programmers. 在实践中,没有人这样做,包括那些程序员。

Don't bother. 不要打扰。

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

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