Win a copy of Node.js Design Patterns: Design and implement production-grade Node.js applications using proven patterns and techniques this week in the Server-Side JavaScript and NodeJS forum!
  • 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
  • Ron McLeod
  • Rob Spoor
  • Tim Cooke
  • Junilu Lacar
Sheriffs:
  • Henry Wong
  • Liutauras Vilda
  • Jeanne Boyarsky
Saloon Keepers:
  • Jesse Silverman
  • Tim Holloway
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
Bartenders:
  • Al Hobbs
  • Mikalai Zaikin
  • Piet Souris

Problem in Generic Override

 
Ranch Hand
Posts: 125
Scala Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This code gives compile time error:

C:\com\source\test>javac sub.java
sub.java:6: error: name clash: foo(Collection<?>) in sub and foo(Collection) in
Super have the same erasure, yet neither overrides the other
public void foo(Collection<?> c){}



But this doesn't:

Can anyone explain why?
 
Rancher
Posts: 1090
14
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think the reason is this.

According to JLS,

JLS wrote:It is a compile-time error if a type declaration T has a member method m1 and there exists a method m2 declared in T or a supertype of T such that all of the following conditions hold:

m1 and m2 have the same name.

m2 is accessible from T.

The signature of m1 is not a subsignature (ยง8.4.2) of the signature of m2.

The signature of m1 or some method m1 overrides (directly or indirectly) has the same erasure as the signature of m2 or some method m2 overrides (directly or indirectly).

These restrictions are necessary because generics are implemented via erasure. The rule above implies that methods declared in the same class with the same name must have different erasures. It also implies that a type declaration cannot implement or extend two distinct invocations of the same generic interface.



In the first case, all the four conditions are satisfied. Hence it is a compile time error. But in the second case, the subsignature rule is not satisfied. Hence it is allowed.

Specifically


is not a subsignature of



but



is a subsignature of



Note that according to JLS,

The notion of subsignature is designed 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. This is important so that library designers may freely generify methods independently of clients that define subclasses or subinterfaces of the library.



Nice question. Helped me learn new things..
 
Sidharth Khattri
Ranch Hand
Posts: 125
Scala Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This means to answer such a question, one should be aware of the implementation details/or signatures? So we won't encounter such a question on the exam?
 
Chan Ag
Rancher
Posts: 1090
14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sidharth Khattri wrote:This means to answer such a question, one should be aware of the implementation details/or signatures?



I'm not really sure how implementation detail is coming into picture here. Those are just four rules that the JLS specifies ( although I agree that generics' rules are confusing and it is only today I found about these four rules ) and we aren't talking about any implementation detail here. If by implementation detail you mean how the erasure is made to work and how such rules are implemented in the compiler code, that is. Signatures, of course, are important. For one thing, it's method overriding we are talking about. So of course, the signature IS important. Or did you mean something else?

Sidharth Khattri wrote:So we won't encounter such a question on the exam?


No idea. Anybody else?

Having said that, I know my answer only explains that JLS specifies this behavior. It does not address the why part. I have my own logic of why the specification has those four rules but they are just speculations - something that may help me remember those four rules. Speculations are just guesses, so they can be wrong and hence I'll keep them to myself. :-)
 
Sidharth Khattri
Ranch Hand
Posts: 125
Scala Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Chan Ag wrote:

Sidharth Khattri wrote:This means to answer such a question, one should be aware of the implementation details/or signatures?



I'm not really sure how implementation detail is coming into picture here. Those are just four rules that the JLS specifies ( although I agree that generics' rules are confusing and it is only today I found about these four rules ) and we aren't talking about any implementation detail here. If by implementation detail you mean how the erasure is made to work and how such rules are implemented in the compiler code, that is. Signatures, of course, are important. For one thing, it's method overriding we are talking about. So of course, the signature IS important. Or did you mean something else?

Sidharth Khattri wrote:So we won't encounter such a question on the exam?


No idea. Anybody else?

Having said that, I know my answer only explains that JLS specifies this behavior. It does not address the why part. I have my own logic of why the specification has those four rules but they are just speculations - something that may help me remember those four rules. Speculations are just guesses, so they can be wrong and hence I'll keep them to myself. :-)



Thanks, I got confused as for why, hence I went into the implementation details part. I crammed the rules though some explanation would be great
 
Chan Ag
Rancher
Posts: 1090
14
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sidharth Khattri wrote:
Thanks, I got confused as for why, hence I went into the implementation details part. I crammed the rules though some explanation would be great



Actually I spent some more time reading the specifications and I went through the examples stated in section 8.4.2. There is clearly no need to guess the reason for the stated behaviour cause the JLS is quite explicit in stating the reason.

This is clearly for backward compatibility. Imagine if somebody using pre generic code created a subclass that provided an overridden version of the foo method, you wouldn't want their code to break after they made the super class method a generic method. The JLS also has a fine example that illustrates this. Refer to this.

Specifically this is the part I'm referring to.

JLS wrote:The notion of subsignature is designed 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. This is important so that library designers may freely generify methods independently of clients that define subclasses or subinterfaces of the library.

Consider the example:



Now, assume this code was written before the introduction of generics, and now the author of class CollectionConverter decides to generify the code, thus:



Without special dispensation, Overrider.toList would no longer override CollectionConverter.toList. Instead, the code would be illegal. This would significantly inhibit the use of generics, since library writers would hesitate to migrate existing code.



Hope this helps. By the way, I loved this question, and the reading I did to answer it. Good one.

Chan.
 
Sidharth Khattri
Ranch Hand
Posts: 125
Scala Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Chan Ag wrote:

Sidharth Khattri wrote:
Thanks, I got confused as for why, hence I went into the implementation details part. I crammed the rules though some explanation would be great



Actually I spent some more time reading the specifications and I went through the examples stated in section 8.4.2. There is clearly no need to guess the reason for the stated behaviour cause the JLS is quite explicit in stating the reason.

This is clearly for backward compatibility. Imagine if somebody using pre generic code created a subclass that provided an overridden version of the foo method, you wouldn't want their code to break after they made the super class method a generic method. The JLS also has a fine example that illustrates this. Refer to this.

Specifically this is the part I'm referring to.

JLS wrote:The notion of subsignature is designed 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. This is important so that library designers may freely generify methods independently of clients that define subclasses or subinterfaces of the library.

Consider the example:



Now, assume this code was written before the introduction of generics, and now the author of class CollectionConverter decides to generify the code, thus:



Without special dispensation, Overrider.toList would no longer override CollectionConverter.toList. Instead, the code would be illegal. This would significantly inhibit the use of generics, since library writers would hesitate to migrate existing code.



Hope this helps. By the way, I loved this question, and the reading I did to answer it. Good one.

Chan.



Thanks for the perfect explanation Chan :-)
 
Ranch Hand
Posts: 34
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In second example in 8.4.2. Method Signature (http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.2).
It is written

Without special dispensation, Overrider.toList would no longer override CollectionConverter.toList. Instead, the code would be illegal. This would significantly inhibit the use of generics, since library writers would hesitate to migrate existing code.



I coded the example, but it compiles well and I have just got two warning.

 
reply
    Bookmark Topic Watch Topic
  • New Topic