As for "visual noise," I find it helps to highlight variable declarations and results in more readable code, but we're firmly in the personal opinion area here.
* Member variables of a class that should be initialized in the constructor
* Static final constants
* Any configuration-like variable
* Like you mentioned, when you need to initialize a variable in a particular scope, but the initialization could happen in several control paths of inner scopes
* Function parameters.
Re-assigning a variable used as a function parameter is frequently a mistake, and almost always makes code more confusing. I find the "this is defined only once in this function" philosophy to be useful in keeping complexity down in Java programs. Even if final doesn't make objects immutable.
Quite true.
> `final` only helps you avoid dumb reassignment bugs that tests should probably catch anyway ...
There is another reason for declaring parameters `final` in Java. It is the only way[1] which they can be used in an anonymous class definition such as:
return new SomeClass () {
override int addOne () {
return aNamedOuterMethodParam + 1;
}
}
1 - "The only way" as of Java 7. Newer versions may have removed this restriction, I haven't bothered to check.(Obviously you know that, Steve, but it's the sort of thing that I find a lot of Java folks mentally don't get.)
I work on a large, mainly Java codebase. If we used `final` everywhere it is applicable, the code would have a ton of visual noise. We find that `final` is not as valuable in most cases.
`final` doesn't buy you as much in Java as `const` does in C, or (the lack of) `mut` in Rust.
In Rust, I can pass in an object reference without mut, and I know that the object will be the exact same after the function call.
In Java, even if a function takes `final ArrayList<..> xs`, the function can still delete every element of your array, modify elements at will, etc.
That means `final` is basically useless as far as using an API goes (I don't care if the implementation of a function reassigns to the same variable as the object I'm passing in, but I do care if they mutate it).
`final` only helps you avoid dumb reassignment bugs that tests should probably catch anyway, and in that case, if you are already writing good tests, why pollute the code with the visual noise of `final`?