United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-5044646 package-private indirect noninherited generic overriders
JDK-5044646 : package-private indirect noninherited generic overriders

Details
Type:
Bug
Submit Date:
2004-05-10
Status:
Closed
Updated Date:
2010-07-09
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
tools
OS:
solaris_8
Sub-Component:
javac
CPU:
generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
5.0
Fixed Versions:

Related Reports

Sub Tasks

Description
Is the compiler right or wrong here?


==========$ cat -n A1.java
     1    package p1;
     2   
     3    public class A1<T> {
     4        int f(T t) { return 0; }
     5    }
==========$ cat -n A2.java
     1    package p2;
     2   
     3    public class A2<T> extends p1.A1<T> {}
==========$ cat -n B.java
     1    package p1;
     2   
     3    public abstract class B<T,U> extends p2.A2<U> {
     4        abstract int f(T t);
     5        // abstract I2 f(String s);
     6    }
==========$ cat -n C.java
     1    package p1;
     2   
     3    public class C extends B<String,String> {
     4        // indirect overrider f(String) from A1
     5    }
==========$ newjavac *.java
C.java:3: p1.C is not abstract and does not override abstract method f(java.lang.String) in p1.B
public class C extends B<String,String> {
       ^
1 error
==========$ 

                                    

Comments
EVALUATION

Nice example. Packages, overriding, overloading, erasure, abstractness - a dream
come true. I think that B is illegal because there are two methods the same
name. different signatures, the same erasure declared in B's hierachy (and
the one in the supertype is accessible to B, since they are in the same 
package).
 
###@###.### 2004-07-09

javac does not give an error on B, therefore this is a compiler bug.

###@###.### 2004-07-09
                                     
2004-07-09
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
dragon
mustang


                                     
2004-09-08
EVALUATION

int f(T t) in p1.A1 is package-private, so is not inherited by p2.A2. (JLS 8.4.8)

Therefore, p1.B doesn't inherit any methods, because its direct superclass p2.A2 doesn't have any. abstract int f(X t) in p1.B (I've renamed B's formal type parameter T to X) doesn't override anything.

p1.C is in the same package as p1.B, so p1.C inherits abstract int f(String t). Since p1.C is not abstract, a compile-time error should occur. As indeed it does.

I presume Gilad missed the accessibility rule that causes p1.A1::f not to be inherited in p2.A2.

Note that **EVEN IF** p2.A2 did inherit int f(T t), it is not the case that abstract int f(X t) in p1.B overrides it. Overriding requires (8.4.8.1 clause (3)) that the overridden member p2.A2::int f(T t) is declared with default access in the same package as p1.B. Not true. Accessibility strikes again.

(For completeness, given m1 = int f(T t), and m2 = abstract int f(X t), where T and X are type variables, m1 has the same signature as m2 according to 8.4.2. Therefore m1 is a subsignature of m2, and m1 and m2 are override-equivalent. Not that this matters here.)
                                     
2006-10-26
EVALUATION

In order to prevent such confusion again, I'll integrate a regression
test which asserts the behavior above.

I'll also request a JCK-compiler test is developed.
                                     
2006-10-26
SUGGESTED FIX

Add regression tests.  Webrev of changes: http://sa.sfbay/projects/langtools/bugid_summary.pl?bugid=5044646
                                     
2006-10-26



Hardware and Software, Engineered to Work Together