8
public class Test
{
    static int i = 1;

    static void m1()
    {
    }
}

class Test1 extends Test
{
    int i = 1;    //allowed 

    void m1()     // not allowed; Both are instance level, so why this difference? Both can be accessed with super keyword
    {
    }
}

Why can't the static method be hidden with the same signature, but the static field is allowed to do this? Both are instance level, so why is only the static field allowed?

Kevin Cruijssen
  • 9,153
  • 9
  • 61
  • 135
Shahaan Syed
  • 109
  • 3
  • 1
    [Here´s not a clear answer, but it´s guessing that hiding static methods or vica verse could lead to confusion](http://stackoverflow.com/questions/14602220/why-doesnt-java-allow-hiding-static-methods-by-instance-methods) – SomeJavaGuy Apr 15 '16 at 08:45

1 Answers1

8

m1() in class Test is a static method, while m1() in Test1 is non static. Now imagine if this would have been allowed then which implementation would be picked by runtime when you execute below statement:

new Test1().m1();

Since instance of child class (Test1 in your case) can access also access static method from parent class (from Test). That is why it is not allowed.

For you next question why variable with same name is allowed in Test1: parent class' static variable can not be accessed from child class instance. In other words parent class' static state is hidden from child. That is

Test1.i;   // compilation error, can't access parent's static variable

will result in compilation error. And if you try

new Test1().i; // will access Test1's i variable

it will point to the child class' state not parent's. That is why child class can have variable with the same name.

Note: If i in Test was non-static, even in that case Test1 can have variable with name i. In this case i in Test1 will shadow i in Test.

EDIT

From Shahaan Syed's comment:

new Test1().i; why is this allowed is my concerned

To put Shahaan Syed's confusion in another words: Why

  • in case of variable, child class can have a non-static variable while parent class has a static variable with the same name,
  • on the other hand, child class can not have a non-static method when parent class has a static method with the same name?

As Kevin Esche commented, I also think that Java messed up somewhere by allowing access to static methods of parent class from instance of child class. Though it is not a good practice and compiler generates warning as well.

Here's a quote from (JLS §8.3):

In this respect, hiding of fields differs from hiding of methods (§8.4.8.3), for there is no distinction drawn between static and non-static fields in field hiding whereas a distinction is drawn between static and non-static methods in method hiding.

But I could not find any reasoning behind this in JLS.

I think instead of generating warning there should have been compile time error. That is accessing both static field and static method of parent class from child class instance, should have been compiler error. In this respect things would have been consistent and easy to understand. But again it's just my thought.

Another interesting question on the same line: Why isn't calling a static method by way of an instance an error for the Java compiler?

Community
  • 1
  • 1
justAbit
  • 4,226
  • 2
  • 19
  • 34
  • 4
    To add on this answer, it´s highly likely that this is done to avoid confusion which has it´s root in a bad language design here (beeing able to call static methods on object instances). – SomeJavaGuy Apr 15 '16 at 08:49
  • @sudhir singh , but same I would have said for new Test1().i; why is this allowed is my concerned point . – Shahaan Syed Apr 15 '16 at 08:50
  • 2
    @ShahaanSyed Because at this point the java language was designed poorly. Sadly that´s the only plausible answer here. – SomeJavaGuy Apr 15 '16 at 08:53
  • 1
    Exactly @KevinEsche , and there is no proper clarification given in JLS for this. – Shahaan Syed Apr 15 '16 at 08:55
  • In the first example, if Java supports using non-static method to hide static method, why doesn't `new Test1().m1()` called the non-static one? Just like the field `i`? – Nier Apr 15 '16 at 09:35
  • @SudhirSingh The first paragraph in your edited answer quoted `new Test1().i;`, but the text following by it is about **access to static methods of parent class from instance of child class**, I don't get it. I know the conclusion that access to static methods of parent class from instance of child class is a bad practice through the link you provided, but I don't know why you put that conclusion under `new Test1().i`, which seems just to access a field, not a method? – Nier Apr 15 '16 at 17:32
  • @Nier Okay, I see your point. I quoted field but discussed about method in the very next line, which might be bit confusing. Updated it with what Shahaan Syed wanted to say there. – justAbit Apr 15 '16 at 18:02
  • @SudhirSingh After reading the JLS, I think the reason why you can't use non-static method to hide static method may be because it's actually **overriding**, not hiding. Overriding lets you can call child's method by a reference of a Parent class. For example, if you assign a Test1 instance to a Test reference by `Test t = new Test1();`, and try to call m1 in t by `t.m1()`, it should call Test1's m1 method. So at runtime, JVM will check the actually type of the instance and try to invoke the method. This can be a problem if m1 is declared as static, because it can be called without instance. – Nier Apr 15 '16 at 19:01
  • BTW it's just my thought, too. I can't make sure why Java designed like this, either. And after reading the JLS, I think there's a big difference between hiding/overriding methods and hiding fields. They just share the same terminology. – Nier Apr 15 '16 at 19:03
  • @Nier Yes, but isn't the whole cause of the problem seems to be that Java allows accessing static method using object instance? – justAbit Apr 15 '16 at 19:25
  • @ShahaanSyed I think it's a different thing. Accessing static method by object instance is acceptable (but not a good practice) because you can determine what Class that instance is, and call the corresponding static method, and this is done in compile time, see the answer [here](http://stackoverflow.com/questions/1039229/are-static-methods-in-java-always-resolved-at-compile-time). However, overriding a static method is strange behavior, because static method should be resolved at compile time, but you override it, which means you want to determine which method to call at run-time. – Nier Apr 15 '16 at 19:44