• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

static method strange behavior?

 
Rancher
Posts: 1093
29
Netbeans IDE Oracle MySQL Database Tomcat Server C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This started in thread https://coderanch.com/t/657274/ocajp/certification/static#3046060 as a different question, but as I made this example, it seems the behavior is not right:

So I'm missing something, my understanding says: you can overload a static method, but not override it, and it is not inherited from the parent class.
In the example class B overrides F1() and inherits F1(int). If those methods are truly static, then they should resolve back to class A and not allow B to override F1(), but it does.
If the static methods are not inherited, then F1(int) should not be visible in B, but it is. If B inherits the static classes from A, then the Override annotation should work, but I get an error saying there is nothing to override.
 
Bartender
Posts: 1845
10
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes the static methods from A are "inherited" by B
However they do no participate in polymorphism.
If B declares a static method with the same signature as one in A, it replaces that method, and effectively hides it, making A's version of it inaccessible.
So it doesn't count as 'overriding'

There is one case that you neglected to test in your example:



Do you think this should this code call A's F1 method or B's ?




 
Les Morgan
Rancher
Posts: 1093
29
Netbeans IDE Oracle MySQL Database Tomcat Server C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stefan Evans wrote:Yes the static methods from A are "inherited" by B
However they do no participate in polymorphism.
If B declares a static method with the same signature as one in A, it replaces that method, and effectively hides it, making A's version of it inaccessible.
So it doesn't count as 'overriding'

There is one case that you neglected to test in your example:



Do you think this should this code call A's F1 method or B's ?



To my way of thinking it would call B's, but it does not. That is because the reference variable is declared as an A. The reference is static and still points to A's F1() method, even though, in B the A's method would be hidden. A's reference is still fixed at the original reference to F1().
 
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That's just how it works. As Stefan said, static methods are not overridden, but instead shadowed. The compiler does not use the actual type but the declared type. When you call b.F1(11), the compiler sees that b is declared as A and therefore calls A.F1(11). When you call c.F1(12), the compiler sees that c is declared as B and therefore calls B.F1(11). For the calls to F1() there is no shadowing so all are resolved to A.F1().
 
Ranch Hand
Posts: 59
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stefan Evans wrote:Yes the static methods from A are "inherited" by B
However they do no participate in polymorphism.
If B declares a static method with the same signature as one in A, it replaces that method, and effectively hides it, making A's version of it inaccessible.
So it doesn't count as 'overriding'

There is one case that you neglected to test in your example:



Do you think this should this code call A's F1 method or B's ?



what do you mean by hiding in this context?
 
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

s sivaraman wrote:
what do you mean by hiding in this context?



The term "hiding" is defined by the Java Language Specification as follows...

https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.8

Basically, it is saying while it may look like overriding (and polymorphism), it is not. And there are ways to reach the desired static method via casting (or specifying the class name).

Henry
 
Ranch Hand
Posts: 499
Spring AngularJS Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I was looking through our forums and came across this interesting topic. I have a doubt in this,

What will happen when we call F1() like this,



As per Stefan Evans,

Stefan Evans wrote:If B declares a static method with the same signature as one in A, it replaces that method, and effectively hides it, making A's version of it inaccessible.



B's F1() should be called.

But as per Rob Spoor,

Rob Spoor wrote:The compiler does not use the actual type but the declared type. When you call b.F1(11), the compiler sees that b is declared as A and therefore calls A.F1(11).


A's F1() should be called.

Which of the above will happen?

 
Marshal
Posts: 79178
377
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Partheban Udayakumar wrote:. . .

Stefan Evans wrote:If B declares a static method with the same signature as one in A, it replaces that method, and effectively hides it, making A's version of it inaccessible.

. . .

Rob Spoor wrote:The compiler does not use the actual type but the declared type. When you call b.F1(11), the compiler sees that b is declared as A and therefore calls A.F1(11).

. . .

Have you tried it? Both quotes are correct; Stephan said that the superclass' version of the method is inaccessible in the subclass, (although Henry points out you can gain access to it by casting). Rob said that the method appropriate to the declared type is used.

The answer is that calling static methods on an object reference is confusing and you should always call static methods on the class name. Otherwise you end up with rubbishy code like this:-
((Arrays)null).sort(myArray);
 
Partheban Udayakumar
Ranch Hand
Posts: 499
Spring AngularJS Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote: Stephan said that the superclass' version of the method is inaccessible in the subclass, (although Henry points out you can gain access to it by casting). Rob said that the method appropriate to the declared type is used.



So shadowing takes place only in the subclass. Rest will work normally. Did I get that right?
 
Campbell Ritchie
Marshal
Posts: 79178
377
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Partheban Udayakumar wrote:. . . So shadowing takes place only in the subclass. Rest will work normally. Did I get that right?

Most of it. You are not shadowing. You are hiding. We have an FAQ about that.
 
Rancher
Posts: 4801
50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
And pretty much all of this is handled by simply not calling a class's static methods using a reference to an object of that class.
Always use the class to access them, and you'll never hit this confusion.

IDE's even warn about this...
 
Partheban Udayakumar
Ranch Hand
Posts: 499
Spring AngularJS Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Most of it. You are not shadowing. You are hiding. We have an FAQ about that.


Thanks for the explanation
 
Campbell Ritchie
Marshal
Posts: 79178
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're welcome
 
reply
    Bookmark Topic Watch Topic
  • New Topic