A final bit of advice

7

Or maybe that should be “a bit of final advice”. :) There was a question on StackOverflow about best practices around using final in parameters, local variables, fields, etc and my answer seems to have been popular. I’ll repeat it here merely to make it easier for me to find later.

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.

Comments

7 Responses to “A final bit of advice”
  1. Casper Bang says:

    My practice is much the same. I’ve found though that by adding final to arguments I gain some more insight over flow and scopes, which tends to yield refactoring into better™ code.

    Interesting you do not comment on the urban legend of how final methods are faster since they can skip consulting the vtable after having been inlined at runtime.

    It would be nice if javac could do a bit more analysis and allow final on fields by indirect constructor initialization, handy when i.e. writing factory methods. A kind of “final once set”.

  2. I’m equally lazy about making parameters and local variables final and agree that it makes the code less readable. Of course I like Ruby and Smalltalk, so of course I lean toward less noisy code.

  3. Alex says:

    @Casper: I didn’t comment as any performance tip like this has a half life of about 6 months. I’d love to see a program that could actually detect a difference in performance between a final and non-final method. :) Worrying about that is a waste of time…

    I agree that it would be good to have more official options regardng “effectively immutable” objects. This comes up occasionally on the Java Memory Model and concurrency mailing lists. See here for example: Documenting Effective Immutability. It does seem like something that JSR 305 could define and that tools like FindBugs could verify.

  4. Buddy Casino says:

    I like final method parameters in larger methods, especially for primitive types. That way, I don’t have to scan the whole method body for parameter modification and can just safely assume that I get what I think I get.

    I agree with the rest, though.

  5. Anonymous says:

    FYI, a complete discussion on the topic: http://www.ibm.com/developerworks/java/library/j-jtp1029.html

  6. Jeff Grigg says:

    Yes, as the article the previous poster referenced (http://www.ibm.com/developerworks/java/library/j-jtp1029.html) says, “final” is useless as a performance improvement technique: The compiler can’t use it, and the JIT runtime optimizer doesn’t need it. The runtime JIT will routinely inline non-final methods that don’t happen to be overridden by currently loaded sublcasses. And it’s smart enough to undo the inlining if a newly loaded subclass does override the method. So final is useless as a performance optimization technique.

Speak Your Mind

Tell us what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!