3

It is written everywhere that static method cannot be overriden, but when I try to reduce the access specifier say from public to protected it gives an error. for example

public class StaticOverrideFunda {

    public static void foo(){
        System.out.println("Parent Foo");
    }
}

public class B extends StaticOverrideFunda{


    protected static void foo(){
        System.out.println("Child Foo");
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        B.foo();            
    }
}

It says

Cannot reduce the visibility of the inherited method

So insense it is following the overriding rules, how come we are saying foo is not being overridden in B class? Why do we say it is hiding/shadowing and not overriding?

pushy
  • 9,535
  • 5
  • 26
  • 45
Jyotirup
  • 2,882
  • 9
  • 30
  • 38
  • 4
    "it is following the overriding rules": false. It's breaking the "cannot reduce the visibility of the inherited method" clause. What is your question exactly? – Viruzzo Apr 24 '12 at 11:52
  • It seems to me that the real question is: what benefit results from prohibiting the subclass from reducing the access of an "inherited" static method? The only benefit I can see is text reuse in the JLS. – Alan Snyder Dec 06 '21 at 14:59

2 Answers2

8

It's following some of the same rules as overriding, but that doesn't mean it is overriding. In this case, it's the rules in section 8.4.8.3 of the JLS, "Requirements in Overriding and Hiding":

The access modifier (§6.6) of an overriding or hiding method must provide at least as much access as the overridden or hidden method, as follows: [...]

It's still not overriding, as the method wouldn't be invoked polymorphically - you can't write a call which will sometimes end up calling StaticOverrideFunda.foo and sometimes end up calling B.foo; the target is determined entirely at compile time.

It would be worth reviewing the rest of section 8.4.8, which defines overriding as being something which occurs on instance methods.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    Hmm, that's a surprise to me. What's the point of not allowing a hiding method to have less visibility than the method it hides? It makes sense for a method that can be called polymorphically since anything that can call the superclass method has to be allowed to call the subclass one too. But that's not the case for a static method that hides rather than overrides. – Wyzard Apr 24 '12 at 11:59
  • 1
    @Wyzard: I agree that it's slightly odd to prohibit a reduction in visibility. However, it's possible that it's trying to avoid a situation where you have an explicit call to `Subclass.foo()` which is a private method which would *normally* resolve to `Superclass.foo()`. Either way, it's behaving exactly according to the JLS, and it's still not overriding. I would recommend against declaring a static method in a subclass with the same name as a superclass static method anyway, to be honest. It's just going to lead to confusion. – Jon Skeet Apr 24 '12 at 12:03
  • Why should that situation be avoided? Why would a programmer write Subclass.foo() when the intent is to call Superclass.foo()? – Alan Snyder Dec 06 '21 at 14:57
  • @AlanSnyder: Because they may not know any better. I regularly see people writing `UnicodeEncoding.UTF8` in .NET for example, which is confusing and weird. (`UTF8Encoding.UTF8` would be bad enough, but using a *different* encoding subclass to access `Encoding.UTF8` is very odd. But it happens.) – Jon Skeet Dec 06 '21 at 15:02
  • An IDE could help with a warning in such cases. – Alan Snyder Dec 08 '21 at 01:03
-1

You yourself posted answer in your question, overriding means having different code in child class for same method. As static methods cannot be overridden you cannot play with the visibility by modifying access specifiers.

Rahul Borkar
  • 2,742
  • 3
  • 24
  • 38