Introducción
Como sabemos, Java es un lenguaje de programación orientado a objetos. Es decir, el concepto básico, porque decir que la base de los fundamentos es que todo es un objeto. Los objetos se describen mediante clases.
Las clases, a su vez, tienen estado y comportamiento. Por ejemplo, una cuenta bancaria puede tener un estado en forma de cantidad de dinero en la cuenta y tener el comportamiento de aumentar y disminuir el saldo. El comportamiento en Java se implementa mediante métodos. La forma de describir métodos se presenta al comienzo de su viaje de aprendizaje de Java. Por ejemplo, en el tutorial oficial de Oracle: “
Definición de métodos ”. Hay dos aspectos importantes aquí:
- Cada método tiene una firma. La firma consta del nombre del método y sus parámetros de entrada;
- Los métodos deben especificar un tipo de devolución;
- El tipo de retorno no forma parte de la firma del método.
Nuevamente, esto es una consecuencia del hecho de que Java es un lenguaje fuertemente tipado y el compilador quiere entender de antemano qué tipos se utilizan y dónde tanto como sea posible. Nuevamente, para protegernos de los errores. En general, todo es para bien. Bueno, me parece que esto nos inculca una vez más una cultura de manejo de datos. Entonces, para los métodos se especifica el tipo de valor. Y para devolver este mismo valor de los métodos se utiliza la palabra clave
return
.
Declaración de devolución de palabras clave en Java
La palabra clave de declaración
return
se refiere a "declaraciones de flujo de control" como se analiza en el tutorial de Oracle "
Declaraciones de flujo de control ". También puedes leer sobre cómo devolver valores en el tutorial oficial: "
Devolver un valor de un método ". El compilador supervisa cuidadosamente, lo mejor que puede, que el valor devuelto por un método coincida con el tipo de valor devuelto especificado por el método.
Usemos el IDE en línea de tutorialspoint como ejemplo . Veamos el ejemplo original:
public class HelloWorld {
public static void main(String []args) {
System.out.println("Hello World");
}
}
Como podemos ver, aquí se ejecuta un método
main
, que es el punto de entrada al programa. Las líneas de código se ejecutan de arriba a abajo. Nuestro
main
método no puede devolver valores; de lo contrario, recibiremos un error: "
Error: Main method must return a value of type void
". Por lo tanto, el método simplemente aparecerá en la pantalla. Ahora traslademos la recepción de la cadena a un método separado para recibir el mensaje:
public class HelloWorld {
public static void main(String []args) {
System.out.println(getHelloMessage());
}
public static String getHelloMessage() {
return "Hello World";
}
}
Como podemos ver, usando la palabra clave
return
especificamos el valor de retorno, que usamos más adelante en el método
println
. En la descripción (definición) del método
getHelloMessage
indicamos que nos devolverá
String
. Esto permite al compilador verificar que las acciones del método sean consistentes con la forma en que se declara. Naturalmente, el tipo de valor de retorno especificado en la definición del método puede ser más amplio que el tipo de valor devuelto por el código, es decir Lo principal es que los tipos se reducen entre sí. De lo contrario obtendremos un error de tiempo de compilación: "
error: incompatible types
". Por cierto, probablemente inmediatamente surgió la pregunta: ¿Por qué
return
se aplica esto a los operadores de control de flujo de programas? Sino porque puede alterar el flujo normal del programa de arriba a abajo. Por ejemplo:
public class HelloWorld {
public static void main(String []args){
if (args.length == 0) {
return;
}
for (String arg : args) {
System.out.println(arg);
}
}
}
Como puede verse en el ejemplo, interrumpimos la ejecución del método
main
si nuestro programa Java se llama sin parámetros. Es importante recordar que si luego
return
tienes el código, éste se vuelve inaccesible. Y nuestro compilador inteligente se dará cuenta de esto y no le permitirá ejecutar dicho programa. Por ejemplo, este código no compilará:
public static void main(String []args) {
System.out.println("1");
return;
System.out.println("2");
}
Hay un truco sucio para solucionar este problema. Por ejemplo, con fines de depuración o por algún otro motivo. El código anterior se puede arreglar envolviéndolo
return
en
if
un bloque:
if (2==2) {
return;
}
Declaración de devolución en el manejo de errores
Hay una circunstancia muy complicada: podemos usarla
return
junto con el manejo de errores. Me gustaría decir de inmediato que usarlo
return
en
catch
bloque es de muy, muy mala forma, por lo que debes evitarlo. Pero necesitamos un ejemplo, ¿verdad? Aquí está él:
public class HelloWorld {
public static void main(String []args) {
System.out.println("Value is: " + getIntValue());
}
public static int getIntValue() {
int value = 1;
try {
System.out.println("Something terrible happens");
throw new Exception();
} catch (Exception e) {
System.out.println("Catched value: " + value);
return value;
} finally {
value++;
System.out.println("New value: " + value);
}
}
}
A primera vista, parece que se debe devolver 2, porque
finally
siempre se ejecuta. Pero no, el valor será 1 y
finally
se ignorará el cambio de la variable en. Además, si
value
contuviera un objeto y dijéramos
finally
,
value = null
aún así
catch
devolvería una referencia al objeto, no
null
. Pero desde el bloque
finally
el operador
return
habría trabajado correctamente. Es evidente que los colegas no le agradecerán tal regalo.
clase.void
Y finalmente. Puedes escribir una construcción extraña como
void.class
. Parecería, ¿por qué y cuál es el punto? De hecho, en varios marcos y casos complicados donde se utiliza
la API Java Reflection , esto puede ser muy necesario. Por ejemplo, puedes comprobar qué tipo devuelve un método:
import java.lang.reflect.Method;
public class HelloWorld {
public void getVoidValue() {
}
public static void main(String[] args) {
for (Method method : HelloWorld.class.getDeclaredMethods()) {
System.out.println(method.getReturnType() == void.class);
}
}
}
Esto puede resultar útil en marcos de prueba donde es necesario reemplazar el código real de métodos. Pero para hacer esto, necesitas entender cómo se comporta este método (es decir, qué tipos devuelve). Hay una segunda forma de implementar el método
main
del código anterior:
public static void main (String[] args) {
for (Method method : HelloWorld.class.getDeclaredMethods()) {
System.out.println(method.getReturnType() == Void.TYPE);
}
}
Se puede leer una discusión bastante interesante sobre la diferencia entre ellos en stackoverflow: ¿
Cuál es la diferencia entre java.lang.Void y void? #viacheslav
GO TO FULL VERSION