Is it a bad idea to declare a final static method?

brasskazoo picture brasskazoo · Dec 19, 2009 · Viewed 28.8k times · Source

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..)

Answer

Gregory Pakosz picture Gregory Pakosz · Dec 19, 2009

I don't consider it's bad practice to mark a static method as final.

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:

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

No, marking the method as final in Foo will prevent Bar from compiling. At least in Eclipse I'm getting:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: Cannot override the final method from Foo

Also, I think people should always invoke static method qualifying them with the class name even within the class itself:

class Foo
{
  private static final void foo()
  {
    System.out.println("hollywood!");
  }

  public Foo()
  {
    foo();      // both compile
    Foo.foo();  // but I prefer this one
  }
}