2012-09-26 23 views
5

Eclipse 3.4. Java compilador nivel 1.6 JRE IBM 1.6Referencia de constructora ambigua en javac pero no en Eclipse

Tenemos una clase de biblioteca que no podemos cambiar que es de la forma.

import java.util.Hashtable; 
public class A extends Hashtable { 
    ... 
} 

Y hemos construido una clase de utilidad para facilitar el acceso a A.

public class B { 
    private A a; 
    public B() { 
    this.a = new A(); 
    } 
    public B(final A props) { 
    this.a = props; 
    } 
    public B(final Map<String, String> props) { 
    this(); 
    for (String key : props.keySet()) { 
     add(key, props.get(key)); 
    } 
    } 
    @SuppressWarnings("unchecked") 
    public B add(final String name, final Object value) { 
    a.put(name, value); 
    return this; 
    } 
} 

El problema se produce cuando tratamos de llamar a uno de los constructores de otra clase.

public class C { 

    public void stuff() { 
    A a = new A(); 
    B b = new B(a);//Error in javac 
    } 
} 

Eclipse compila esto sin errores, y cuando se compila a través javac hormiga y Jenkins el compilador da un error como el siguiente.

reference to B is ambiguous, both method B(com.foo.A) in com.bar.B and method B(java.util.Map<java.lang.String,java.lang.String>) in com.bar.B match 
    [javac]   B b = new B(a); 

¿Debería ocurrir este error en javac? En mi opinión, eclipse es correcto al seleccionar el método más específico.

+1

¿Estás seguro de que estás utilizando el mismo JDK dentro de Eclipse que para Java? – dbalakirev

+3

A extiende 'HashTable'. ¿Debería ser 'Hashtable'? –

+0

@David correcto -> editado –

Respuesta

0

Dado que HashTable implementa Mapa, existe ambigüedad. HThis respuesta contiene algunas ideas Goot:

Calling ambiguously overloaded constructor in Java

+0

Pero Hashtable es más específico que Map, por lo que debe seleccionarse sin ninguna restricción. JLS -> http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#308804 Esto debe ser un problema relacionado con los genéricos declarados en el mapa –

-1

como Clase A se extiende tabla hash y sí Hashtable implementa la interfaz del mapa, por lo que se puede decir de clase A obtiene propiedades del mapa y también se convierte en Mapa.

Cuando usted está teniendo public B(final A props) y public B(final Map<String, String> props) Es como si tuviera un mapa argumento tanto en los constructores.

Es por eso que le da ambigüedad.

+0

-1 No lo hago piensa que tu explicación es correcta Es perfectamente válido tener métodos sobrecargados con parámetros que son subtipos entre sí. Como dije en la pregunta, Eclipse puede compilar esto sin ningún problema. El compilador elegirá el método más específico basado en el tipo declarado del parámetro en tiempo de ejecución. Como Hashtable es más específico que Map, se debe seleccionar sin abcuridad. JLS -> documentos.oracle.com/javase/specs/jls/se5.0/html/... Esto debe ser un problema relacionado con los genéricos declarados en el mapa –

0

El problema es que un constructor acepta una Hashtable sin procesar, mientras que el otro acepta un Mapa parametrizado. Ambos constructores son aplicables, sin embargo, la lógica de desambiguación no funciona en este caso, ya que, por Java Language Specification, un constructor sería más específico que el otro solo si su argumento fuera un subtipo (estricto) del otro argumento. El subtipado sin marcar no está permitido durante esta etapa, de ahí la ambigüedad.

Cuestiones relacionadas