• Post Reply Bookmark Topic Watch Topic
  • New Topic

Java Generics Overriding  RSS feed

 
Suhrid Karthik
Ranch Hand
Posts: 58
Eclipse IDE Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm trying to figure out why this is a valid override:



but this is not:



In this case, the compiler says: Name clash: The method foo(Collection<?>) of type Sub has the same erasure as foo(Collection) of type Super but does not override it.

Since they have the same erasure, both the signatures would reduce to foo(Collection c) - why is this not a valid override ? And why is it only so in the second case ?
 
Ogeh Ikem
Ranch Hand
Posts: 180
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A method in a subclass can override a method in a superclass only when its signature is identical to the superclass method's signature, or the erasure of the superclass method's signature. Based on this rule, a generic method cannot override a non-generic method but a non-generic method can override a generic method.
 
Suhrid Karthik
Ranch Hand
Posts: 58
Eclipse IDE Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ogeh Ikem wrote:A method in a subclass can override a method in a superclass only when its signature is identical to the superclass method's signature, or the erasure of the superclass method's signature. Based on this rule, a generic method cannot override a non-generic method but a non-generic method can override a generic method.


Thanks. But the compiler does say in the error message that the erasure's are identical, so hence the doubt.

[Edit: Corrected my question]



 
Ogeh Ikem
Ranch Hand
Posts: 180
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The compiler doesn't know what you're trying to do. Use the @Override annotation and see what the compiler says.
 
Ogeh Ikem
Ranch Hand
Posts: 180
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This might make it clearer

Suhrid Karthik wrote:The method foo(Collection<?>) of type Sub has the same erasure as foo(Collection) of type Super but does not override it.

In order for foo(Collection<?>) of type Sub to override foo(Collection) of type Super, it must have
  • the same signature as the signature of foo(Collection)(it doesn't), or
  • the same signature as the erasure of the signature of foo(Collection) (it doesn't...erasure of the superclass method doesn't even take place here)

  • This is why a generic method cannot override a non-generic method.

    The Java Language Specification uses the notion of a subsignature to

    express a relationship between two methods whose signatures are not identical, but in which one may override the other. Specifically, it allows a method whose signature does not use generic types to override any generified version of that method.

    The Java Language Specification defines a subsignature as follows:
    The signature of a method m1 is a subsignature of the signature of a method m2 if either
  • m2 has the same signature as m1, or
  • the signature of m1 is the same as the erasure of the signature of m2.
  •  
    Seetharaman Venkatasamy
    Ranch Hand
    Posts: 5575
    Eclipse IDE Java Windows XP
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    suhrid, mixing raw type and generic type always take you in confusion! you should avoid this in your program...
    Coming to your question,
    when you override a method in subclass then, subclass method can have the erasure of super class method's signature. but reverse not true, it is not either overloading or overriding, instead it is a name clash!
     
    Seetharaman Venkatasamy
    Ranch Hand
    Posts: 5575
    Eclipse IDE Java Windows XP
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    quoted from angelikalanger-GenericsFAQ

    This kind of overriding is permitted in order to allow that legacy supertypes can be re-engineered and generified without affecting any existing subtypes of the legacy supertype. Imagine the supertype had originally not used any generics. In that original situation, the signatures of supertype and subtype method had been identical. After generification of the supertype the signatures are different. Without the rule that the subtype method can be the erasure of the supertype method all subtypes would also need to be re-engineered and generified. Fortunately, the additional rule renders this re-engineering effort unnecessary and the generification of the supertype does not affect overriding methods in subtypes.
     
    Suhrid Karthik
    Ranch Hand
    Posts: 58
    Eclipse IDE Java Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Ogeh Ikem wrote:
    In order for foo(Collection<?>) of type Sub to override foo(Collection) of type Super, it must have
  • the same signature as the signature of foo(Collection)(it doesn't), or
  • the same signature as the erasure of the signature of foo(Collection) (it doesn't...erasure of the superclass method doesn't even take place here)

  • This is why a generic method cannot override a non-generic method.


    This makes it clear to me now. Thanks a lot Ogeh.
     
    Suhrid Karthik
    Ranch Hand
    Posts: 58
    Eclipse IDE Java Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Seetharaman, good points. Thank you.
     
    Seetharaman Venkatasamy
    Ranch Hand
    Posts: 5575
    Eclipse IDE Java Windows XP
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Suhrid Karthik wrote:Seetharaman, good points. Thank you.

    you are welcome
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!