在Java中,有一种惯例,将每个变量(局部变量或类)声明为final参数(如果它们确实是final的话)。

虽然这会使代码更加冗长,但这有助于容易阅读/掌握代码,也可以防止错误,因为意图被清晰地标记出来。

你对此有何看法?


当前回答

为事件监听器使用匿名本地类等是Java中的常见模式。 final关键字最常见的用法是确保偶数侦听器可以访问作用域内的变量。

但是,如果您发现自己被要求在代码中放入大量的最终语句。这可能是你做错事的好暗示。

上面的文章给出了这样一个例子:

public void doSomething(int i, int j) {
    final int n = i + j; // must be declared final

    Comparator comp = new Comparator() {
        public int compare(Object left, Object right) {
            return n; // return copy of a local variable
        }
    };
}

其他回答

为:

Final fields - Marking fields as final forces them to be set by end of construction, making that field reference immutable. This allows safe publication of fields and can avoid the need for synchronization on later reads. (Note that for an object reference, only the field reference is immutable - things that object reference refers to can still change and that affects the immutability.) Final static fields - Although I use enums now for many of the cases where I used to use static final fields.

考虑但审慎地使用:

最终类——框架/API设计是我唯一考虑的情况。 Final方法——基本上与Final类相同。如果你疯狂地使用模板方法模式,并把东西标记为final,你可能太依赖继承而不是委托。

忽略,除非感觉肛门:

Method parameters and local variables - I RARELY do this largely because I'm lazy and I find it clutters the code. I will fully admit that marking parameters and local variables that I'm not going to modify is "righter". I wish it was the default. But it isn't and I find the code more difficult to understand with finals all over. If I'm in someone else's code, I'm not going to pull them out but if I'm writing new code I won't put them in. One exception is the case where you have to mark something final so you can access it from within an anonymous inner class.

对于将所有可能的变量都声明为final,我非常武断。这包括方法参数、局部变量,以及很少的值对象字段。我有三个在任何地方声明最终变量的主要原因:

Declaring Intention: By declaring a final variable, I am stating that this variable is meant to be written to only once. It's a subtle hint to other developers, and a big hint to the compiler. Enforcing Single-use Variables: I believe in the idea that each variable should have only one purpose in life. By giving each variable only one purpose, you reduce the time it takes to grok the purpose of that particular variable while debugging. Allows for Optimization: I know that the compiler used to have performance enhancement tricks which relied specifically on the immutability of a variable reference. I like to think some of these old performance tricks (or new ones) will be used by the compiler.

然而,我确实认为final类和方法远不如final变量引用有用。最后一个关键字,当与这些声明一起使用时,只是为自动化测试和以您从未预料到的方式使用代码提供了障碍。

I have to read a lot of code for my job. Missing final on instance variables is one of the top things to annoy me and makes understanding the code unnecessarily difficult. For my money, final on local variables causes more clutter than clarity. The language should have been designed to make that the default, but we have to live with the mistake. Sometimes it is useful particularly with loops and definite assignment with an if-else tree, but mostly it tends to indicate your method is too complicated.

Final显然应该用在常量上,并加强不可变性,但在方法上还有另一个重要的用途。

Effective Java在这方面有一个完整的项目(项目15),指出了意外继承的陷阱。实际上,如果您没有为继承而设计和记录您的类,那么从它继承可能会带来意想不到的问题(该项目提供了一个很好的例子)。因此,建议在不打算继承的任何类和/或方法上使用final。

That may seem draconian, but it makes sense. If you are writing a class library for use by others then you don't want them inheriting from things that weren't designed for it - you will be locking yourself into a particular implementation of the class for back compatibility. If you are coding in a team there is nothing to stop another member of the team from removing the final if they really have to. But the keyword makes them think about what they are doing, and warns them that the class they are inheriting from wasn't designed for it, so they should be extra careful.

当在Java中与变量一起使用时,Final提供了c++中常量的替代品。所以当final和static被用于一个变量时,它就变成了不可变的。同时让迁移的c++程序员非常开心;-)

当与引用变量一起使用时,它不允许您重新引用对象,尽管对象可以被操作。

当final与方法一起使用时,它不允许子类重写该方法。

一旦用法非常清楚,就应该谨慎使用。这主要取决于设计,因为在方法上使用final不利于多态性。

只有当你非常确定变量的值不会/不应该被改变时,才应该将它用于变量。还要确保您遵循SUN鼓励的编码约定。int COLOR_RED = 1;(大写字母以下划线分隔)

对于引用变量,只在需要对特定对象的不可变引用时使用它。

关于可读性部分,在使用最终修饰语时,注释起着非常重要的作用。