JDK-5009937 : hiding versus generics versus binary compatibility
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 5.0
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris_8
  • CPU: generic
  • Submitted: 2004-03-09
  • Updated: 2010-03-02
  • Resolved: 2011-05-17
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
7 b27Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
The following illustrates that the binary compatibility rules conflict
with generics.  The method resolved at compile time and at runtime are
different, resulting in a runtime call to the wrong method.

Date: Wed, 25 Feb 2004 14:15:59 -0800
From: <###@###.###>
Subject: Method isn't hidden, but acts like it is at runtime
To: ###@###.###
Cc: ###@###.###

import java.util.*;

import static java.lang.System.out;

public class T2 {

    public static void main(String[] args) {
        Collection c = T2a.m(new ArrayList<String>());  // => "T2a.m"

    static Collection m(List<String> p) {
        return null;

class T2a extends T2 {

    static Collection m(List<Number> p) {
        return null;

SUGGESTED FIX see http://sa.sfbay.sun.com/projects/langtools_data/7/5009937/

SUGGESTED FIX I also fixed a defect in checkCompatibleConcreters. The new implementation fixes a bug that I discovered involving classes inheriting two methods with the same signature, as javac was able to detect the error in this situation: class A<X> { void m(X x) {} void m(Integer i) {} } class C extends A<Integer> {} But NOT in this slightly trickier one: class A<X> { void m(X x) {} } class B<T> extends A<T> { void m(Integer i) {} } class C extends B<Integer> {} since the two clashing methods come from different classes and there was a bug in the way in which javac walked the inheritance tree.

SUGGESTED FIX the code is below

EVALUATION As previous evaluations have suggested, this bug is due to the fact that the subclass T2a is inheriting the static member T2.m() whose signature conflicts with its static member T2a.m() (argument types are different). JLS state that: "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. * m1 or some method m1 overrides (directly or indirectly) has the same erasure as m2 or some method m2 overrides (directly or indirectly). " The last condition is the one that matters here. That condition ensures that type erasure can never generate two methods with the same signature in the same class (which would be inconsistent). A good point where to insert this check is in Check.checkOverride. However special care is required since we must be sure to not generate inappropriate errors (e.g. we must skip constructors, non inherited members, etc.). This new implementation of checkOverrides has the advantage of detecting errors earlier. In fact, in a scenario in which two non-static, non overriding methods are inherited by a given class, javac used to be able to report the error only after having applied type-erasure on method symbols and generated bridges for generic inherited methods (which is the last step of the compiler pipeline before code generation). With this new implementation javac is able to detect the error while attributing the class (and this is the correct behaviour since the class is not well-formed wrt to the JLS

CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: dragon mustang

EVALUATION Two methods in same hierarchy, accessible, same name and erasure but different signature. This is a compile time error (at the definition of T2a). ###@###.### 2004-07-09 This is therefore a compiler bug. ###@###.### 2004-07-09