2015-06-19 5 views
6

Ich habe eine statische Funktion mit der folgenden Signatur für eine generische Art Teinen generischen Typs von einem generischen Typ in Java (kompilieren Zeitfehler) Herleitung

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

, das eine Liste des Kartenschlüssels mit einer Eigenschaft zurückgeben sollte .

Jetzt möchte ich eine generische HashMap vom Typ S

Map<S,Double> map 

in Aufruf innerhalb einer generischen Klasse die statische Funktion zu übergeben, die die Karte als Mitglied Variable hat.

Ich habe ein minimales Codebeispiel unten aufgelistet.

Allerdings bekomme ich eine Fehlermeldung (S und T sind sowohl T die aber in verschiedenen Bereichen meines Codes, das heißt 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>) 

Wie dieses Problem beheben können? Ich bin überrascht, dass Java nicht erlaubt, einen generischen Typ von einem generischen Typ abzuleiten. Welche Struktur in Java kann man verwenden, um mit dieser Art von abstrakterer Code-Argumentation zu arbeiten?

-Code:

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

zeigen Bitte den Klassencode das Publikum. –

+0

'' static'' Methoden können nicht auf Membervariablen zugreifen; und welche Version von Java verwendest du? –

+0

Ich denke, dass Sie mehr Code hinzufügen müssen, um das Problem zu verstehen. –

Antwort

7

Es ist nicht das Problem mit den T und S, aber mit den Comparable und Double.

Der Grund für den Fehler ist, dass ein Map<T, Double> is not a Map<T, Comparable>.

Sie müssen den Umfang des zweiten Typparameters etwas erweitern. Etwas wie:

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

Dann werden Sie in der Lage sein, die Methode aufzurufen mit:

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

dies heißt [Varianz] (https://msdn.microsoft.com/en-US/library/ee207183.aspx) –

+0

Vielen Dank! Ich wurde durch die Compiler-Nachricht, die sich auf die generischen Typen konzentrierte, in die Irre geführt. Außerdem dachte ich, der Compiler würde verstehen, dass "Double" "Comparable" ist und dass Interfaces anders gehandhabt werden als die Klassenvererbung für Generics. Ich denke immer noch, dass die Java-Logik, das Schlüsselwort 'extends' in generics zu verwenden, um zu beschreiben, dass ich einen Typ' S' erwarte, der * implementiert * und die Schnittstelle ist ein wenig aus. Vermisse ich hier etwas? Macht es Sinn, * mit Generika zu erweitern und zu verbinden? – madison54

+0

Ja, 'extends' in Generics wird für Klassen und Schnittstellen verwendet. –

Verwandte Themen