JDK-6245717 : Compiler complains about ambiguity
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 5.0,6
  • Priority: P5
  • Status: Resolved
  • Resolution: Won't Fix
  • OS: generic
  • CPU: generic
  • Submitted: 2005-03-24
  • Updated: 2021-05-25
  • Resolved: 2021-05-25
Related Reports
Duplicate :  
Relates :  
Description
From: 	###@###.###
Date: 	Thu, 24 Mar 2005 19:21:27 +0100

public class AttributeList extends ArrayList {
     public AttributeList(AttributeList al) {...}
     public AttributeList(List<Attribute> l) {...}
}

For some surprising compatibility reasons, AttributeList can't extend 
ArrayList<Attribute>, even though that is what it really is.  It just 
extends raw ArrayList.

What we're seeing is that the following code:

AttributeList al =
     new AttributeList(new AttributeList());

gives the following error:

AL.java:6: reference to AttributeList is ambiguous, both method 
AttributeList(javax.management.AttributeList) in 
javax.management.AttributeList and method 
AttributeList(java.util.List<javax.management.Attribute>) in 
javax.management.AttributeList match
         AttributeList al = new AttributeList(new AttributeList());
                            ^


###@###.### 2005-03-24 20:00:46 GMT

Comments
EVALUATION "But we have that AttributeList <: List which could be converted (by unchecked conversion) to List<String>. In other words if we exploited the same rules described for assignment conversion the method would be applicable - could that be what JLS really meant or is just a javac bug?" The split between "applicable by subtyping" and "applicable by method invocation conversion" is to ensure that a method chosen by overload resolution pre-5.0 is still chosen by overload resolution in 5.0+. Pre-5.0, the ctors would/could have been AttributeList(AttributeList) and AttributeList(List). Both would have been applicable to a ctor invocation which passed 'new AttributeList()'. The former would have been chosen as more specific. Now the latter has been generified, but it is not desirable to suddenly choose it. So the JLS did mean for "applicable by subtyping" to have only the former be applicable in the first instance. (Via subtyping and unchecked conversion only.) It would miss the point to make the latter applicable here via assignment/method invocation conversion.
23-11-2010

EVALUATION Actually I spoke to fast: JLS literally say: "Ai is convertible to some type Ci by unchecked conversion (��5.1.9), and Ci <: Si" Which is not the case, since AttributeList is not convertible to any generic type X such that X <: List<Attribute>. But we have that AttributeList <: List which could be converted (by unchecked conversion) to List<String>. In other words if we exploited the same rules described for assignment conversion the method would be applicable - could that be what JLS really meant or is just a javac bug?
13-03-2009

EVALUATION This is not a bug. JLS3 15.12.2.2 say that: "The method m is applicable by subtyping if and only if both of the following conditions hold: * For 1in, either: o Ai is a subtype (��4.10) of Si (Ai <: Si) or o Ai is convertible to some type Ci by unchecked conversion (��5.1.9), and Ci <: Si. * If m is a generic method as described above then Ul <: Bl[R1 = U1, ..., Rp = Up], 1lp." Here we have that both constructors are applicable: 1) public AttributeList(AttributeList al) {...} (w/o unchecked conversion) 2) public AttributeList(List<Attribute> l) {...} (w/ unchecked conversion from List -> List<Attribute>) It follows that the most specific method algorithm should be applied between (1) and (2). However since neither AttributeList <: List<Attribute> nor List<Attribute> <: AttributeList (here we cannot use unchecked conversion - straight subtyping is exploited) it follows that neither method is more specific. Hence javac is right.
13-03-2009

WORK AROUND Don't mix generic and raw types. In particular, make sure that you parameterize ArrayList in the superclass declaration: public class AttributeList extends ArrayList<Attribute> { } Or perhaps: public class AttributeList extends ArrayList<Object> { } The latter could be required for compatibility, but that really depends on your specification and what developers can/should be expected to work. ###@###.### 2005-03-24 20:00:47 GMT
24-03-2005