• 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
  • Paul Clapham
  • Tim Cooke
  • Jeanne Boyarsky
  • Liutauras Vilda
Sheriffs:
  • Frank Carver
  • Henry Wong
  • Ron McLeod
Saloon Keepers:
  • Tim Moores
  • Frits Walraven
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
Bartenders:
  • Al Hobbs
  • Piet Souris
  • Himai Minh

Unexpected polymorphic behaviour when raw type is used ?

 
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi guys, wondering if anyone could help explain what is going on here ...


I could understand how a parameterised type of Base<Integer> b might be able to make a polymorphic call to a Sub's method(Integer i) but how could a variable of raw type of Base b possibly determine that it should call the Sub's method(Integer i) ? Is it "inferring" this from the declaration of Sub extends Base<Integer> .. if that's that the case it seems like a BIG leap for the compiler to make ?

I would have expected raw Base b to only be able to "see" it's own method being method(Object t) and therefore only able to call it's own method(Object t) (and NOT be able to call method(Integer i) in Sub ?

Any help in understanding this would be really appreciated.

Thanks, John

 
Marshal
Posts: 76447
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think what it is is that you have specified what T is before extending the class. You say a Base can take any type, but in the Sub class you are saying you want to use Integers.

Anyway, the runtime type is Sub, so you will get the subtype's method called regardless. That is what polymorphism is all about. Had it not been obvious to the javac tool which versions were avialable, you would not have got the sub method, nor would you have got the base method to run. You would have suffered a compile‑time error.
 
Campbell Ritchie
Marshal
Posts: 76447
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I do not think you are using a raw type anywhere.
 
author
Posts: 23928
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

Campbell Ritchie wrote:I do not think you are using a raw type anywhere.



I think that the OP was referring to the Base reference declaration.

... but ... regardless, Campbell's explanation is correct. Since, a Sub IS-A Base<Integer>, the compiler know that the Sub class method call is an override, and produces code to deal with it appropriately.

Henry
 
John Mulholland
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Richie.

At Line 15 Base b = new Sub(); I use a reference variable of type Base (not Base<Type>).

What I can't see is how a Base b could possibly recognise the method(Integer i) in Sub (even though Sub ITSELF has been declared Sub extends Base<Integer>).

Could the compiler have inserted a bridge method - method(Integer i){} - into Base as part of the type erasure process ?
 
Campbell Ritchie
Marshal
Posts: 76447
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

John Mulholland wrote:. . . I use a reference variable of type Base . . .

Never mind what type the reference is, it is the runtime type that matters. Because you said it extends Base<Integer>, you have obviously been considered as overriding that method. Try again with the @Override annotation. If you want to see any methods mysteriously added in compilation try
javap -c Base
or similar. You may omit the -c for a shorter printout.

Do you actually have a raw type? I don't know.
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

John Mulholland wrote:What I can't see is how a Base b could possibly recognise the method(Integer i) in Sub (even though Sub ITSELF has been declared Sub extends Base<Integer>).
Could the compiler have inserted a bridge method - method(Integer i){} - into Base as part of the type erasure process ?


No, it's simple execution. When you write b.method(10), you are asking the JVM to execute b's instance method; and since b (as we already know) is a Sub, it calls the method defined for Sub - that's how polymorphism works. It's a runtime determination, not a compile-time one.

And from the compiler's standpoint there's nothing wrong with the call either, because 10 (at least in this context) is an Integer - which is also an Object.

HIH

Winston
 
expectation is the root of all heartache - shakespeare. tiny ad:
Garden Master Course kickstarter
https://coderanch.com/t/754577/Garden-Master-kickstarter
reply
    Bookmark Topic Watch Topic
  • New Topic