it-swarm.com.de

Überladen der Methode für ein Nullargument

Ich habe drei Methoden mit Parametern hinzugefügt:

public static  void doSomething(Object obj) {
    System.out.println("Object called");
}

public static  void doSomething(char[] obj) {
    System.out.println("Array called");
}

public static  void doSomething(Integer obj) {
    System.out.println("Integer called");
}

Wenn ich doSomething(null) anrufe, wirft der Compiler einen Fehler als mehrdeutige Methoden . Ist das Problem also, weil Integer- und char[]-Methoden oder Integer- und Object-Methoden?

118
Phani

Java wird immer versuchen, die jeweils spezifischste Version einer verfügbaren Methode zu verwenden (siehe JLS §15.12.2 ).

Object, char[] und Integer können alle null als gültigen Wert annehmen. Daher sind alle 3-Versionen anwendbar, sodass Java die spezifischste Version finden muss.

Da Object der Supertyp von char[] ist, ist die Array-Version spezifischer als die Object- -Version. Wenn also nur diese beiden Methoden vorhanden sind, wird die char[]-Version ausgewählt.

Wenn sowohl die char[]- als auch die Integer-Version verfügbar sind, sind both spezifischer als Object, aber keine ist spezifischer als die andere, daher kann Java nicht entscheiden, welche aufgerufen werden soll. In diesem Fall müssen Sie explizit angeben, welche Sie aufrufen möchten, indem Sie das Argument in den entsprechenden Typ umwandeln.

Man beachte, dass dieses Problem in der Praxis viel seltener auftritt, als man vielleicht denkt. Der Grund dafür ist, dass dies nur dann der Fall ist, wenn Sie eine Methode explizit mit null oder mit einer Variablen eines eher unspezifischen Typs aufrufen (z. B. Object).

Im Gegenteil wäre der folgende Aufruf vollkommen eindeutig:

char[] x = null;
doSomething(x);

Obwohl Sie immer noch den Wert null übergeben, weiß Java genau, welche Methode aufgerufen werden soll, da der Typ der Variablen berücksichtigt wird.

194
Joachim Sauer

Jedes Paar dieser drei Methoden ist für sich alleine mehrdeutig, wenn es mit einem null-Argument aufgerufen wird. Weil jeder Parametertyp ein Referenztyp ist. 

Im Folgenden werden die drei Möglichkeiten beschrieben, eine bestimmte Methode von Ihnen mit null aufzurufen.

doSomething( (Object) null);
doSomething( (Integer) null);
doSomething( (char[]) null);

Ich kann vorschlagen, diese Mehrdeutigkeit zu entfernen, wenn Sie diese Methoden tatsächlich mit null-Argumenten aufrufen möchten. Ein solches Design führt zu Fehlern in der Zukunft.

38
jmg

null ist ein gültiger Wert für einen der drei Typen. Der Compiler kann also nicht entscheiden, welche Funktion verwendet werden soll. Verwenden Sie stattdessen etwas wie doSomething((Object)null) oder doSomething((Integer)null).

4
Lars Noschinski

Jede Klasse in Java erweitert die Object-Klasse. Die Integer-Klasse erweitert auch Object. Daher werden sowohl Object als auch Integer als Objektinstanz betrachtet. Wenn Sie also null als Parameter übergeben, wird der Compiler verwechselt, welche Objektmethode aufgerufen werden soll, d. H. Mit dem Parameter Object oder dem Parameter Integer, da beide Objekte sind und deren Referenz null sein kann. Die Grundelemente in Java erweitern Object jedoch nicht.

2
Ankit

Ich habe es ausprobiert und wenn es genau ein Paar überladener Methoden gibt und eine davon einen Parametertyp Object hat, wählt der Compiler die Methode immer mit einem spezifischeren Typ aus. Wenn es jedoch mehr als einen bestimmten Typ gibt, löst der Compiler einen mehrdeutigen Methodenfehler aus. 

Da es sich um ein Kompilierzeitereignis handelt, kann dies nur passieren, wenn einer dieser Methoden absichtlich eine Null übergeben wird. Wenn dies absichtlich geschieht, ist es besser, diese Methode erneut ohne Parameter zu überladen oder eine andere Methode zu erstellen. 

1
Jafar Ali
class Sample{
  public static void main (String[] args) {
       Sample s = new Sample();
       s.printVal(null);

    } 
    public static void printVal(Object i){
        System.out.println("obj called "+i);
    }

    public static void printVal(Integer i){
        System.out.println("Int called "+i);
    }
}

Die Ausgabe ist Int und wird als Null bezeichnet. Die Mehrdeutigkeit besteht also bei char [] und Integer 

es gibt eine Mehrdeutigkeit wegen doSomething (char [] obj) und doSomething (Integer obj).

char [] und Integer sind beide für null gleich, weshalb sie mehrdeutig sind.