Recently I got stuck on an old consideration of mine related to usage of private and final in Java. The Private -visibility declaration limits the methods’ or properties’ visibility to the class itself only, and declaring something as final prohibits declaration of any further sub-classes. Final might also allow some minor performance optimizations on some Java JDKs.
While this is not a programming language specific problem, I have learned since that declaring everything to final is almost considered as a best practice in Java (see http://www.javapractices.com/topic/TopicAction.do?Id=23 ). Eclipse often auto-suggests declaring variables as final, so it might seem like a good thing to do (but is not).
Personally I have thought about the usage of private and final in Java and Object Oriented programming, and found little use for them. Declaring methods or classes final makes code-reuse by inheritance difficult. Similarly the default usage of private makes code-reuse to require always a change to the super class (you need to re-declare it as protected). If you are using a framework or a library (such as Apache Wicket) with final classes or methods, or the java.lang.String, you might be out of luck unless you fork and recompile the whole dependency tree and related libraries. Thus, I personally strongly favor declaring everything as non-final and protected instead, by default. This leaves the future extensions and code re-use possibilities open, and doesn’t artificially undermine the core promises of Object Oriented programming (of code re-use and encapsulation).
The second downside of overly usage of privates and finals is making the unexpected future usages of your code much harder. Recently I got excited about LambdaJ and the possibility to use functional programming style in Java to make the iteration over Java Collections to look nicer and shorter. The rise of functional programming was probably not something that Java core architects or Apache Wicket’s developer had seen in advance when they initiated their projects. However, a major hindrance of the otherwise excellent LambdaJ library came from the Java practice of declaring everything as private and final in Java. For example you cannot use LambdaJs basic select() -operation to String, because it is declared as final. See my other article on LambdaJ. I hope that Java 8 brings some relief to this problem, but it is also a matter of coding convention.
Do not declare anything as final or private, unless there is a REALLY good reason for it. Use non-final methods and protected visibility instead.