2012-09-26 16 views
5

Eclipse 3.4. Java kompilator poziom 1.6 JRE IBM 1.6Niejednoznaczne odwołanie do Konstruktora w javac, ale nie w Eclipse

Mamy klasę biblioteki, której nie możemy zmienić, która jest z formularza.

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

I mamy zbudować klasę użytkową, aby zapewnić łatwy dostęp do 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; 
    } 
} 

Problem pojawia się, gdy staramy się zadzwonić pod jeden z konstruktorów z innej klasy.

public class C { 

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

Eclipse to kompiluje bez błędów, a kiedy jest kompilowany przez ant javac i Jenkins kompilator daje błąd jak poniżej.

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); 

Czy ten błąd występuje w javac? Moim zdaniem zaćmienie jest prawidłowe przy wyborze bardziej szczegółowej metody.

+1

Czy na pewno używasz tego samego JDK w środowisku Eclipse, co w przypadku java? – dbalakirev

+3

A rozszerza 'HashTable'. Czy powinno to być "Hashtable"? –

+0

@David correct -> edit –

Odpowiedz

0

Ponieważ HashTable implementuje mapę, istnieje niejasność. HThis odpowiedź zawiera pewne spostrzeżenia Goot:

Calling ambiguously overloaded constructor in Java

+0

Ale Hashtable jest bardziej specyficzna niż mapa, więc powinna być wybrana bez niejasności. JLS -> http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#308804 To musi być problem związany z generycznymi zgłoszonymi na mapie –

-1

Jako klasa A i sam rozciąga Hashtable Hashtable implementuje interfejs mapę, więc można powiedzieć, klasa A dostaje właściwości mapą i staje się również mapa.

Kiedy masz public B(final A props) i public B(final Map<String, String> props) To jak masz się mapa argumentu w obu konstruktorów.

Dlatego daje dwuznaczność.

+0

-1 Nie Myślę, że wyjaśnianie jest poprawne. Jest całkowicie prawidłowe, aby przeciążać metody parametrami, które są podtypami nawzajem. Jak już wspomniałem w pytaniu, Eclipse jest w stanie skompilować to bez problemu. Kompilator wybierze bardziej szczegółową metodę na podstawie zadeklarowanego typu parametru w środowisku wykonawczym. Ponieważ Hashtable jest bardziej specyficzna niż mapa, powinna być wybrana bez niejasności. JLS -> docs.oracle.com/javase/specs/jls/se5.0/html/... To musi być problem dotyczący generycznych deklarowanych na mapie –

0

Problem polega na tym, że jeden konstruktor akceptuje surową Hashtable, a drugi akceptuje sparametryzowaną mapę. Oba konstruktory mają zastosowanie, jednak logika ujednoznacznia nie działa w tym przypadku, ponieważ, na Java Language Specification - konstruktor byłby bardziej szczegółowy niż drugi, gdyby jego argument był (ścisłym) podtypem innego argumentu. Niezaznaczone podtypy nie są dozwolone na tym etapie, stąd dwuznaczność.

Powiązane problemy