2015-06-19 18 views
6

Mam statyczną funkcję z następującym podpisem dla typu rodzajowego TWnioskując typ rodzajowy od typu rodzajowego w Java (błąd kompilacji czas)

public static<T> List<T> sortMap(Map<T, Comparable> map) 

które powinny powrócić listę kluczy mapa z niektórych nieruchomości .

Teraz chcę przekazać rodzajowe HashMap typu S

Map<S,Double> map 

w wywołaniu funkcji statycznej w ogólnej klasy, który ma mapę jako zmiennej składowej.

Podałem poniżej przykład kodu minimalnego.

Jednak pojawia się komunikat o błędzie (S i T są zarówno T, ale w różnych zakresach mojego kodu, tj T#1 = T, T#2 = S):

required: Map<T#1,Comparable> 
    found: Map<T#2,Double> 
    reason: cannot infer type-variable(s) T#1 
    (argument mismatch; Map<T#2,Double> cannot be converted to Map<T#1,Comparable>) 

Jak można rozwiązać ten problem? Jestem zaskoczony, że Java nie zezwala na wnioskowanie typu ogólnego od typu ogólnego. Jakiej struktury w Javie można użyć do pracy z tego rodzaju bardziej abstrakcyjnym rozumowaniem kodu?

Kod:

public class ExampleClass<T> { 
    Map<T, Double> map; 
    public ExampleClass() { 
     this.map = new HashMap(); 
    } 
    //the following line produces the mentioned error 
    List<T> sortedMapKeys = UtilityMethods.sortMap(map); 
} 

public class UtilityMethods { 
    public static<T> List<T> sortMap(Map<T, Comparable> map) { 
     // sort the map in some way and return the list 
    } 
} 
+0

Proszę pokazać kod klasa publiczność. –

+0

Metody 'statyczne' nie mogą uzyskać dostępu do zmiennych członkowskich; i jakiej wersji java używasz? –

+0

Myślę, że będziesz musiał dodać trochę więcej kodu, aby zrozumieć problem. –

Odpowiedz

7

To nie jest problem z T i S, ale z Comparable i Double.

Powodem błędu jest to, że Map<T, Double> is not a Map<T, Comparable>.

Będziesz musiał nieco rozszerzyć zakres drugiego parametru typu. Coś jak:

public static <T, S extends Comparable<S>> List<T> function(Map<T, S> map) { 
    //implementation 
} 

Wtedy będziesz w stanie wywołać metodę z:

Map<S, Double> map = new HashMap<S, Double>(); 
function(map); 
+0

to się nazywa [wariancja] (https://msdn.microsoft.com/en-US/library/ee207183.aspx) –

+0

Dzięki! Zostałem wprowadzony w błąd przez komunikat kompilatora skupiający się na typach ogólnych. Ponadto, myślałem, że kompilator zrozumie, że 'Double' jest' porównywalny' i że interfejsy będą obsługiwane inaczej niż dziedziczenie klasowe dla generycznych. Nadal uważam, że logika Java używania słowa kluczowego "extends" w generycznych dla opisania, że ​​oczekuję typu 'S'that * implementuje * i interfejsu jest trochę wyłączona. Czy tęsknię za czymś tutaj? Czy ma sens * rozszerzanie i interfejs * z rodzajami? – madison54

+0

Tak, 'extends' w Generics jest używany dla obu klas i interfejsów. –

Powiązane problemy