La firma di un metodo in Java include il tipo restituito?


102

La firma del metodo in una classe / interfaccia Java include il tipo restituito?

Esempio:

Java conosce la differenza tra questi due metodi:

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

O forse sono solo il nome del metodo e l'elenco dei parametri che contano?


7
A proposito, c'era un bug nella gestione dei generici in Java 6 che ti consentiva di avere entrambi i metodi, poiché la JVM utilizza il tipo di ritorno nella firma e li chiama selettivamente. Questo problema è
Peter Lawrey,

Risposte:


146

Citando da Oracle Docs :

Definizione: due dei componenti di una dichiarazione di metodo comprendono la firma del metodo: il nome del metodo ei tipi di parametro.

inserisci qui la descrizione dell'immagine

Poiché la domanda è stata modificata per includere questo esempio:

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

No, il compilatore non conoscerà la differenza, poiché la loro firma: myMethod(int param)è la stessa. La seconda riga:

    public char myMethod(int param) {}

ti darà un errore: il metodo è già definito nella classe , il che conferma ulteriormente l'affermazione sopra.


Quindi vuoi dire che non possiamo avere due metodi in classe con lo stesso nome di metodo, stessi parametri con diversi tipi di ritorno?
Kasun Siyambalapitiya,

6
@KasunSiyambalapitiya of cource we can't. Come farebbe il compilatore a sapere quale dei metodi chiamare in uno scenario come questo foo.bar(baz);?
Kolyunya

@Jops, e se abbiamo la parola chiave throws? Appartiene anche alla firma?
Akila Amarasinghe

19

La firma del metodo di classe in Java include il tipo restituito?

In Java, non lo fa, ma in questa JVM lo fa, il che può portare a un'ovvia confusione.

La firma del metodo di interfaccia in Java include il tipo restituito?

Lo stesso dei metodi di classe.

O solo il nome del metodo e l'elenco dei parametri?

Nome del metodo e tipi di parametri per Java. Ad esempio, le annotazioni e i nomi dei parametri non sono importanti.


1
Cosa intendi con "In Java non è così ma in JVM sì.". Potresti approfondire come in JVM?
Tarun Maganti

3
@TarunMaganti La JVM include il tipo restituito nella firma del metodo. Java come linguaggio no.
Peter Lawrey

3
@xyz questo è qualcosa che puoi vedere leggendo il codice byte ma non il codice Java. Qualsiasi codice byte lo mostra.
Peter Lawrey

8

A livello di bytecode, il "tipo restituito" fa parte della firma del metodo. Considera questo

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

in bytecode ci sono 2 metodi clone ()

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

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

differiscono solo per il tipo restituito.


1
ciò è fuorviante in quanto il metodo di istanza ha implicitamente l'istanza come primo parametro. Una volta può pensare che om (a) sia in effetti m (o, a). In quanto tale, in caso di clone, ciò che fa la differenza è l'argomento non restituito tipo.
Huy Le


7

Java Language Spec dice

Due metodi hanno la stessa firma se hanno lo stesso nome e tipi di argomenti.

quindi No, il tipo restituito non fa parte della firma del metodo.


6

In JAVA e in molte altre lingue, puoi chiamare un metodo senza una variabile per contenere il valore restituito. Se il tipo restituito fa parte della firma di un metodo, non è possibile sapere quale metodo verrà chiamato durante la chiamata senza specificare il valore di ritorno della variabile.


4

Bro, In java, usiamo per chiamare metodi con il loro nome e i loro parametri solo per usarli nel nostro codice, come

myMethod (20, 40)

quindi, JAVA cerca solo roba simile corrispondente nella dichiarazione corrispondente (nome + parametro), questo è il motivo per cui la firma del metodo include solo il nome e i parametri del metodo. :)



3

no, in Java la firma del metodo non include il tipo restituito, ma la dichiarazione sì.

public             String         getString(String myString)

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

modificato in base al feedback di seguito :)


1
Non è quello che dice il JLS. È "lo stesso nome e tipi di argomenti". Anche il modificatore di accesso e il nome del parametro non fanno parte della firma del metodo.
Peter Lawrey

se è una domanda di prova va bene, ma se sto scrivendo un programma non sto scrivendo public getString (), sto scrivendo public String getString ()
Jeff Hawthorne

1
Il modificatore di accesso, il tipo restituito e il / i tipo / i di lancio non fanno parte della firma, motivo per cui non puoi avere String method( String s )e Double method( String s )nella stessa classe, ad esempio.
Ray Stojonic

2
Forse stai confondendo method signatureconmethod declaration
Peter Lawrey

@ Ray vorrei sottolineare, ho scritto la mia risposta prima di modificare la domanda iniziale, tutto ciò che mi ha chiesto è stato se fosse parte della firma, volevo assicurarmi che non stesse cercando di scrivere il nome pubblico () senza elencare il tipo di ritorno (a dire il vero, avrebbe potuto rispondere alla sua stessa domanda semplicemente scrivendo un semplice programma per testarlo)
Jeff Hawthorne


1

Utilizzando AspectJ (org.aspectj.lang.reflect.MethodSignature), ha il tipo di ritorno


1

IL METODO FIRMA COMPRENDE IL TIPO DI RESO.

Il compilatore lo ignora quando deve controllare i duplicati. Per Java è illegale avere due metodi con la firma che differisce solo dal tipo restituito.

Prova questo:

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

Costruisci il progetto, vai alla directory bin, copia Caller.cass da qualche parte. Quindi cambia il metodo chiamato:

public int aMethod() {
    return 0;
}

Crea il progetto, vedrai che sia Called.class che Caller.class hanno un nuovo timestamp. Sostituisci Caller.class sopra ed esegui il progetto. Avrai un'eccezione:

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


0

Se provi a eseguire il codice che hai menzionato su eclipse, avrai una risposta su quali elementi cerca il compilatore java differenziando tra i metodi java:

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

L'errore generato è: metodo duplicato myMethod (int) nel tipo Foo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.