2017-08-17 1 views
3

Ich habe die folgenden Methoden in einer Klasse:Java Überlastung mit generischen Typparametern

void delete(ClassA a) { 
    //.... 
} 

void delete(ClassB b) { 
    //... 
} 

void delete(List<ClassA> list) { 
    for (ClassA a: list) { 
    delete(a); 
    } 
} 

void delete(List<ClassB> list) { 
    for (ClassB b: list){ 
    delete(b); 
    } 
} 

Die Überlastung für die ersten beiden Methoden gut funktioniert. Aber es gibt einen Konflikt zwischen der dritten und der vierten Methode.

Ist es möglich, sie durch eine Methode zu ersetzen? Ich habe versucht, die folgende Methode, die nicht korrekt ist:

void delete(List<? extends Object> list){ 
    for (Object o: list){ 
    delete((o.getClass())o); 
    } 
} 

Wie kann ich den Klassentyp der Instanz in der Liste zur Laufzeit und rufen Sie die entsprechende Methode erkennen?

+0

Verwenden Sie 'instanceof', um das Objekt zu überprüfen – soorapadman

Antwort

3

Das Überladen wird zur Kompilierungszeit aufgelöst, sodass Sie sich nicht auf die Laufzeittypen verlassen können.

Was können Sie tun, ist die Laufzeittypen mit instanceof und Guss dem jeweiligen Typ überprüfen ausdrücklich:

void delete(List<? extends Object> list){ 
    for (Object o: list) { 
     if (o instanceof ClassA) { 
      delete((ClassA) o); 
     } else if (o instanceof ClassB) { 
      delete((ClassB) o); 
     } 
    } 
} 
+0

Ist es nicht möglich, einfach zu sagen" Cast o to which class es ist Instanz von "? ohne es explizit in diese Klasse zu werfen? –

+1

@ArianHosseinzadeh Nein, der Compiler muss den Kompilierzeittyp des Arguments kennen, das an 'delete 'übergeben wird, um zu bestimmen, welche der überladenen Methoden aufgerufen werden soll. – Eran

1

Sie haben versucht, verschiedene Implementierungen zu haben, für die Löschung eines List<ClassA> vs. List<ClassB>. Sie können das in Java tun, aber nicht mit dem gleichen Methodennamen.

So können Sie eine deleteAList(List<ClassA> aList) und eine deleteBList(List<ClassB> bList) haben.

Technisch bedeutet Überladen, dass verschiedene Methoden denselben Basisnamen verwenden, aber unterschiedliche Parametertypen haben. Der Compiler weiß also, welche Methode aufgerufen werden soll.

Oder anders gesagt, der Name der effektiven Methode setzt sich aus dem von Ihnen erstellten Namen und den Parametertypen zusammen. Und dieses Konzept wurde vor der Einführung von Generika definiert, so sieht es nur delete(List list), den generics-Typparameter ignorierend, den Sie dem List hinzufügten. Sie haben also zwei Methoden mit demselben effektiven Methodennamen, und darüber beschwert sich der Compiler.

Also, helfen Sie den Compiler, indem Sie die Methode Basisnamen anders machen, und alles ist in Ordnung.

Verwandte Themen