I understand that in this code:
class Foo {
public static void method() {
System.out.println("in Foo");
}
}
class Bar extends Foo {
public static void method() {
System.out.println("in Bar");
}
}
.. the static method in Bar
'hides' the static method declared in Foo
, as opposed to overriding it in the polymorphism sense.
class Test {
public static void main(String[] args) {
Foo.method();
Bar.method();
}
}
...will output:
in Foo
in Bar
Re-defining method()
as final
in Foo
will disable the ability for Bar
to hide it, and re-running main()
will output:
in Foo
in Foo
(Edit: Compilation fails when you mark the method as final
, and only runs again when I remove Bar.method()
)
Is it considered bad practice to declare static methods as final
, if it stops subclasses from intentionally or inadvertantly re-defining the method?
(this is a good explanation of what the behaviour of using final
is..)
I encountered one detriment to using final methods using Spring's AOP and MVC. I was trying to use spring's AOP put in security hooks around one of the methods in the AbstractFormController which was declared final. I think spring was using the bcel library for injection in classes and there was some limitation there.
When I create pure utility classes, I declare then with a private constructor so they cannot be extended. When creating normal classes, I declare my methods static if they are not using any of the class instance variables (or, in some cases, even if they were, I would pass the arguments in the method and make it static, it's easier to see what the method is doing). These methods are declared static but are also private - they are there just to avoid code duplication or to make the code easier to understand.
That being said, I don't remember running into the case where you have a class that has public static methods and that can/ should be extended. But, based on what was reported here, I would declare its static methods final.
Most of this
final
issue dates back to the time when VM-s were quite dumb/conservative. Back then if you marked a methodfinal
it meant (among other things), that the VM can inline it, avoiding method calls. That is not case since a long-long (or long double :P ) time: http://java.sun.com/developer/technicalArticles/Networking/HotSpot/inlining.html .I guess that Idea/Netbeans inspection warns you, because it thinks that you want to use the
final
keyword for optimization and they think that you are unaware of the fact that it is unneeded with modern VMs.Just my two cents...
If I have a
public static
method, then it's often already located in a so-called utility class with onlystatic
methods. Self-explaining examples areStringUtil
,SqlUtil
,IOUtil
, etcetera. Those utility classes are by itselves already declaredfinal
and supplied with aprivate
constructor. E.g.This way you cannot override them.
If yours is not located in kind of an utility class, then I'd question the value of the
public
modifier. Shouldn't it beprivate
? Else just move it out to some utility class. Do not clutter "normal" classes withpublic static
methods. This way you also don't need to mark themfinal
.Another case is a kind of abstract factory class, which returns concrete implementations of self through a
public static
method. In such case it would perfectly make sense to mark the methodfinal
, you don't want the concrete implementations be able to override the method.