La signature d'une méthode en Java inclut-elle son type de retour?


102

La signature de méthode dans une classe / interface Java inclut-elle son type de retour?

Exemple:

Java connaît-il la différence entre ces deux méthodes:

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

Ou est-ce seulement le nom de la méthode et la liste des paramètres qui comptent?


7
À propos, il y avait un bogue dans la gestion des génériques dans Java 6 qui vous permettait d'avoir les deux méthodes, car la JVM utilise le type de retour dans la signature et les appelle de manière sélective. Ce problème a
Peter Lawrey

Réponses:


146

Citations d' Oracle Docs :

Définition: Deux des composants d'une déclaration de méthode comprennent la signature de méthode - le nom de la méthode et les types de paramètres.

entrez la description de l'image ici

Puisque la question a été modifiée pour inclure cet exemple:

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

Non, le compilateur ne connaîtra pas la différence, car leur signature: myMethod(int param)est la même. La deuxième ligne:

    public char myMethod(int param) {}

vous donnera peut erreur: la méthode est déjà définie dans la classe , ce qui confirme davantage l'instruction ci-dessus.


Vous voulez dire que nous ne pouvons pas avoir deux méthodes dans la classe ayant le même nom de méthode, les mêmes paramètres avec des types de retour différents?
Kasun Siyambalapitiya

6
@KasunSiyambalapitiya de cource nous ne pouvons pas. Comment le compilateur pourrait-il savoir laquelle des méthodes à appeler dans un scénario comme celui-ci foo.bar(baz);?
Kolyunya le

@Jops, et si nous avons le mot-clé throws? Appartient-il aussi à la signature?
Akila Amarasinghe

19

La signature de méthode de classe en Java inclut-elle le type de retour?

En Java, ce n'est pas le cas, mais dans cette JVM, c'est le cas, ce qui peut conduire à une confusion évidente.

La signature de la méthode d'interface en Java inclut-elle le type de retour?

La même chose que pour les méthodes de classe.

Ou seulement le nom de la méthode et la liste des paramètres?

Nom de méthode et types de paramètres pour Java. Par exemple, les annotations et les noms des paramètres n'ont pas d'importance.


1
Qu'entendez-vous par "En Java, ce n'est pas le cas, mais en JVM, c'est le cas.". Pourriez-vous expliquer comment en JVM?
Tarun Maganti

3
@TarunMaganti La JVM inclut le type de retour dans la signature de la méthode. Java en tant que langage ne le fait pas.
Peter Lawrey

3
@xyz c'est quelque chose que vous pouvez voir en lisant le code d'octet mais pas le code Java. Tout code d'octet le montre.
Peter Lawrey

8

Au niveau du bytecode, le "type de retour" fait partie de la signature de méthode. Considère ceci

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

dans bytecode il y a 2 méthodes clone ()

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

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

ils diffèrent uniquement par le type de retour.


1
ceci est trompeur car la méthode d'instance a implicitement l'instance comme premier paramètre. On peut penser que om (a) est en fait m (o, a). En tant que tel en cas de clone, ce qui fait la différence, c'est l'argument pas le type de retour.
Huy Le



6

En JAVA et dans de nombreux autres langages, vous pouvez appeler une méthode sans variable pour contenir la valeur de retour. Si le type de retour fait partie d'une signature de méthode, il n'y a aucun moyen de savoir quelle méthode sera appelée lors de l'appel sans spécifier la variable contenant la valeur de retour.


4

Bro, En java, nous utilisons pour appeler des méthodes par leur nom et leurs paramètres uniquement pour les utiliser dans notre code, comme

myMethod (20, 40)

Ainsi, JAVA ne recherche que des éléments similaires correspondant dans leur déclaration correspondante (nom + paramètre), c'est pourquoi la signature de méthode inclut uniquement le nom et les paramètres de la méthode. :)


3

La signature de la méthode est uniquement le nom et la liste des paramètres.


3

non, en Java, la signature de méthode n'inclut pas le type de retour, mais la déclaration le fait.

public             String         getString(String myString)

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

édité en fonction des commentaires ci-dessous :)


1
Ce n'est pas ce que dit le JLS. Ce sont «les mêmes types de nom et d'argument». Le modificateur d'accès et le nom du paramètre ne font pas non plus partie de la signature de la méthode.
Peter Lawrey

si c'est une question de test c'est bien, mais si j'écris un programme je n'écris pas public getString (), j'écris public String getString ()
Jeff Hawthorne

1
Le modificateur d'accès, le type de retour et le ou les types de jet ne font pas partie de la signature, c'est pourquoi vous ne pouvez pas avoir String method( String s )et Double method( String s )dans la même classe, par exemple.
Ray Stojonic

2
Peut-être que vous confondez method signatureavecmethod declaration
Peter Lawrey

@Ray je voudrais noter, j'ai écrit ma réponse avant de modifier la question initiale, tout ce qu'il a demandé était que cela faisait partie de la signature, je voulais m'assurer qu'il n'essayait pas d'écrire le nom public () sans énumérer le type de retour (à vrai dire, il aurait pu répondre à sa propre question simplement en écrivant un programme simple pour le tester)
Jeff Hawthorne


1

En utilisant AspectJ (org.aspectj.lang.reflect.MethodSignature), il a le type de retour


1

LA SIGNATURE DE LA MÉTHODE INCLUT LE TYPE DE RETOUR.

Le compilateur l'ignore lorsqu'il doit vérifier les doublons. Pour Java, il est illégal d'avoir deux méthodes dont la signature ne diffère que par le type de retour.

Essayez ça:

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();
    }
}

Construisez le projet, allez dans le répertoire bin, copiez le Caller.cass quelque part. Puis changez la méthode appelée:

public int aMethod() {
    return 0;
}

Générez le projet, vous verrez que Called.class et Caller.class ont un nouvel horodatage. Remplacez le Caller.class ci-dessus et exécutez le projet. Vous aurez une exception:

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


0

Si vous essayez d'exécuter le code que vous avez mentionné sur eclipse, vous aurez une réponse sur les éléments que le compilateur java recherche pour différencier les méthodes java:

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

L'erreur générée est: Dupliquer la méthode myMethod (int) dans le type Foo.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.