2010-10-05 11 views
8

Wo ich versuche, zwei statische Überladungsmethoden zu erstellen, habe ich einen Kompilierungsfehler. Kann das jemand erklärenStatische Methode überladen mit Generics

public class A { 
public static void a(Set<String> stringSet) {} 
public static void a(Set<Map<String,String>> mapSet) {} 
} 
+0

Was ist der Fehler? – kasten

Antwort

14

Der Grund ist type erasure. Generics werden nicht in den Klassen gespeichert, sie sind nur Informationen zur Kompilierung, daher sind die beiden Methoden zur Laufzeit identisch und daher gibt es einen Namenskonflikt.

Referenz

Diese drei Methoden tatsächlich identisch sind (sprich: sie produzieren identisch Bytecode):

public static void a(Set plainSet) {} 
public static void a(Set<String> stringSet) {} 
public static void a(Set<Map<String,String>> mapSet) {} 

Wenn Sie wirklich zwei separate Methoden haben möchten, müssen Sie verschiedene Methodensignaturen (z. verschiedene Methodennamen, ein zusätzlicher Parameter für eine der Methoden etc.)

+0

Die Methodenauflösung erfolgt zur Kompilierzeit, sodass die Java-Sprache erweitert werden könnte, um diese Art von Überladung ohne Verdinglichung zu ermöglichen. Es ist jedoch wahrscheinlich einfacher, auf einer besseren Methodenbenennung zu bestehen. –

+0

Ja, aber das Ziel war, das Binärformat nicht zu unterbrechen (Legacy-Code musste weiter funktionieren, sogar mit neuem Code) –

1

Aus der Sicht der Methoden sind die Parameter Set<String> und Set<Map<String,String>> gleich, weil alle Instanzen einer generischen Klasse dieselbe Laufzeitklasse haben (In Ihrem Fall), unabhängig von ihren tatsächlichen Typparametern. Daher erhalten Sie eine erasure error. zur Laufzeit auch schauen beide werden wie ... public static void a(Set stringSet) {} UND public static void a(Set mapSet) {}

0

Sie den Compiler-Fehler bekommen, weil die Methoden nicht richtig überlastet sind. Beide Methoden haben einen Parameter vom Set-Typ, der beide Methoden für den Compiler identisch macht.