6 ms·
What about final for Java function parameters? A professor was requiring that and I'm not sure whether its something I should continue doing or not.
by daodedickinson 11y ago
What about final for Java function parameters? A professor was requiring that and I'm not sure whether its something I should continue doing or not.
- golergka 11y agoMake everything you can as immutable as possible. The less possibilities exist for data to change, the more you know about it during runtime, the easier it is to reason about it. I love the trend that new languages, like Swift and Rust, make it really easy to make variables immutable and even disallow using "null" values unless a variable is explicitly nullable.
- gamegoblin 11y agoTo 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.
- shoo 11y agoCurious. I haven't written anything in Java for a long time so I wasn't aware that you could mark parameters as `final`, or what that would mean. If you are working with code where you know that functions never modify their parameters then it is simpler to reason about what it does. I prefer to write code this way myself if there is no language mechanism to enforce it. Other possible uses of `final` (to tag methods or classes) have the downside of reducing the flexibility of code by removing interfaces / "seams" that can be overridden. This reduction of flexibility will generally make things harder to test, which may or may not matter. Michael Feathers has a short article discussing this [1]. [1] Michael Feathers' "Testable Java" : http://www.objectmentor.com/resources/articles/TestableJava.pdf http://www.objectmentor.com/resources/articles/TestableJava....
- AdieuToLogic 11y ago> What about final for Java function parameters? For built-ins, such as numeric types and "char" (String is obviously disallowed from this definition), final will prevent changes to instances of those types similar to what "const int" does for C++. For pointers, however, the final keyword in Java limits the ability to change the variable holding the pointer, not to what it references. The equivalent in C++ would be: SomeClass * const foo = &instanceOfSomeClass; Here, the pointer "foo" could not change, but operations changing foo would be allowed. Java (the language) does not possess the semantics to express "the pointer given to a method cannot allow changes to what it points."
- EdwardDiego 11y agoYep, if you want an immutable list, or whatever, you have to make sure your list is immutable, which usually involves defensive copying.