Using the “final” modifier whenever applicable in

2019-01-01 04:32发布

In Java, there is a practice of declaring every variable (local or class), parameter final if they really are.

Though this makes the code a lot more verbose, this helps in easy reading/grasping of the code and also prevents mistakes as the intention is clearly marked.

What are your thoughts on this and what do you follow?

标签: java oop
25条回答
看淡一切
2楼-- · 2019-01-01 05:10

I have never been in a situation where having a final keyword on a variable has stopped me from making a mistake, so for the moment I think it's a giant waste of time.

Unless there is a real reason for doing it (as in you want to make a specific point about that variable being final) I would rather not do it since I find it makes the code less readable.

If, however, you don't find it makes the code harder to read or longer to write then by all means go for it.

Edit: As a clarification (and an attempt to win back down-votes), I'm not saying don't mark constants as final, I'm saying don't do stuff like:

public String doSomething() {
  final String first = someReallyComplicatedExpressionToGetTheString();
  final String second = anotherReallyComplicatedExpressionToGetAnother();

  return first+second;
}

It just makes code (in my opinion) harder to read.

It's also worth remembering that all final does is prevent you from reassigning a variable, it doesn't make it immutable or anything like that.

查看更多
不流泪的眼
3楼-- · 2019-01-01 05:11

Another caveat is that many people confuse final to mean that the contents of the instance variable cannot change, rather than that the reference cannot change.

查看更多
笑指拈花
4楼-- · 2019-01-01 05:12

Using anonymous local classes for event listeners and such is a common pattern in Java. The most common use of the final keyword is to make sure that variables in scope are accessible to the even listener.

However, if you find yourself being required to put a lot of final statements in your code. That might be a good hint you're doing something wrong.

The article posted above gives this example:

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
        }
    };
}
查看更多
浪荡孟婆
5楼-- · 2019-01-01 05:12

I'm pretty dogmatic about declaring every possible variable final. This includes method parameters, local variables, and rarely, value object fields. I've got three main reasons for declaring final variables everywhere:

  1. 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.
  2. 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.
  3. 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.

However, I do think that final classes and methods are not nearly as useful as final variable references. The final keyword, when used with these declarations simply provide roadblocks to automated testing and the use of your code in ways that you could have never anticipated.

查看更多
几人难应
6楼-- · 2019-01-01 05:14

Marking the class final can also make some method bindings happen at compile time instead of runtime. Consider "v2.foo()" below - the compiler knows that B cannot have a subclass, so foo() cannot be overridden so the implementation to call is known at compile time. If class B is NOT marked final, then it's possible that the actual type of v2 is some class that extends B and overrides foo().

class A {
    void foo() {
        //do something
    }
}
final class B extends A {
    void foo() {
    }
}
class Test {
    public void t(A v1, B v2) {
        v1.foo();
        v2.foo();
    }
}
查看更多
梦醉为红颜
7楼-- · 2019-01-01 05:16

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.

查看更多
登录 后发表回答