There are typically two reasons to make a method final, performance and design.
When a method is final, it may be inlined. Before HotSpot compiling (JDK 1.1.x), these methods were usually inlined at compile time, whereas with HotSpot they are inlined at runtime, unless the compiler can guarantee that the inlined method will always be compiled together with the code that uses it.
Code:
// somebody else's class
public class A {
public static final void f() {
System.out.println("A's f()");
}
}
// our class
public class B {
public void g() {
A.f();
}
}
In the past, at compile time our class would be turned into:
// compiled class
public class B {
public void g() {
System.out.println("A's f()");
}
} The effect of this was that we had to make one less method call, and since method calls produce extra overhead, we saved some clock cycles. The disadvantage of this, made clear to me by an old (ok, experienced) COBOL programmer during one of my courses, was that whenever somebody else's class changed we would have to remember to recompile our class!
In JDK 1.[234].x with HotSpot(tm), Sun changed this so that the methods were no longer inlined at compile time, but rather by the HotSpot compiler at run time, IFF the performance measurements suggested that it would improve the overall performance of our code.
There are quite a few factors which will affect whether a method will be inlined or not, and we cannot assume that just because we make something final that it will definitely be inlined. As we saw in newsletter 21, it is a good idea anyway to always recompile all your code when you get a new version of someone else's library, so this is not necessarily a reason to NOT use final methods.
When you make a method final, no-one else will be able to override it again. You thus limit extensibility of your code by choosing to make the method or, even worse, your class final. I have been utterly frustrated in the past when I wanted to extend code where the developer had tried to add optimizations in the form of final. I thus never make a method or class final unless I specifically want to stop do others from overriding them.
So, when do I use final methods? If I have performance values that prove that final makes a difference then I would consider using it for performance reasons, otherwise I would only ever use it for design reasons.