3 ms·
To provide a counterpoint, and I say this as a big casual user of Haskell and Rust (both immutable by default), but a professional Java developer. I work on a
by gamegoblin 11y ago
To provide a counterpoint, and I say this as a big casual user of Haskell and Rust (both immutable by default), but a professional Java developer.
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`?
- steveklabnik 11y agoSmall nit: you can know it's the same, unless it's a type which offers interior mutability.
- eropple 11y agoWhich, naturally, you should be avoiding, too, to ensure immutability and thus consistency and predictability across the entire piece of code. =) (Obviously you know that, Steve, but it's the sort of thing that I find a lot of Java folks mentally don't get.)
- LgWoodenBadger 11y agoOn the contrary, it buys you much more. The final keyword in Java will result in compilation errors if you fail to assign it a value for all possible branches within its scope. And it's 5 characters to prevent a whole class of errors for free (erroneous assignments to method parameters), so why not do it? 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.
- gamegoblin 11y agoFor where we do use it: * 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
- the_af 11y agoAnd coming full circle with the original question, I'd add: * 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.
- AdieuToLogic 11y ago> `final` doesn't buy you as much in Java as `const` does in C, or (the lack of) `mut` in Rust. 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.