返回语句之前的局部变量,这有关系吗?

时间:2015-07-30 20:51:52

标签: java string memory int helper

很抱歉,如果这是一个新手问题,但我找不到答案。 这样做更好:

int result = number/number2;
return result;

或:

return number/number2;

我知道整数使用内存所以我猜它会略微降低性能?但另一方面,它使事情更清晰,特别是当int / string是一个很长的计算时。

3 个答案:

答案 0 :(得分:17)

实际上有一个从PMD继承的SonarQube规则,名为 Unnecessary Local Before Return ,它说明了这一点。它说:

  

避免不必要地创建局部变量。

SSLR规则 later replaced 的此规则为Variables should not be declared and then immediately returned or thrown,该规则保持相同的位置:

  

声明一个变量只是为了立即返回或抛出它是坏   实践即可。一些开发人员认为这种做法可以改进代码   可读性,因为它使他们能够明确地命名正在发生的事情   回。但是,此变量是内部实现细节   没有暴露给方法的调用者。 方法名称   应该足以让呼叫者确切知道将会是什么   返回

我完全同意。

IntelliJ(或至少Android Studio)也有针对这种情况的警告:

  

变量仅用于以下返回并且可以内联

     

此检查报告局部变量,仅用于下一次返回或其他变量的精确副本。在这两种情况下,更好地内联这样的变量。

在这种情况下,我根本不认为表现是值得担心的。话虽如此,正如@Clashsoft在评论中提到的那样,JIT最有可能内联变量,你最终会得到相同的结果。

答案 1 :(得分:6)

选择您认为更具可读性的版本。

有一些合法的情况,命名变量提高了可读性。例如

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

在某些情况下,我们需要一个与返回类型不同的变量。这会影响类型转换和推理,从而产生显着的语义差异。

Foo foo()            vs.        Foo foo()
{                               {
                                    Bar bar = expr;
    return expr;                    return bar;
}                               }

答案 2 :(得分:5)

编译器通常足够聪明,可以根据需要优化此类事情。请参阅维基百科上的data-flow optimizations

在这种情况下,即使您没有自己指定结果,也可能需要分配一个临时变量来存储结果。

编辑:Clashsoft关于字节码编译器是正确的:

$ 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
}