tags:

views:

4001

answers:

23

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?

A: 

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.

SCdF
Turning the statement on its head: I have been in _plenty_ of situations where _not_ using `final` (and immutable objects in general) has had a significant contributing factor to the number and impact of bugs.
Christian Vest Hansen
I'm all for immutable objects, I just have never been in a situation where marking an immutable object final has helped me.
SCdF
I agree that we shouldn't use final on local variables and method parameters, it does make code much less readable.
Skillwired
+17  A: 

You really need to understand the full use of the final keyword before using it. It can apply to and has differing affects on variables, fields, methods and classes

I’d recommend checking out the article linked to below for more details.

Final Word On the final Keyword

HowardSP
+2  A: 

I hardly use final on methods or classes because I like allowing people to override them.

Otherwise, I only use finally if it is a public/private static final type SOME_CONSTANT;

jjnguy
Hmm..edited at one place..still is says finally on the second line ;-)
Omnipotent
+12  A: 

Effective Java has an item that says "Favour immutable objects". Declaring fields as final helps you take some small steps towards this, but there is of course much more to truly immutable objects than that.

If you know that objects are immutable they can be shared for reading among many threads/clients without synchronization worries, and it is easier to reason about how the program runs.

Lars Westergren
careful - final and immutable are completely different concepts. Its easy to have a final mutable object - final is about the reference, mutability is about the object instance.final Person olaf = new Person(); olaf.setName("Olaf");
Olaf
Exactly-- immutable objects are one thing, immutable references (i.e. final) are something else entirely.
SCdF
But they are closely related since you can by declaring the Person.name field as final (and declaring the class final, and...) make the Person object final. It is however not as easy as just doing "final Person"...
Sebastian Ganslandt
+20  A: 

I think it all has to do with good coding style. Of course you can write good, robust programs without using a lot of final modifiers anywhere, but when you think about it...

Adding final to all things which should not change simply narrows down the possibilities that you (or the next programmer, working on your code) will misinterpret or misuse the thought process which resulted in your code. At least it should ring some bells when they now want to change your previously immutable thing.

At first, it kind of looks awkward to see a lot of final keywords in your code, but pretty soon you'll stop noticing the word itself and will simply think, that-thing-will-never-change-from-this-point-on (you can take it from me ;-)

I think it's good practice. I am not using it all the time, but when I can and it makes sense to label something final I'll do it.

Johan Pelgrim
Instead of using the final keyword for parameters you can use static analysis tool such as FindBugs to require that parameter variables are not reassigned. This way you remove the syntactic burden and can enforce it via a FindBugs check in your Continuous integration tool.
Timo Westkämper
@Timo This would work, but it has the downside that this needs to be checked after checkin and not while the dev is working on the code. For `final`, the compiler obviously won't let you continue if you make a mistake.
Mike
@Mike, agreed. I love FindBugs and use it religiously, but when there's a language feature and compiler support... use it! Yeah, I think final all over the place is ugly, and when they finally do an incompatible Java rewrite, I hope everything is final by default.
andersoj
+2  A: 

Final when used with variables in Java provides a substitute for constant in C++. So when final and static is used for a variable it becomes immutable. At the same time makes migrated C++ programmers pretty happy ;-)

When used with reference variables it does not allow you to re-reference the object, though the object can be manipulated.

When final is used with a method, it does not allow the method to be over-ridden by the subclasses.

Once the usage is very clear it should be used with care. It mainly depends on the design as using final on the method would not help polymorphism.

One should only use it for variables when you are damn sure that the value of the variable will/should never be changed. Also ensure that you follow the coding convention encouraged by SUN.for eg: final int COLOR_RED = 1; (Upper case seperated by underscore)

With a reference variable, use it only when we need a an immutable reference to a particular object.

Regarding the readability part, ensue that comments play a very important role when using the final modifier.

Omnipotent
Can someone tell me why this is down voted??? Just curious..
Omnipotent
It's probably because you state that you should ONLY make it final when XYZ. Others consider it better practice to make EVERYTHING final unless there is a need to do so otherwise.
Outlaw Programmer
A: 

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
        }
    };
}
Hans Sjunnesson
A: 

I use it for constants inside and outside methods.

I only sometimes use it for methods because I don't know if a subclass would NOT want to override a given method(for whatever reasons).

As far as classes, only for some infrastructure classes, have I used final class.

IntelliJ IDEA warns you if a function parameter is written to inside a function. So, I've stopped using final for function arguments. I don't see them inside java Runtime library as well.

anjanb
A: 

Using final for constants is strongly encouraged. However, I wouldn't use it for methods or classes (or at least think about it for a while), because it makes testing harder, if not impossible. If you absolutely must make a class or method final, make sure this class implements some interface, so you can have a mock implementing the same interface.

phjr
It does not make testing harder because you should be using interfaces anyway.
Christian Vest Hansen
+9  A: 

The final modifier, especially for variables, is a means to have the compiler enforce a convention that is generally sensible: make sure a (local or instance) variable is assigned exactly once (no more no less). By making sure a variable is definitely assigned before it is used, you can avoid common cases of a NullPointerException:

final FileInputStream in;
if(test)
  in = new FileInputStream("foo.txt");
else
  System.out.println("test failed");
in.read(); // Compiler error because variable 'in' might be unassigned

By preventing a variable from being assigned more than once, you discourage overbroad scoping. Instead of this:

 String msg = null;
 for(int i = 0; i < 10; i++) {
     msg = "We are at position " + i;
     System.out.println(msg);
 }
 msg = null;

You are encouraged to use this:

 for(int i = 0; i < 10; i++) {
     final String msg = "We are at position " + i;
     System.out.println(msg);
 }

Some links:

Bruno De Fraine
+1, best answer so far
Willi
+1 for discourge overbroad scoping argument
Tom Tresansky
+4  A: 

I use final all the time for object attributes.

The final keyword has visibility semantics when used on object attributes. Basically, setting the value of a final object attribute happens-before the constructor returns. This means that as long as you don't let the this reference escape the constructor and you use final for all you attributes, your object is (under Java 5 semantics) guarenteed to be properly constructed, and since it is also immutable it can be safely published to other threads.

Immutable objects is not just about thread-safety. They also make it a lot easier to reason about the state transitions in your program, because the space of what can change is deliberately and, if used consistently, thoroughly limited to only the things that should change.

I sometimes also make methods final, but not as often. I seldomly make classes final. I generally do this because I have little need to. I generally don't use inheritance much. I prefer to use interfaces and object composition instead - this also lends itself to a design that I find is often easier to test. When you code to interfaces instead of concrete classes, then you don't need to use inheritance when you test, as it is, with frameworks such as jMock, much easier to create mock-objects with interfaces than it is with concrete classes.

I guess I should make the majority of my classes final, but I just haven't gotten into the habbit yet.

Christian Vest Hansen
+2  A: 

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.

Tom Hawtin - tackline
+23  A: 

Obsess over:

  • 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.

Consider but use judiciously:

  • Final classes - Framework/API design is the only case where I consider it.
  • Final methods - Basically same as final classes. If you're using template method patterns like crazy and marking stuff final, you're probably relying too much on inheritance and not enough on delegation.

Ignore unless feeling anal:

  • 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.
Alex Miller
A: 

I never use them on local variables, there is little point for the added verbosity. Even if you don't think the variable should be reassigned, that will make little difference to the next person altering that code that thinks otherwise, and since the code is being changed, any original purpose for making it final may no longer be valid. If it is just for clarity, I believe it fails due to the negative effects of the verbosity.

Pretty much the same applies to member variables as well, as they provide little benefit, except for the case of constants.

It also has no bearing on immutability, as the best indicator of something being immutable is that it is documented as such and/or has no methods that can alter the object (this, along with making the class final is the only way to guarantee that it is immutable).

But hey, that's just my opinion :-)

Robin
+1  A: 

I set up Eclipse to add final on all fields and attributes which are not modified. This works great using the Eclipse "save actions" which adds these final modifiers (among other things) when saving the file.

Highly recommended.

Check out my blog post of Eclipse Save Actions.

zvikico
+3  A: 

final should obviously be used on constants, and to enforce immutability, but there is another important use on methods.

Effective Java has a whole item on this (Item 15) pointing out the pitfalls of unintended inheritance. Effectively if you didn't design and document your class for inheritance, inheriting from it can give unexpected problems (the item gives a good example). The recommendation therefore is that you use final on any class and/or method that wasn't intended to be inherited from.

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.

DJClayworth
+3  A: 

Final should always be used for constants. It's even useful for short-lived variables (within a single method) when the rules for defining the variable are complicated.

For example:

final int foo;
if (a)
    foo = 1;
else if (b)
    foo = 2;
else if (c)
    foo = 3;
if (d)        // Compile error:  forgot the 'else'
    foo = 4;
else
    foo = -1;
David Leppik
A: 

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();
    }
}
Eugene
+1  A: 

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.

Uri
+6  A: 

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.

Ryan Ransford
+1  A: 

Even for local variables, knowing that it is declared final means that I don't need to worry about the reference being changed later on. This means that when debugging and I see that variable later on, I am confident that it is referring to the same object. That is one less thing I need to worry about when looking for a bug. A bonus is that if 99% of variables are declared final, then the few variables which really are variable stand out better. Also, the final lets the compiler find some more possible stupid mistakes that might otherwise go unnoticed.

Diastrophism
A: 

For arguments I'm think they're not needed. Mostley they just hurt readabillity. Rreassigning an argument variable is so insanely stupid that I should be pretty confident that they can be treated as constants anyway.

The fact that Eclipse colors final red makes it easier to spot variable declarations in the code which I think improves readbillity most of the time.

I try to enforce the rule that any and all variables should be final it there isn't an extremley valid reason not to. It's so much easier to answer the "what is this variable?" question if you just have to find the initilization and be confident that that is it.

I actually get rather nervous around non-final variables now a days. It's like the differnce between having a knife hanging in a thread abouve your head, or just having it you kitchen drawer...

A final variable is just a nice way to lable values.

A non-final variable is bound to part of some bug-prone algorithm.

One nice feature is that when the option to use a variable in out of the question for an algorithm most of the time the sollution is to write a method instead, which usually improves the code significantly.

John Nilsson
+1  A: 

I've been coding for a while now and using final whenever I can. After doing this for a while (for variables, method parameters and class attributes), I can say that 90% (or more) of my variables are actually final. I think the benefit of NOT having variables modified when you don't want to (I saw that before and it's a pain sometimes) pays for the extra typing and the extra "final" keywords in your code.

That being said, if I would design a language, I would make every variable final unless modified by some other keyword.

I don't use final a lot for classes and methods, thought. This is a more or less complicated design choice, unless your class is a utility class (in which case you should have only one private constructor).

I also use Collections.unmodifiable... to create unmodifiable lists when I need to.

Ravi Wallau