7

Warum löst das folgende Programm eine Ausnahme aus?SCJP Frage: Java Methode überladen mit var-args. Was ist der Grund?

public class MainClass{ 
    public static void main(String[] argv){ 
     callMethod(2); 
    } 
    public static void callMethod(Integer... i){ 
     System.out.println("Wrapper"); 
    } 
    public static void callMethod(int... i){ 
     System.out.println("Primitive"); 
    } 

}

Die Methode Callmethod (Integer []) ist nicht eindeutig für den Typ Mainclass

OK, kann ich sehen, dass eine der beiden Methoden funktionieren wird (wenn die Andere sind auskommentiert), aber ich weiß auch, dass es eine Hierarchie gibt, was passiert, wenn ein Primitiv nicht exakt mit dem Typ der Eingabe einer Methode übereinstimmt.

Das erste, was versucht wird, ist das Primitiv zu erweitern. Also, wenn gab es eine dritte Methode:

 public static void callMethod(long i){ 
     System.out.println("long"); 
     } 

Der Code würde lange

Das zweite, was gedruckt ist, das primitive boxen. Wenn es also eine Methode gibt, die eine Ganzzahl annimmt, wäre das die aufgerufene.

Die dritte Priorität sind die var-args.

Basierend auf der obigen Priorität, würde ich erwarten, dass die zweite Priotität der Fall sein wird. Ich würde erwarten, dass der Int in einen Integer eingeschlossen wird und der (Integer ...) aufgerufen wird. Aber das passiert natürlich nicht. Stattdessen wird die Ausnahme ausgelöst.

Kann jemand sehen und erklären warum die Priorisierung in diesem Beispiel nicht zutrifft?

Prost!

Antwort

9

Sie haben Recht, dass Verbreiterung kommt vor dem Boxen, die wiederum kommt vor Var-Args.

Aber Sie scheinen die erste Methode wie callMethod(Integer i) zu behandeln, nicht callMethod(Integer... i). Da beide Methoden var-args verwenden, gibt es eine Priorität tie. Das heißt, keiner erfüllt die Kriterien für das Boxen allein, aber beide erfüllen die Kriterien für Var-Args.

Denken Sie daran, dass es illegal ist, zu erweitern, dann Box (obwohl ich einige Forschung vor dem Posten dieser Antwort und fand, dass es legal ist, zu boxen, dann erweitern). In ähnlicher Weise erhalten Sie nicht Box, dann var-args-Verhalten; Der Compiler springt direkt zum var-args-Schritt und sieht zwei Methoden, die var-args verwenden.

EDIT: Ich sollte klarstellen, dass Sie Box-dann-Var-Args-Verhalten erhalten, wenn es keine Mehrdeutigkeit gibt. Mit anderen Worten, wenn es nur eine callMethod() und Integer... i gäbe, würden Sie "Wrapper" erhalten.

+0

Ich dachte irgendwie, dass es versucht, die drei Ansätze und die erste "aufrufbar" würde aufgerufen werden. Obwohl die Methode (Integer ... i) akzeptiert, erwartete ich, dass das Einbetten in Integer diese Methode "aufrufbar" machen würde. Aber wie Sie sagen, scheint auch die nachfolgende "Var-Argalisierung" zu berücksichtigen. Prost! –