JDK-6946211 : Multiple generic types cause weaker access privileges error on clone()
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6u20,6u29,7
  • Priority: P3
  • Status: Closed
  • Resolution: Not an Issue
  • OS: generic,windows_xp,windows_7
  • CPU: generic,x86
  • Submitted: 2010-04-22
  • Updated: 2011-12-12
  • Resolved: 2010-07-29
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Client VM (build 16.3-b01, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7600]

A DESCRIPTION OF THE PROBLEM :
The compiler fails if a base interface includes a clone() method and an extended interface has multiple generic types. The error message is the same as Bug ID:  4185308 but the cause is different.
(Note that the sample code compiles correctly in the Eclipse Java compiler.)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Put the source code for an executable test case into two separate files in the same directory. Compile them. You should get a compiler error.


ERROR MESSAGES/STACK TRACES THAT OCCUR :
SubType.java:1: clone() in java.lang.Object cannot implement clone() in BaseType; attempting to assign weaker access privileges; was public
public interface SubType<T extends BaseType & java.io.Closeable> extends BaseType {
                         ^
1 error


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public interface BaseType {
    BaseType clone() throws CloneNotSupportedException;
}

public interface SubType<T extends BaseType & java.io.Closeable> extends BaseType {
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Modify SubType so that the generic type parameter T extends only BaseType, not Closeable.

Comments
EVALUATION The "problem" is caused by the fact that the intersection type 'T extends BaseType' (really, 'T extends BaseType & java.io.Closeable', but Closeable is not important here) is defined to have the same members as this synthetic class: class Synthetic implements BaseType {} Unfortunately, this class declaration happens to be ill-formed, as Synthetic inherits the protected Object.clone() that cannot override the public method BaseType.clone(). The declaration is analogous to the following real and illegal class: abstract class NonSynthetic implements BaseType {} So the compiler is merely acting in accordance with JLS3. It's true that rejecting the program is a bit harsh, given that one might declare the following class: class NonSynthetic implements BaseType { public BaseType clone() {..} } which is well-formed and is obviously a valid witness for the type-variable. Nevertheless, it would require a change to the intersection type rules (see 6644562) to change the compiler's behavior.
12-05-2010