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..)
Static methods are one of Java's most confusing features. Best practices are there to fix this, and making all static methods
final
is one of these best practices!The problem with static methods is that
therefore you should
final
and you should
NB: the second version of you program should fails a compilation error. I presume your IDE is hiding this fact from you!
The code does not compile:
The message is misleading since a static method can, by definition, never be overridden.
I do the following when coding (not 100% all the time, but nothing here is "wrong":
(The first set of "rules" are done for most things - some special cases are covered after)
Since an interface cannot have static methods you don't wind up with the issue. If you are going to make static methods in the abstract class or concrete classes they must be private, then there is no way to try to override them.
Special cases:
Utility classes (classes with all static methods):
If you want to have a static method in a concrete or abstract class that is not private you probably want to instead create a utility class instead.
Value classes (a class that is very specialized to essentially hold data, like java.awt.Point where it is pretty much holding x and y values):
If you follow the above advice you will wind up with pretty flexible code that also has fairly clean separation of responsibilities.
An example value class is this Location class:
I don't consider it's bad practice to mark a
static
method asfinal
.As you found out,
final
will prevent the method from being hidden by subclasses which is very good news imho.I'm quite surprised by your statement:
No, marking the method as
final
inFoo
will preventBar
from compiling. At least in Eclipse I'm getting:Also, I think people should always invoke
static
method qualifying them with the class name even within the class itself:Usually with utility classes - classes with only static methods - it is undesirable to use inheritence. for this reason you may want to define the class as final to prevent other classes extending it. This would negate putting final modifiers on your utility class methods.
It might be a good thing to mark static methods as final, particularly if you are developing a framework that you expect others to extend. That way your users won't inadvertently end up hiding your static methods in their classes. But if you are developing a framework you might want to avoid using static methods to begin with.
Because static methods are the properties of the class and they are called with the name of the class rather than of object. If we make the parent class method final as well it will not be overloaded as final methods does not allow to change its memory location but we can update the final data member at the same memory location...