the blog for developers

All variables in Java must be final

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

You can leave a Reply here. Of course, you should follow me on twitter here.

You can share this post!
Do you want to tell others about this article? Use the social bookmark icons to submit this artice to the service of your choice. Thanks.

About the author: Stephan Schmidt is head of development at brands4friends. He has more than 15 years of internet technology experience and 10 years experience in agile. He was head of development, consultant and CTO and is a speaker, author and blog writer. He specializes in organizing and optimizing software development helping companies by increasing productivity with lean software development and agile methodologies. Want to know more? All views are only his own.
Leave a reply.

Comments

John

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?

pwilder

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.

stephan

@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 freeze thanks 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!

stephan

@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 transient should 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.

kj

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) {
}

raveman

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)

stephan

@kj: I’m not sure if the const keyword 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.unmodifiableCollection which cannot be differntiated from normal Lists in the API)

stephan

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

stephan

@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…

stephan

@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. :)

stephan

@Torgny: :-)

choucri

You sound like someone who would love to discover Scala! Check this link:
http://www.codecommit.com/blog/scala/roundup-scala-for-java-refugees

stephan

@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);

}

stephan

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

stephan

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

stephan

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.

stephan

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

stephan

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

stephan

Thanks.

You could fix this with a

if (predicate) {
return true;
}
return false;

Not as nice, but possible with another Loop implementation.

stephan

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…

stephan

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. :)

stephan

:-)

stephan

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.

stephan

@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 Collections would provide an apply() method, the implicit loop would be there, in infrastructure code. i don’t care if they use final or not.

Rubys each needs 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. :)

[...] All variables in Java must be final at Stephans Blog (Java) [...]

DG

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.

stephan

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

DG

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

stephan

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.

DG

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.

stephan

“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. :)

stephan

I wanted to hack javac to do fun things for quite some time, especially since everyon hacks his own closure implementation :-)

DG

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

stephan

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

DG

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.

stephan

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

DG

@peter lawrey:

“You must have been using Java for very different things than myself.”

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)) {

}

stephan

“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 :-)

DG

@peter lawrey,

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.

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.

stephan

“[...] 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.

DG

@stephan,

Wait, wait, wait until you find the right person.

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.

stephan

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.

BA

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.

stephan

“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

hacklberry

“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? :-)

stephan

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

Sipowitz

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.

BA

“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?

I couldn’t agree more. Make everything final that can be. I’d add to that the final keyword for class declarations. All classes in Java should be declared final unless they are declared abstract.

Greg Mildenhall

“There’s a reason they’re called variables.”

Yes, but it’s not what you think.

It comes from the mathematical usage. The value of the variable varies from one application of the function (invocation of the method) to the next, _not_ within one. So in maths, all variables are final – and their functions end up so clearly-defined and well-behaved that they typically _prove_ that they’re correct. ;)

The last sentence was kinda tongue-in-cheek but I do agree with the make-it-final agenda even Java seems to go out of its way in many places to stop you adhering to good coding practices like that one.

Peter Lawrey

One problem with making class either final or abstract is that you cannot create instance of abstract classes. This may be too restrictive and I think a lot of classes are neither final or abstract for good reason.
I would suggest in this case there be a third option of an inheritable class which can be instanciated.

I think that final fields are great. Declaring most/all of the fields as final dramatically reduces the chances of Null-Pointer-Exceptions in the code.

As for local variables things are somewhat more complicated. One case is loop variables which cannot be final. Another case is formal parameters whose values sometimes need to be adjusted. Of course you this can be solved by introducing an additional local variable but it is not always worth the extra verbosity.

Anyway, I agree that final should be the default. Also, I like very much the idea of having the final qualifier hidden by the IDE.

intellij has an inspection for re-use of local variables, so you have have it flag it as a warning/error as desired without the noise of the final keyword everywhere.

I agree with your basic premise, I love using final everywhere. I love using them in classes to make them immutable. What I wish was the case is that Java and Java Beans would better support them. I find it so frustrating that to use any bean utility or more importantly do any form of serialization (to XML, Java serialization, or databases) you must have a bloody no arg constructor! If there were only a good way around that constraint.

[...] with the up/down side of the suggestion, if you eager to do that, just do that somewhere else (here for [...]

I really like this idea and am also trying to apply it to C# (which uses const & readonly) – but I’m not finding a way to make method params “final”. Any ideas how to duplicate this behavior in C#?

newton

I think you mean “All class member property must be final”,if not,the code “for(final int=0;…” looks funny.

I agree with you because of readability.

Regarding “hacking javac” — when you’re doing that, could you enable the “goto” command? Thanks.

Facetiously yours (smirking),

Randolf.

chrisn

First off, I agree with the premise of this article completely. I think your suggestion about variables being final automatically and then transient or mutable only by declaration is a great idea.

‘let’ statements make this type of programming a lot easier, at least for me. They allow declaring more variables and clearly show the dependency graph of how one value depends on previous values.

Have you checked out clojure? It is quite strict about mutability and super fun because you are programming in LISP which is quite beautiful.

For .net, instead of warping C# into some bizarre form I like to use F# in my happy place where I don’t have to worry about other devs bitching about learning a new language.

@Chrisn: Yes I have, see my Scala vs. Clojure posts and I like Clojure a lot. That said, I think Clojure will need to fight an uphill battle to get into mainstream.

Matt Gumbley

@DG “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.”

When you copy the variable to a temporary, you should do so under synchronization.

“It is a common mistake to assume that synchronization needs to be used only when writing to shared variables; this is simply not true.” [Java Concurrency in Practice, Goetz et al, p 28]

I’ve been coding in Java for a number of years now – and I have to say that, contrary to a lot of the comments here, I almost completely disagree.

I’ll start off with a positive though; I do think the final keyword is underused in Java when dealing with variables that shouldn’t change. I’ll often define parameters and variables as final, and it’s used a lot in my code as such. If I’m declaring a variable I don’t intend to change, I’ll mark it as final so I get an unavoidable warning if I then change it. Sometimes I’ll remove the final keyword, sometimes I’ll do things a different way; the important thing here is it causes me to think. Was my original logic incorrect when marking the variable as final, or am I reusing a variable I shouldn’t touch?

However, all variables being final?! Why?! Counters and loops are the two classic examples, but I’ve reassigned many variables in code other than these and I make no apologies for doing so (parameters included.) I can safely say I’ve never introduced a bug through doing so.

I see the closure example above that avoids loops, but again – why?! It’s introducing something comparatively complicated that can be achieved in a perfectly logical, reasonable and bug free fashion already.

I also completely agree with Java’s methodology of creating classes non-final (extensible) by default. The whole point and focus of OO is that you design classes to be extensible – if you’re finding this difficult (with the exception of a few cases such as singletons / utility classes) then sorry, but you’re just not designing good OO code. Inheritance is a brilliant idea, it vastly cuts down on code duplication and when used correctly reduces the potential for many bugs. It’s a growing trend that people are designing classes not to be extended, or just randomly marking them as final (C# is adding to this trend unfortunately) – this is bad.

“Functional Programming is a state of mind not a programming language. So people can code FP in Java.”
No no no!!! This, in my mind is the statement that sums it all up. Java is not designed for people to write functional style code, it’s designed for people to write object oriented code. If you come along from an OO viewpoint, it’s fantastic. If you come from a functional viewpoint then of course you’re going to have to bodge your way around language features to get it to behave how you want, it just wasn’t designed for that purpose! It’s a bit like me buying a land rover and claiming that it’s not designed nearly as well as a Ferrari for a smooth race track (or vice versa…)

Playing devil’s advocate, you could argue the same case procedurally that the static keyword should be there by default and you should only put a keyword on a method if its non static. If you’re using Java as a procedural language it’ll help cut down on verbosity, but in short you just shouldn’t be doing that.

If you want to write functional code then by all means go ahead, but Java is not the tool for the job (and neither should it be.) Yes, it’s a mindset, but it’s a mindset that you generally apply to specific languages like Erlang, F# or Haskell – languages designed for that purpose.

“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”
Sorry to say, but I can guarantee you with near 100% certainty that Java will never make variables or classes final by default. The changes to volatile were necessary to fix the broken double checked locking pattern (needed to lazily instantiate singletons in a threadsafe manner.) They were minor changes and actually fixed a heck of a lot of previous code rather than breaking any (IIRC the change was to the optimisation side of the JIT compiler, as such the only side effect was a very minor performance hit on some JVMs which has now been addressed in the vast majority of cases.)
Changing the fundamental behaviour of a major keyword though is a complete no go. Aside from the fact it’d break pretty much ALL existing code, I think you’ll find the vast majority of Java developers will take a similar standpoint to me and disagree with the change entirely. Major disruption over a very controversial change just won’t be allowed – just look at the effort they took in getting generics working in a backwards compatible way for instance (and a very good job they did of it too.)
Yes, I’ve read the comments about the -final switch on the compiler, but in practice this is again a silly idea in my opinion. Do I have to blindly guess at how I should compile each java project, with or without -final? You’re also losing a lot of intelligibility, when reading some Java at the moment I can tell you just based on the code whether it will compile or not. Start adding in all sorts of bizarre switches that change the behaviour of fundamental keywords and I can’t say whether it will or won’t, or how it’ll behave… that takes me back to VB and the likes of whether I’ve got option explicit on or not, which is not a mindset I want to be in!

If you were talking about a functional style language here, I’d entirely agree. But you’re not – you’re talking about adding very functional concepts to an OO language…

[...] with the up/down side of the suggestion, if you eager to do that, just do that somewhere else (here for [...]

Leave a Reply

What people wrote somewhere else:

Additional comments powered by BackType

Guide to CodeMonkeyism

Over the last 4 years I wrote many articles on this blog. To make it easier for you to find the relevant ones, I've organized them into topics.

Top 10

6 reasons why my VC funded startup did fail

Go Ahead: Next Generation Java Programming Style

Java Interview questions: Write a String Reverser

The dark side of NoSQL

7 Bad Signs not to Work for a Software Company or Startup

Is Java dead?

Scala vs. Clojure

Never, never, never use String in Java

No future for functional programming in 2008 – Scala, F# and Nu

Clojure vs Scala, Part 2

Java Developer

Is Java Dead?

Go Ahead: Next Generation Java Programming Style

Be careful with magical code

All variables in Java must be final

Never, never, never use String in Java

Bending Java: More readable code with methods that do nothing?

NoSQL Guy

NoSQL: The Dawn of Polyglot Persistence

The dark side of NoSQL

Essential storage tradeoff: Simple Reads vs. Simple Writes

Sharding destroys the goals of your relational database

The unholy legacy of databases

Startup/CTO

Development Dream Teams

6 reasons why my VC funded startup did fail

American vs. European style of Software Development

12 Things to Reduce Your Lead Time and Time to Market

The high cost of overhead when working in parallel

Essential storage tradeoff: Simple Reads vs. Simple Writes

Job Seeker

Another Good (Java) Interview Question

7 Bad Signs not to Work for a Software Company or Startup

Java Interview questions: Write a String Reverser (and use Recursion!)

Java Interview questions: Multiple Inheritance

As a Manager: What I value in developers

Top 10 Tips (+1) to Get a Pay Raise

Agilist

What Developers Need to Know About Agile

5 Practices Better to Change in Your Scrum Implementation

Scrum is not about engineering practices

ScrumMaster and ZenMaster: The joke of certification

What is Trans-Scrum?