[TYPES] Java generics unsoundness?

Erik Ernst eernst at daimi.au.dk
Sun Oct 1 17:08:09 EDT 2006


Dear Eijiro Sumii and all others,

not pretending to be the world authority on this issue, the following 
does seem to apply:

  - JLS mentions type erasure (4.6) so this would be part of the 
language, but it is not an inherent property of type erasure that 
these method name clashes arise.

  - JLS does not mention bridge methods as far as I know, so 
presumably it should be possible to implement them in a different way 
without violating the language def.  To avoid the method clash we 
could use name mangling, i.e., including the types of the type-erased 
arguments in the name of the method (as well as $ or similar, to 
avoid clashes with user-defined names).  Call sites would be compiled 
in a context where the argument types are known, so they could easily 
use the correct (mangled) name.

All in all, this seems to be a bug in the implementation.

Of course it is not that easy in practice, e.g., because 
existing .class files would then break en masse...

On Sunday 01 October 2006 03:18, Eijiro Sumii wrote:
> [..]
> 
> Dear all,
> 
> Hiromasa Kido, an undergraduate student in the University of Tokyo,
> has found the problem below in the implementation of generics in 
> Java. [..]
>----------------------------------------------------------------------
> [..]
> C:\WINDOWS\Temp>type B.java
> class A{
>        public int compareTo(Object o){
>                return 0;
>        }
> }
> 
> class B extends A implements Comparable<B>{
>        public int compareTo(B b){
>                return 0;
>        }
> 
>        public static void main(String[] argv){
>                System.out.println(new B().compareTo(new Object()));
>        }
> }
> [..]
>----------------------------------------------------------------------
> 
> Here is my understanding (confirmed by Atsushi Igarashi) of the
> problem: after erasure (i.e., replacing every type variable with the
> Object class), an auxiliary method (called bridged method) like
> 
>   public int compareTo(Object x){
>     return compareTo((B)x);
>   }
> 
> is created by the compiler in class B.  However, this additional
> method happens to override A.compareTo and raises an unexpected
> ClassCastException.
> 
> We have already submitted a bug report to Sun.  My question is: Is
> this a bug in the compiler, or in the design of the language?  On 
> one 
> hand, it is a compiler bug because the bridge method, inserted by 
> the 
> compiler, is doing the harm.  On the other hand, it would be hard 
> for 
> any compilers to implement generic interfaces without bridge methods
> (unless we modify the present JVM).  In my understading, such
> overriding as above is not forbidden in the current language
> specification (page 227 and page 478 perhaps).
> 
> Does any expert in this list have a word on this matter...?
> 
> Thanks in advance,
> 
> Eijiro Sumii
> http://www.kb.ecei.tohoku.ac.jp/~sumii/
> 

  best regards,

-- 
Erik Ernst                        eernst at daimi.au.dk
Department of Computer Science, University of Aarhus
IT-parken,  Aabogade 34,  DK-8200 Aarhus N,  Denmark


More information about the Types-list mailing list