All variables in Java must be final
Published April 22nd, 2008 in Beautiful Java, JavaI haven’t been using the final keyword in Java for 10 years, but more and more I think it’s an excellent keyword in Java. All local variables should be declared final. Today one of the developers of my team made every local variable in a method final and I was wondering how strange that looked. But of course it was the right thing to do. Declaring all variables final will lead to less bugs (logic and typos e.g.).
public void doSomething(final input) {
final result = calc(input);
}
If you reassign a variable you most probably do something wrong. I’ll bet if you reassign a variable your method does at least two different things though every method should only do one thing. As should a class. Final also goes for method parameters, all should be final. Others think so too even for methods.
How do you deal with final attributes? When making most attributes final, just initialize them in the constructor. Immutable objects also play nicely with Tell, don’t ask.
All these final keywords around your code create noise though. It would be best to have all variables automatically be final and have a new transient keyword for reassignable variables. Or at least for my IDE - Intellij IDEA - to hide the final keyword and write the variable in a different color. Hear me IDEA developers!
Update: After some more work with Scala, var and val are a good solution.
79 Responses to “All variables in Java must be final”
- 1 Pingback on Apr 25th, 2008 at 9:11 pm
for (final int i = 0; …
I make all variables and classes final. I only make classes non-final if I am designing for inheritance. I can’t make method parameters final though, it just feels too noisy for me.
This makes me feel safe. But I can only get into this mindset in Java. I have yet to use the Object.freeze() method in Ruby, because it seems to be frowned upon. I write my code and run my tests and everything seems right.
Not sure whether all variables should be final, especially places like null checks and reassignments. but in general I follow the same strategy of making parameters and local variables final.
Another strategy I follow to reduce typos is maintain a separate set of prefixes for member variables, parameters and local variables like m, p and e respectively
Immutability is generally regarded as a good thing in the functional programming world. I wonder how much of a benefit this has from the perspective of helping the compiler to produce efficient code, has anyone tried benchmarking this?
I couldn’t tell from your post but just in case you didn’t know there is already a rarely used transient Java key word.
http://en.wikibooks.org/wiki/Java_Programming/Keywords/transient
Sorry I couldn’t find a Sun reference.
@pwilder: Thanks, I know about transient which is for non serializable attributes and is used - as far as I know - also used with JPA. What I meant was a transient keyword for non final declarations. It would fit I think.
@Ian: There was a myth some years ago when people put final everywhere for more performance, nowadays I think the Hotspot VM JIT is far outperforms final optimization by hand.
@Shams: What do you mean with “null checks”?
@matthew: “[…] Object.freeze() method in Ruby, because it seems to be frowned upon. ” as a mindset this might lead to problems down the road with 500 classes and 100 developers. I’ll look into
freezethanks for the tip.I couldn’t agree more: all variables should be final. Most variables are not assigned more than once anyway in well designed software, at least to my experience.
I think that the ratio between final and non-final variables is an estimation of how hard it is to understand a piece of code, because it gives an indication of how much state the code has.
In Eclipse at least, it is actually possible to configure the compile such that it generates an error if a method parameter is assigend. One step in the right direction, I think.
I disagree for using final for method parameters and as a blanket statement for local variables.
For members/immutability, classes, etc, no problem.
But for the method params, it just too much noise. Same for locals, usually. I will use them occasionally but not by dogma.
It is true that I have a vulnerability for bugs, but it is very small and a good set of unit tests should expose it. The unit tests are key, because they not only handle this issue but much, much more.
Mike
ps. For language design, it would be interesting to have everything to default to final unless otherwise stated. Alas, with Java, I don’t see it happening.
final is the most frequently used keyword in my code. It should be by default, with some other keyword, like “mutable”, required to make a variable non-final. I’m glad I’m not the only one who has “final” all over the place in my code.
Functional programming!
@Saudade: Functional Programming is a state of mind not a programming language. So people can code FP in Java. Or there are atoms of principles from which programming languages derive their style: immutable declarations and statelessness are two of them, both can be realized with an FP language or with an OO language. FP is build on those, not equals those. Some people confuse the two facts.
@ChiralSoftware: Excatly, as I said
transientshould be a keyword (and the current use dropped) for those.@Michael: Yes I agree, too much noise. An intelligent IDE could help.
@Torgny: “I think that the ratio between final and non-final variables is an estimation of how hard it is to understand a piece of code, because it gives an indication of how much state the code has.”
Excellent point.
What we really need is the const keyword, compare with the c keyword…
public const String getId() {
return copy-to-const(this.id);
}
….
public const /* do not change object state */ …() {
…
}
public void …(const String t) {
}
i disagree, for example you said that final lead to less bugs, for example if I have code
public final void doSomething(final String string, final String string2) {
final String trimedString = string.trim();
final String substringedString = string2.substring(1);
return trimedString substringedString;
}
i would argue that it can be more buggy if you have 2 variables more.
public void doSomething(String string, String string2) {
string = string.trim();
string2 = string2.substring(1);
return string string2;
}
I used to do final variables, but when i was changing the code removing final felt weird.
“I only make classes non-final if I am designing for inheritance”
its weird idea too. When you do that you make final even more stupid since it only means that now you dont extend that class, maybe in future you will, but then you can remove the final and call it refactoring.
and what about transient ?? i say use it alot too, if you not serializing class it should have all its field transient, just to tell people that youre not into serializing. Some wierd guy might try to serialize your class, but its YOUR class, stop him now! (with AOP you can make class implements Serializable at runtime, so you should use transient)
@kj: I’m not sure if the
constkeyword corresponds to all uses of final in Java. It’s more or less about immutable attributes, and yes we should be able (annotation?) to tell about immutable objects.(and returns from
Collections.unmodifiableCollectionwhich cannot be differntiated from normal Lists in the API)@raveman: The problem with inheritance is that most extending classes do not take the pre/post-conditions of the class into account they are extending, or even don’t know about them (Java vs. Eiffel). Final might help to prevent bugs from inheritance, when people don’t know what they do. And by default: Noone should use inheritance because it was a stupid idea from the beginning, use composition!. Only inherit in frameworks.
Re: the “transient” keyword: I agree, it should be dropped as a keyword, and replaced with a @Transient annotation.
Making all “variables” final by default would be a nice change but I’m not sure if they would consider doing something like that, given how many millions of lines of existing code it would probably break. I guess they could have a compile-time flag that says which language version it is using. This is a compiler change, not a bytecode issue.
@Chiral: Migration should be supported with -final argument to the compiler, just like with other features of Java as you’ve said.
In hindsight, my preference would be that fields be final by default and there should be a keyword to highlight variable fields. like var?
I also think const should declare a reference as immutable, but I think its too late to add this now…
@peter: It’s never too late. And Java has shown that it can adapt, very slowly over several years, but it happens. See the very late changes to volatile :-)
“Noone should use inheritance because it was a stupid idea from the beginning, use composition!”
Again, I totaly agree. I even wrote a post about it a few days ago. :)
@Torgny: :-)
You sound like someone who would love to discover Scala! Check this link:
http://www.codecommit.com/blog/scala/roundup-scala-for-java-refugees
@choucri: I’ve been following Scala for a long time and did some minor stuff with Scala. From my perspective it’s too inconsistent for the average Java - enterprise - developer. But I guess the bet is still out for Scala, but I lean on the pessimistic side.
http://stephan.reposita.org/archives/2008/01/21/no-future-for-functional-programming-in-2008-scala-f-and-nu/
So how do you iterate over a loop? Or keep the current stack position? Or…? Or how do you change the date of birth of a Person object?
Oh, I see. You recommend having a new keyword called transient. Nah. I don’t like it. Then I should declare half of my variables or maybe even more transient.
@stephan regarding null checks
public void doSomething(input) {
if (input == null)
input = myDefaultValue;
final result = calc(input);
}
vs
public void doSomething(final input) {
final result;
if (input == null)
result = calc(myDefaultValue);
else
result = calc(input);
}
“So how do you iterate over a loop?”
I usually iterate over a collection not a loop.
“I usually iterate over a collection not a loop.”
LOL. I wanted to say the same thing. Also sometimes you just need to create loops just for the sake of implementing various kinds of algorithms. And even almost all iterator implementation need non-final variables. There still are a billion of places in which you need non-final variables.
@Behrang: Some people think, and I might be one of them, that you should not iterate at all.
Instead of
for (Person person: department.getPersons()) { ... }One could write
department.eachPerson( new Loop<Person>() { public void doWith(Person person) { ... } }which is longer and more noisy but a.) doesn’t make the caller dependent of the Person implementation (Iterator or Collection) b.) the Loop code could be used in different places.
Java isn’t the best language to do this, but it’s possible.
Beside that, you could use a keyword to make the variable not final.
See http://www.pragprog.com/articles/tell-dont-ask for the usage of
Applyable.There should be an extra step for making a variable non-final. The point is that a high percentage of non-final variable could be final and more importantly could be made final with just a little though, a process which is currently missing.
Closures make your loop code much shorter.
forEach(Person p: department) {
// what ever.
}
Note: the default modifiers for interface are final for fields and non-final for classes. In the same way the default modifier for fields can be final, but the default for loop variables could be non-final. If you want to be explicit everywhere you still could.
I would suggest ‘var’ be the keyword as it is used for javascript to do the same thing.
@Stephan
Without closures you can’t do that in Java unless you use some kind of iteration.
@Behrang: Can’t do? Well the example does it. Anonymous classes in Java are closures. What people most often mean when they say Java has no closures:
1.) There is no short syntax for closures (See Java 7 proposals)
2.) The libraries don’t “think” in closures
But all Java collections could support a map(Mapper) method and it would be - more noisy - but the same as map in Ruby/Python/…
I have to disagree: Java does not have closures — Java has anonymous classes. On thing that can be done with closures that cannot be done with anonymous classes is the following:
forEach(collection) {
if (predicate) {
return;
}
}
A naive mapping to anonymous classes whould result in something like:
forEach(collection, new Loop() {
void iteration()
if (predicate) {
return;
}
}
}
which _does_not_ have the same semantics as the closure-example above.
This is one reason Java needs closures in my opinion.
@Torgny: Could you explain why it does not have the same semantics?
When you call “return” in a closure, you return from the method that is executing the closure.
That is, in the first of my two examples the ‘return’ statement means “return from the surrounding method, i.e., the method that contains the forEach-loop”.
On the other hand, in the secound example the ‘return’ statement means “return from the ‘iteration’ method”.
In other words, the ‘return’ statement will stop the iteration in the first example, but will not stop the iteration in the second example.
I hope this explains what I mean. Sorry for being unclear earlier.
Thanks.
You could fix this with a
if (predicate) {
return true;
}
return false;
Not as nice, but possible with another
Loopimplementation.And probably very buggy.
Sure, there are work-arounds, but the whole point with closures (at least for me) is that noisy code becomes easier to read and understand.
Let’s wait and see what Java 7 will be like…
Well, when it’s about noise, then syntactic sugar to annonymous classe should be enough :-) But we’ll see with Java 7.
Crap, you got me. :)
:-)
And your dynamic scope is crazy stuff. I really like people pushing Javas boundaries, it feels like when we push 6502 boundaries 25 years ago.
There are other things you can do with closures which you cannot do easily with anonymous classes.
1) Change local variables.
boolean found = false;
forEach(Person person) {
if (person.name.equals(name))
found = true;
break;
}
}
// found may or may not have changed.
2) break from a “loop”
Rather like a return from the loop.
3) continue in a “loop”
skip the rest of the anonymous method.
4) return in a “loop” from the method. This doesn’t return from the anonymous class
public Person find(String name) {
forEach(Person person) {
if (person.name.equals(name))
return person;
}
}
// do some more searching
// ….
}
5) Throw checked exceptions. The forEach throws whatever CheckedException’s the closure throws.
public Person find(String name) throws InvalidPersonException {
forEach(Person person) {
if (person.name == null)
throw new InvalidPersonException(”null name”)l
}
}
6) break or continue with a label.
The following has two nested closures….
LOOP: forEach(Person person) {
forEach(Role role) {
if (!person.roles.isAMemberOf(role))
continue LOOP;
if (!person.isActive())
continue;
}
}
“Can’t do? Well the example does it.”
Stephan, could you please show me the completed forEach method? Or the completed each method of the Applyable class? The Applyable class moves the loop from the caller code into the callee but it does not eliminate it.
@Behrang: A closure based each doesn’t eliminate it either. Someone has to loop over the collection. But it’s not me, the caller, which has to do it, it’s not my code.
If Java
Collectionswould provide anapply()method, the implicit loop would be there, in infrastructure code. i don’t care if they use final or not.Rubys
eachneeds to have an internal loop too, but it’s part of the language library not part of my code.http://martinfowler.com/bliki/Closure.html
That was the point I wished to make.
Department.java:
public void persons(Applyable applyable) {
this.persons.apply(applyable);
}
“And your dynamic scope is crazy stuff. I really like people pushing Javas boundaries, it feels like when we push 6502 boundaries 25 years ago.”
It’s powerful but dangerous stuff, I think… :)
The closest I’ve got the a 6502 is when I programmed in Basic on the C64. Ah, such fond memories. :)
How would one close a Connection in a finally block that was opened in the corresponding try block? The only way I know is to declare the reference (variable) outside the try block and initialize it to null, then assign the opened Connection to it inside the try block, which is impossible if the reference is final.
@DG: You’re right, the current language syntax in Java does not allow to make such a var final. Or more clearly the compiler is to blame because it does not accept
if (finalVar != null) {
…
}
as a guard to an uninitialized variable.
I think that aspect of the Java compiler (preventing the reading of a possibly uninitialized variable) is a great feature. In my guess, it’s prevented far more runtime bugs than making all references final would. After pushing out many, many thousands of lines of Java code over the years, I can’t recall a single bug I ever found and fixed where I said to myself, “gee, that wouldn’t have happened if only I had declared that reference as final.”
It’s not that the compiler shouldn’t prevent the reading of uninitialized variables, but with a Null check guard this should work, if the contract is extended for uninitialized variables to be null (see my comment above). Otherwise your totally right of course.
It sounds like what you really want is assign-once variables rather than final varibles. For me, there is a difference:
final: is assigned where the variable is declared; cannot be undefined/unassigned; cannot change value.
assign-once: is assign after being declared; can be undefined/unassigned; cannot change value once defined/assigned.
(Note that final variables is a subset of assign-once variables).
I would think that it it impossible (in the general case) to gurantee that assign-once variables are defined before they are read. This is, however, trivial to final variables. IOW, there will be run-time errors instead of compile-time errors if assign-once variable is used.
However, it is alot easier for the developer to reason about assign-once variables than non-final varables. At least I can reason easire about assign-once variables.
If you make uninitialized local references null, then you’re breaking the contract for final, because the reference will hold two legitimate values during its lifetime.
But that’s all beside my main point, which was in the last sentence of my previous post. This proposal of yours is, IMO, a solution in search of a problem.
“final: is assigned where the variable is declared; cannot be undefined/unassigned; cannot change value.”
Not really, final is more a write-before-first-read.
final int a;
a = 3;
works as does
private final int b;
public A() {
this.b = 3;
}
The problem with the finally is that the variable is first read before written.
“Not really, final is more a write-before-first-read.”
I didn’t know that… Hurray! I learn something new everyday! :)
“The problem with the finally is that the variable is first read before written.”
I have to argue that that’s not a problem… it’s a feature. :)
If you want that kind of behaviour I suggest that you write an AssignOnce class, such that you can do:
class Something {
private final AssignOnce it = new AssignOnce();
setIt(Object o) {
it.set(o); // throws run-time exception if already set.
}
}
Or, (and that’s a much more fun solution) you make some delicate changes to javac. :)
I wanted to hack javac to do fun things for quite some time, especially since everyon hacks his own closure implementation :-)
@stephan:
Even if your proposal, to make references (or identifiers, I guess I should say, so as to include primitives) final by default, were a good idea, which I’m arguing it’s not, it’s absurd to think that any governing body of a language would make a change that would break probably 95% of the existing code base.
As for declaring all variables as final (at least where it’s possible), I’m sorry to be blunt, but I think it’s a dumb idea, plain and simple. If there was a measurable benefit to be gained from doing it, it would have become common practice long ago, not just in Java, but in other languages where variables are, well, variable.
Certain ideas are just obviously good, like for example global variables and goto statements should be avoided, and as a result they gain currency over time, and become conventional wisdom in the programming world. Seriously, no offense, but your idea is not one of them.
You say doing this can prevent bugs, but as I said, I can’t recall ever encountering a bug that would have been prevented by adopting this practice. And even though it could conceivably prevent a bug on very rare occasions, I can more easily imagine scenarios where a proliferation of declared variables (when one is all that’s really needed) could make bugs more likely, rather than less.
@DG:
“[…], but in other languages where variables are, well, variable”
It’s the default style of implementation in some languages, FP language for example favor final type assignments. See the comment from Saudade above.
“[…] it’s absurd to think that any governing body of a language would make a change that would break probably 95% of the existing code base.”
See my comment above: “Migration should be supported with -final argument to the compiler, just like with other features of Java as you’ve said.”
“[…] I can’t recall ever encountering a bug that would have been prevented by adopting this practice.”
Making all variables (well except the ones I declared var/mutable/transient, see above comments from me) final would result in differently - and I think better - organized and designed code, more with a functional flavor. And it would lead to less bugs. Perhaps you didn’t have any aliased/shadowed bug in your career, I had quite some in the last 25 years and they we’re often hard to find.
“(when one is all that’s really needed)”
As written above, I consider reusing variables a code smell. See comment comment above.
I’ve had a few shadowed bugs in my career, but they would represent a minuscule percentage in the big picture. Certainly not enough to justify junking up my code with tons of superfluous variables.
And, to each his own, but I don’t consider “reusing” variables to be a code smell. They’re called “variables” for a reason.
At any rate, if you think this is a good idea, you should keep promoting it. Maybe enough programmers will agree with you for it to catch on. But I doubt that will be the case.
“At any rate, if you think this is a good idea, you should keep promoting it.”
I’ll do :-)
“Maybe enough programmers will agree with you for it to catch on.”
Not in Java I fear. Other communities have different ideas. But in the end I do not care. I really think reusing variables is a code smell and preventing reuse will lead to more and smaller methods, which only do one thing and do not try to achieve several things, and in the end better code. My wish for a compiler switch is also more for me, not to dump it onto others. Perhaps IDEA will have a plugin sometimes to hide the final keyword.
Thanks for your thoughts on the topic.
“I can’t recall ever encountering a bug that would have been prevented by adopting this practice.”
You must have been using Java for very different things than myself.
One of the things final fields help with is thread safety. I can only assume you have never had a field change when you didn’t expect it to. or you were happy to just synchronize everything, or you only write single threaded code.
I can only assume you have never used a field before it was initialized.
I guess you are lucky that you have only worked with people who always understood all the assumption made about when a field is set and when it can be used.
Or perhaps you haven’t realized how many bugs you could have prevented with final fields.
“Maybe enough programmers will agree with you for it to catch on.”
Unlikely. Most developers don’t like having to think about multi-threaded issues and most applications don’t require them to do so.
However if there were a compiler option I would certainly use it.
There is a measurable benefit in using final fields. Its not big but applications do perform faster as the JVM can optimize access to such fields.
The biggest benefit is in allowing multi-threaded access without synchronization. This does provide a significant benefit in highly multi-threaded systems.
@peter lawrey:
And then again, maybe I’m just less prone to introducing bugs into my code. I’m not trying to be a smartass when I say that, although I know it sounds that way. If I found myself plagued by careless bugs that I coded all the time, I would probably also be seeking out novel ways to prevent those bugs, even if it meant junking up my code with a lot of defensive measures like declaring every local variable as final. But I’m not plagued by the sorts of bugs mentioned in the above comments. I occasionally create them, of course, but I find them, fix them and move on.
“One of the things final fields help with is thread safety. I can only assume you have never had a field change when you didn’t expect it to.”
No I haven’t. One of my habits is to always assume a multi-threaded environment. So, when I’m working with a static or an instance variable (field) in a method, I’ll assign it to a temporary local variable which won’t be changed by another thread. (Particularly when I’m using lazy instantiation.) Or, if the situation calls for it, I’ll use synchronization. And if the value of a field is never going to change, I have no objection to declaring it as final, and I usually in fact do.
“There is a measurable benefit in using final fields. Its not big but applications do perform faster as the JVM can optimize access to such fields.”
But the discussion above has been more about declaring local variables as final, than fields. And if there’s any efficiency gained by making a local variable final, it’s likely offset by the cost of extra final variables that are needed every time the value changes (as discussed above), and if not, the gain wouldn’t be worth the extra clutter in the code, at least not to me.
There is another (more?) important thing about final variables: it communicates the intent of the variable to the reader of the source code.
I find variables that are defined final easier to reason about.
If the varible does/should not change, then make it final. It’s not that hard, is it? Actually, Eclipse can be configured to automatically insert ‘final’ for variables/fields/parameters that can be final. That’s very nice.
“And then again, maybe I’m just less prone to introducing bugs into my code.”
“I’m not plagued by the sorts of bugs mentioned in the above comments. I occasionally create them, of course, but I find them, fix them and move on.”
I agree that I rarely introduce bugs into code I have written and often fix them quickly when I do.
However, consider you are in a team of say 80 developers of varying coding standard working on a code base of 2.5 million lines of code which is a few year old. The main application has 600 threads fired off in no consistent manner.
You are reading a large section of code you have to work on for the first time and you have no idea which variables might change when and in what weird and wonderful ways. The simplest first step is to do what @Torgny Andersson suggest (I use IntelliJ which has 650 code analysis inspections) and turn as many fields final as possible and as many inner classes/methods static as possible etc. Essentially you are doing a basic code tidy up wishing the previous developer had bothered to do more housekeeping.
You might assume why worry if the code works. Actually this is a dangerous assumption because you will find there have been so many layers of code added that even if the application works the code may have never have worked but someone may have added a work around on top. (Actually several people may have added pieces of work arounds in many different places) Until the code you are working on isn’t really called so it does really work and never has.
On one program I worked it had 263 calls to System.exit() typically without a warning message. Numerous examples of infinite recursion.
Often enhancing a feature meant getting it work in the first place.
And in this kind of environment you find lots of bugs which are highlighted by code analysis and a common refactoring trick to get some control over the code is to place final on as many fields as possible. For large methods it can be worth adding final variables as well. However I would say a better option is to break up the methods into smaller ones if possible. When you extract a method in IntelliJ it can detected other blocks of code which can be replaced by the method and gives you the option of replacing these as well.
“I’ll assign it to a temporary local variable” - I assume where ever a variable might be used more than once.
Not sure if this is simpler or not “cluttering up your code” when just adding final does the same thing. Obviously for non final variables you should do this where appropriate.
“But the discussion above has been more about declaring local variables as final, than fields. ”
I take your point. However I would broaden the claim that final be the default modifier for variables and fields and you should have a keyword to signify non-final variables.
“for (final int i = 0; …”
You can use final in foreach loops as the variable has the scope of the block e.g.
for(final String line: readByLine(filename)) {
}
“However, consider you are in a team of say 80 developers of varying coding standard working on a code base of 2.5 million lines of code which is a few year old”
Ah, exactly my territory :-)
@peter lawrey,
Then I would argue that you’re barking up the wrong tree if you think your problems could be mitigated, much less solved, by coding conventions. Incompetent programmers will produce inferior code, period. It sounds like the root of your problem is your management’s inability to recruit, hire and retain reasonably competent programmers.
“[…] recruit […]”
Ah, recruit. Getting the best usually can only be done with:
Lots and lots and lots of money -> need to have a VC or an IPO or both (be Google)
Grow your developers on a tree.
Wait, wait, wait until you find the right person.
@stephan,
Not the right person, a right person. Notice that I said “reasonably competent”, not, to use your words, “the best”.
Whoever randomly sprinkles a codebase with unwarned System.exits or endless recursions, is not competent at all. They’re doing more harm to their team’s development effort than good, at least in my opinion. Keeping them on the team is a failure on the part of management, again in my opinion.
As a team manager I apply the wait, wait, wait strategy. Hiring people who put
System.exit()everywhere does not scale. In the end it does cost much more than they are worth, as you’ve said.Not sure what all this noise is about making all variables final. Seems quite ridiculous to make method parameters final in Java. What is this getting you? The semantics are the same for the caller of your method whether you make them final or not. What exactly are you telling the user of your method with this final keyword?
BTW: I was in an interview recently when they were discussing a language they had invented in house. !! While it had some pluses I could see, I was a bit shocked when they said the libraries had 30 million lines of code.
I have developed a small framework which is just over 30K lines and in a recent rewrite I got rid of 10K…
Anyway, I have found what works for me and what works for a team of diverse individuals are not the same. In a team I tend to prefer defensive approaches which minimize assumptions.
“Anyway, I have found what works for me and what works for a team of diverse individuals are not the same. In a team I tend to prefer defensive approaches which minimize assumptions.”
Same for me.
I always use the final keyword in my code.
At first it seems that writing final everywhere will clutter the code, but I found it the opposite: When I define a non final variable, I KNOW for sure it will be assigned more than one time (this saves time too.)
Consider also the tricky relationship between final and method overriding, as I discussed here:
http://groups.google.com.ar/group/comp.lang.java.programmer/browse_thread/thread/ef31c6c22307d11b/22bc937b17d51703
Gabriel
“I haven’t been using the final keyword in Java for 10 years…” - that is sad, was someone stopping you from reading (freely available) books? :-) http://www.parashift.com/c -faq-lite/const-correctness.html ,and Bruce Eckel wrote about const correctness in Java in his “Thinking in Java”. Why do I always feel that the most common
characteristic of java developers is their ignorance? :-)
@hacklberry: As I’ve written lots of Ruby, Perl, Python, C, Delphi and some Groovy in the past 15 years, shouldn’t it be that “the most common charactersitic of Ruby, Perl, Python, C, Delphi, Groovy and Java developers is their ignorance” ? :-)
“The semantics are the same for the caller of your method whether you make them final or not. ”
Good point. I would agree that final parameters for a method make no difference to the caller. So making them final by default would have no impact in that situation either.
I adopted the habit of making all variables final about a year ago, and I don’t regret it. It’s the right thing to do, especially in relatively long methods.
“It’s the right thing to do, especially in relatively long methods.”
Can you elaborate on the right thing? Why? And, it’s usually considered bad practice to have long methods so that’s not really a good point, is it?