Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 5044646
Votes 0
Synopsis package-private indirect noninherited generic overriders
Category java:compiler
Reported Against tiger-beta2
Release Fixed 7(b03)
State 10-Fix Delivered, bug
Priority: 4-Low
Related Bugs 6486939 , 6552040
Submit Date 10-MAY-2004
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
==========$ 
Work Around
N/A
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).
 
  xxxxx@xxxxx   2004-07-09

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

  xxxxx@xxxxx   2004-07-09
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.)
Posted Date : 2006-10-26 15:37:59.0

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.
Posted Date : 2006-10-26 16:39:29.0
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang