Had a discussion at work today about the Java final keyword… it’s an insidious creature not in what it is, but what assumptions it gives people who read the code.

Let’s say you have a function that looks like this:

public String doSomething(final Foo someFooObject) { /* stuff */ }

This is of course a valid thing (excluding of course that I elided the body!). Most programmers, my colleagues included, look at that and thing “well, I guess the someFooObject is an invariant.”

They are half right. But normally the assumption falls on the wrong half.

Programmers who have programmed C++ immediately equate “final” to “const.” This is a problem since “const” and “final” mean very different things.

Final just means that the reference can’t be changed. The state of the instance can be changed all you want assuming there are mutating functions on Foo. It’s just that you can’t assign a new instance to the local variable. Since Java is a reference-passing language just because the reference can’t change to point to a new object doesn’t affect how you can interact with the object being referenced.

Const, on the other hand, says the contents of the object are constant.

The reason this came up is there’s some checkstyle rule that says function parameters must be final.

What rubbish.

It has some utility, but oftentimes the assumptions override what little utility it might actually have.