¿La firma de un método en Java incluye su tipo de retorno?

102

¿La firma del método en una clase / interfaz Java incluye su tipo de retorno?

Ejemplo:

¿Conoce Java la diferencia entre esos dos métodos?

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

¿O tal vez solo importa el nombre del método y la lista de parámetros?

faressoft
fuente
7
Por cierto, hubo un error en el manejo de genéricos en Java 6 que le permitió tener ambos métodos, ya que la JVM usa el tipo de retorno en la firma y los llama selectivamente. Esto se solucionó en Java 7. vanillajava.blogspot.co.uk/2011/02/…
Peter Lawrey

Respuestas:

146

Citando de Oracle Docs :

Definición: dos de los componentes de una declaración de método comprenden la firma del método: el nombre del método y los tipos de parámetros.

ingrese la descripción de la imagen aquí

Dado que la pregunta se editó para incluir este ejemplo:

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

No, el compilador no notará la diferencia, ya que su firma: myMethod(int param)es la misma. La segunda línea:

    public char myMethod(int param) {}

le dará un error: el método ya está definido en la clase , lo que confirma aún más la declaración anterior.

Jops
fuente
¿Quiere decir que no podemos tener dos métodos en la clase con el mismo nombre de método, los mismos parámetros con diferentes tipos de retorno?
Kasun Siyambalapitiya
6
@KasunSiyambalapitiya de cource no podemos. ¿Cómo sabría el compilador cuál de los métodos llamar en un escenario como este foo.bar(baz);?
Kolyunya
@Jops, ¿y si tenemos la palabra clave throws? ¿Pertenece también a la firma?
Akila Amarasinghe
19

¿La firma del método de clase en Java incluye el tipo de retorno?

En Java, no lo hace, pero en esta JVM lo hace, lo que puede generar una confusión obvia.

¿La firma del método de interfaz en Java incluye el tipo de retorno?

Lo mismo que para los métodos de clase.

¿O solo el nombre del método y la lista de parámetros?

Nombre del método y tipos de parámetros para Java. Por ejemplo, las anotaciones y los nombres de los parámetros no importan.

Peter Lawrey
fuente
1
¿Qué quieres decir con "En Java no lo hace, pero en JVM lo hace". ¿Podrías explicar cómo en JVM?
Tarun Maganti
3
@TarunMaganti La JVM incluye el tipo de retorno en la firma del método. Java como lenguaje no lo hace.
Peter Lawrey
3
@xyz esto es algo que puede ver leyendo el código de bytes pero no el código Java. Cualquier código de bytes muestra esto.
Peter Lawrey
8

A nivel de código de bytes, el "tipo de retorno" es parte de la firma del método. Considera esto

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

en bytecode hay 2 métodos clone ()

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

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

solo se diferencian por el tipo de retorno.

Evgeniy Dorofeev
fuente
1
esto es engañoso ya que el método de instancia tiene implícitamente la instancia como primer parámetro. Una vez se puede pensar que om (a) es de hecho m (o, a). Como tal, en el caso de la clonación, lo que hace la diferencia es que el argumento no devuelve el tipo.
Huy Le
7

La especificación del lenguaje Java dice

Dos métodos tienen la misma firma si tienen el mismo nombre y tipos de argumentos.

por lo tanto, No, el tipo de retorno no es parte de la firma del método.

PermGenError
fuente
6

En JAVA y muchos otros lenguajes, puede llamar a un método sin una variable para mantener el valor de retorno. Si el tipo de retorno es parte de la firma de un método, no hay forma de saber qué método se llamará al llamar sin especificar la variable que contiene el valor de retorno.

Huy Le
fuente
4

Hermano, en Java, solemos llamar a los métodos por su nombre y sus parámetros solo para usarlos en nuestro código, como

myMethod (20, 40)

Entonces, JAVA solo busca cosas similares que coincidan en su declaración correspondiente (nombre + parámetro), es por eso que la firma del método solo incluye el nombre y los parámetros del método. :)

NIKHIL CHAURASIA
fuente
3

La firma del método es solo el nombre y la lista de parámetros.

Ray Stojonic
fuente
3

no, en Java la firma del método no incluye el tipo de retorno, pero la declaración sí.

public             String         getString(String myString)

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

editado en base a los comentarios a continuación :)

Jeff Hawthorne
fuente
1
Eso no es lo que dice la JLS. Es "el mismo nombre y tipos de argumentos". El modificador de acceso y el nombre del parámetro tampoco forman parte de la firma del método.
Peter Lawrey
si es una pregunta de prueba, está bien, pero si estoy escribiendo un programa no estoy escribiendo public getString (), estoy escribiendo public String getString ()
Jeff Hawthorne
1
El modificador de acceso, el tipo de retorno y los tipos de lanzamiento no forman parte de la firma, por lo que no se puede tener String method( String s )y Double method( String s )en la misma clase, por ejemplo.
Ray Stojonic
2
Tal vez usted está confundiendo method signatureconmethod declaration
Peter Lawrey
@Ray, me gustaría señalar, escribí mi respuesta antes de que él editara la pregunta inicial, todo lo que preguntó fue que era parte de la firma, quería asegurarme de que no estaba tratando de escribir el nombre público () sin enumerar el tipo de retorno (la verdad sea dicha, podría haber respondido su propia pregunta con solo escribir un programa simple para probarlo)
Jeff Hawthorne
1

Usando AspectJ (org.aspectj.lang.reflect.MethodSignature), tiene el tipo de retorno

devnull
fuente
1

LA FIRMA DEL MÉTODO INCLUYE EL TIPO DE DEVOLUCIÓN.

El compilador lo ignora cuando tiene que buscar duplicados. Para Java, es ilegal tener dos métodos con la firma que difieran solo por el tipo de retorno.

Trata eso:

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

Construya el proyecto, vaya al directorio bin, copie Caller.cass en algún lugar. Luego cambia el método llamado:

public int aMethod() {
    return 0;
}

Construya el proyecto, verá que tanto Called.class como Caller.class tienen una nueva marca de tiempo. Reemplace la Caller.class anterior y ejecute el proyecto. Tendrás una excepción:

java.lang.NoSuchMethodError: it.prova.Called.aMethod()Ljava/lang/String;
Lucio Menci
fuente
0

Si intenta ejecutar el código que ha mencionado en eclipse, tendrá una respuesta sobre qué elementos busca el compilador de Java para diferenciar entre los métodos de Java:

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

El error arrojado es: Método duplicado myMethod (int) en tipo Foo.

Nishant_Singh
fuente