Michael Feathers goes public with the idea that "final" is just a bad idea:
Well... no.. not really. Here's the problem: When you use final pervasively, you make unit testing nearly impossible. Believe me, I know. I encounter enough teams who are in that situation. Have a class A which uses a class B that is final? Well, you'd better like B when you are testing A because it's coming along for the ride.
Extract an interface for B? Sure, if you own B. If you don't, you have to wrap it to supply a mock. And.. here's the kicker: if you are going to wrap B, well, what about security? All final does for a class is guarantee that the class itself won't be the point of access, but what about your wrapper? If you use the interface of the wrapper everywhere, again, because you want to test, the developers of B haven't made your software more secure, they've merely pushed the problem onto your plate: they've forced you to choose between testability and security. It's rather interesting to consider that perhaps we truly can have security, but only if we can't really be sure our software works.
The suggestion he has is the one that has been used in Smalltalk since the beginning: conventions that explain to developers which parts of a class' API might change in the future. What "final" does is attempt to lock the door before anyone's been in the house to look around. It assumes perfect knowledge about future usage, and that's a bad assumption.