java - standard - Variables locales antes de declaraciones de retorno, ¿importa?
tag lib jstl (3)
Elige la versión que creas más legible.
Hay casos legítimos donde la variable nombrada mejora la legibilidad. Por ejemplo
public String encrypt(String plainString)
{
byte[] plainBytes = plainString.getBytes(StandardCharsets.UTF_8);
byte[] hashPlainBytes = enhash( plainBytes, 4 );
byte[] encryptedBytes = doAes128(Cipher.ENCRYPT_MODE , hashPlainBytes );
String encryptedBase64 = Base64.getEncoder().withoutPadding().encodeToString(encryptedBytes);
return encryptedBase64;
}
public String decrypt(String encryptedBase64)
{
byte[] encryptedBytes = Base64.getDecoder().decode(encryptedBase64);
byte[] hashPlainBytes = doAes128(Cipher.DECRYPT_MODE , encryptedBytes );
byte[] plainBytes = dehash( hashPlainBytes, 4 );
String plainString = new String(plainBytes, StandardCharsets.UTF_8);
return plainString;
}
También hay casos en los que necesitamos una variable de un tipo diferente al tipo de retorno. Esto afecta la conversión de tipo y la inferencia, lo que hace una diferencia semántica significativa.
Foo foo() vs. Foo foo()
{ {
Bar bar = expr;
return expr; return bar;
} }
Lo siento si esta es una pregunta de novato pero no pude encontrar una respuesta para esto. ¿Es mejor hacer esto?
int result = number/number2;
return result;
o:
return number/number2;
Sé que los enteros usan memoria, así que supongo que disminuirá ligeramente el rendimiento. Pero, por otro lado, aclara las cosas, especialmente cuando el int / string es un cálculo largo.
En realidad, existe una regla de SonarQube heredada de PMD llamada Local Necesario Antes de Devolver que habla de esto. Dice:
Evitar la creación innecesaria de variables locales.
Esta regla fue reemplazada posteriormente por la regla SSLR. Las variables no se deben declarar y luego se deben devolver o lanzar de inmediato , lo que mantiene la misma posición:
Declarar una variable solo para devolverla o lanzarla de inmediato es una mala práctica . Algunos desarrolladores argumentan que la práctica mejora la legibilidad del código, porque les permite nombrar explícitamente lo que se está devolviendo. Sin embargo, esta variable es un detalle de implementación interna que no está expuesto a los llamadores del método. El nombre del método debe ser suficiente para que las personas que llaman sepan exactamente qué se devolverá .
Y estoy totalmente de acuerdo con eso.
IntelliJ (o al menos Android Studio) también tiene una advertencia para esta situación:
Variable utilizada solo en la siguiente devolución y puede estar en línea.
Esta inspección informa las variables locales que se usan solo en la próxima devolución o las copias exactas de otras variables. En ambos casos es mejor alinear dicha variable.
No creo que el rendimiento sea algo de qué preocuparse en absoluto en esta situación. Dicho esto, como mencionó @Clashsoft en su comentario, el JIT probablemente incorporará la variable y usted obtendrá el mismo resultado en ambos sentidos.
Los compiladores suelen ser lo suficientemente inteligentes como para optimizar este tipo de cosas según corresponda. Ver optimizaciones de flujo de datos en Wikipedia.
En este caso, es probable que deba asignar una variable temporal para almacenar el resultado, incluso si usted no especifica una.
Edit: Clashsoft tiene razón sobre el compilador de bytecode:
$ cat a.java
class a {
public static int a(int x, int y) {
return x / y;
}
public static int b(int x, int y) {
int r = x/y;
return r;
}
public static int c(int x, int y) {
final int r = x/y;
return r;
}
}
$ javap -c a
Compiled from "a.java"
class a {
a();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static int a(int, int);
Code:
0: iload_0
1: iload_1
2: idiv
3: ireturn
public static int b(int, int);
Code:
0: iload_0
1: iload_1
2: idiv
3: istore_2
4: iload_2
5: ireturn
public static int c(int, int);
Code:
0: iload_0
1: iload_1
2: idiv
3: istore_2
4: iload_2
5: ireturn
}