Enthält die Signatur einer Methode in Java ihren Rückgabetyp?


102

Enthält die Methodensignatur in einer Java-Klasse / -Schnittstelle den Rückgabetyp?

Beispiel:

Kennt Java den Unterschied zwischen diesen beiden Methoden:

public class Foo {
    public int  myMethod(int param) {}
    public char myMethod(int param) {}
}

Oder ist es vielleicht nur der Methodenname und die Parameterliste wichtig?


7
Übrigens gab es einen Fehler bei der Behandlung von Generika in Java 6, der es Ihnen ermöglichte, beide Methoden zu verwenden, da die JVM den Rückgabetyp in der Signatur verwendet und diese selektiv aufruft. Dies wurde in Java 7 behoben
Peter Lawrey

Antworten:


146

Zitieren aus Oracle Docs :

Definition: Zwei der Komponenten einer Methodendeklaration umfassen die Methodensignatur - den Namen der Methode und die Parametertypen.

Geben Sie hier die Bildbeschreibung ein

Da die Frage so bearbeitet wurde, dass sie dieses Beispiel enthält:

public class Foo {
    public int  myMethod(int param) {}
    public char myMethod(int param) {}
}

Nein, der Compiler wird den Unterschied nicht kennen, da seine Signatur myMethod(int param)dieselbe ist. Die zweite Zeile:

    public char myMethod(int param) {}

gibt Ihnen können Fehler: Methode ist bereits in der Klasse definiert , was die obige Aussage weiter bestätigt.


Sie meinen also, wir können nicht zwei Methoden in der Klasse haben, die denselben Methodennamen und dieselben Parameter mit unterschiedlichen Rückgabetypen haben?
Kasun Siyambalapitiya

6
@ KasunSiyambalapitiya natürlich können wir nicht. Wie würde der Compiler wissen, welche der Methoden in einem solchen Szenario aufgerufen werden soll foo.bar(baz);?
Kolyunya

@Jops, was ist, wenn wir das Schlüsselwort throw haben? Gehört es auch zur Unterschrift?
Akila Amarasinghe

19

Enthält die Signatur der Klassenmethode in Java den Rückgabetyp?

In Java ist dies nicht der Fall, in dieser JVM jedoch, was zu offensichtlicher Verwirrung führen kann.

Enthält die Signatur der Schnittstellenmethode in Java den Rückgabetyp?

Das gleiche wie für Klassenmethoden.

Oder nur Methodenname und Parameterliste?

Methodenname und Parametertypen für Java. Zum Beispiel spielen die Parameteranmerkungen und -namen keine Rolle.


1
Was meinst du mit "In Java nicht, aber in JVM." Könnten Sie näher erläutern, wie in JVM?
Tarun Maganti

3
@TarunMaganti Die JVM enthält den Rückgabetyp in der Methodensignatur. Java als Sprache nicht.
Peter Lawrey

3
@xyz Dies können Sie sehen, indem Sie den Bytecode lesen, aber nicht den Java-Code. Jeder Bytecode zeigt dies.
Peter Lawrey

8

Auf Bytecode-Ebene ist "Rückgabetyp" Teil der Methodensignatur. Bedenken Sie

public class Test1  {
    public Test1 clone() throws CloneNotSupportedException {
        return (Test1) super.clone();
    }
}

Im Bytecode gibt es 2 clone () -Methoden

public clone()LTest1; throws java/lang/CloneNotSupportedException 

public clone()Ljava/lang/Object; throws java/lang/CloneNotSupportedException 

Sie unterscheiden sich nur nach Rückgabetyp.


1
Dies ist irreführend, da die Instanzmethode implizit die Instanz als ersten Parameter hat. Einmal kann man denken, dass om (a) tatsächlich m (o, a) ist. Was im Fall eines Klons den Unterschied ausmacht, ist das Argument, dass der Typ nicht zurückgegeben wird.
Huy Le


7

Java Language Spec sagt

Zwei Methoden haben dieselbe Signatur, wenn sie denselben Namen und dieselben Argumenttypen haben.

Daher ist der Rückgabetyp nicht Teil der Methodensignatur.


6

In JAVA und vielen anderen Sprachen können Sie eine Methode ohne Variable aufrufen, um den Rückgabewert zu speichern. Wenn der Rückgabetyp Teil einer Methodensignatur ist, kann nicht angegeben werden, welche Methode beim Aufruf aufgerufen wird, ohne dass der Rückgabewert für die Variable angegeben wird.


4

Bro, In Java verwenden wir Methoden, um sie nach ihrem Namen und ihren Parametern aufzurufen, nur um sie in unserem Code zu verwenden, wie z

myMethod (20, 40)

Daher sucht JAVA nur in der entsprechenden Deklaration (Name + Parameter) nach ähnlichen Übereinstimmungen. Aus diesem Grund enthält die Methodensignatur nur den Namen und die Parameter der Methode. :) :)



3

Nein, in Java enthält die Methodensignatur nicht den Rückgabetyp, die Deklaration jedoch.

public             String         getString(String myString)

^access modifier   ^return type   ^name    ^parameter type and name

bearbeitet basierend auf dem Feedback unten :)


1
Das sagt die JLS nicht. Es ist "der gleiche Name und die gleichen Argumenttypen". Der Zugriffsmodifikator und der Parametername sind ebenfalls nicht Teil der Methodensignatur.
Peter Lawrey

Wenn es eine Testfrage ist, die in Ordnung ist, aber wenn ich ein Programm schreibe, schreibe ich nicht public getString (), schreibe ich public String getString ()
Jeff Hawthorne

1
Der Zugriffsmodifizierer, Rückgabetyp und wirft Art (en) ist nicht Teil der Signatur, weshalb Sie nicht haben können String method( String s )und Double method( String s )in der gleichen Klasse, zum Beispiel.
Ray Stojonic

2
Vielleicht verwechseln Sie method signaturemitmethod declaration
Peter Lawrey

@ Ray Ich möchte darauf hinweisen, dass ich meine Antwort geschrieben habe, bevor er die erste Frage bearbeitet hat. Er hat nur gefragt, ob sie Teil der Signatur ist. Ich wollte sicherstellen, dass er nicht versucht hat, einen öffentlichen Namen () zu schreiben, ohne die aufzulisten Rückgabetyp (um ehrlich zu sein, er hätte seine eigene Frage beantworten können, indem er ein einfaches Programm geschrieben hätte, um sie zu testen)
Jeff Hawthorne


1

Bei Verwendung von AspectJ (org.aspectj.lang.reflect.MethodSignature) hat es den Rückgabetyp


1

DIE METHODEN-UNTERZEICHNUNG UMFASST DEN RÜCKGABETYP.

Der Compiler ignoriert es, wenn nach Duplikaten gesucht werden muss. Für Java ist es illegal, zwei Methoden zu haben, deren Signatur sich nur durch den Rückgabetyp unterscheidet.

Versuch das:

public class Called {
    public String aMethod() {
        return "";
    }
}

public class Caller {
    public static void main(String[] main) {
        aMethod();
    }
    public static void aMethod() {
        Called x = new Called();
        x.aMethod();
    }
}

Erstellen Sie das Projekt, gehen Sie in das Verzeichnis bin und kopieren Sie die Caller.cass irgendwo hin. Ändern Sie dann die aufgerufene Methode:

public int aMethod() {
    return 0;
}

Wenn Sie das Projekt erstellen, werden Sie feststellen, dass sowohl Called.class als auch Caller.class einen neuen Zeitstempel haben. Ersetzen Sie die Caller.class oben und führen Sie das Projekt aus. Sie haben eine Ausnahme:

java.lang.NoSuchMethodError: it.prova.Called.aMethod()Ljava/lang/String;


0

Wenn Sie versuchen, den Code auszuführen, den Sie in Eclipse erwähnt haben, erhalten Sie eine Antwort darauf, nach welchen Elementen der Java-Compiler sucht, um zwischen Java-Methoden zu unterscheiden:

class Foo {
    public int  myMethod(int param) {
        return param;}
    public char *myMethod*(int param) { //this line throws an error 
        return param;
    }
}

Der Fehler lautet: Doppelte Methode myMethod (int) vom Typ Foo.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.