web-dev-qa-db-ja.com

returnステートメントの前のローカル変数、それは重要ですか?

これが初心者の質問である場合は申し訳ありませんが、これに対する答えが見つかりませんでした。これを行う方が良いですか:

int result = number/number2;
return result;

または:

return number/number2;

整数がメモリを使用することを知っているので、パフォーマンスがわずかに低下すると思いますか?しかし一方で、特にint/stringが長い計算である場合は、内容がより明確になります。

21
SJ19

実際には、PMDから継承された戻る前に不要なローカルというSonarQubeルールがあります。それは言う:

ローカル変数を不必要に作成することは避けてください。

このルールは 後で置き換えられました SSLRルール変数を宣言してすぐに返されたりスローされたりしないでください、これは同じを維持しますポジション:

変数をすぐに返すかスローするためだけに変数を宣言することは、悪い習慣です。一部の開発者は、この方法により、返されるものに明示的に名前を付けることができるため、コードの可読性が向上すると主張しています。ただし、この変数は内部実装の詳細であり、メソッドの呼び出し元には公開されません。 メソッド名は、呼び出し元が何が返されるかを正確に知るのに十分である必要があります

そして、私はそれに完全に同意します。

IntelliJ(または少なくともAndroid Studio)にも、この状況に対する警告があります。

変数は次のリターンでのみ使用され、インライン化できます

この検査では、次の戻り値でのみ使用されるローカル変数、または他の変数の正確なコピーが報告されます。どちらの場合も、そのような変数をインライン化することをお勧めします。


このような状況では、パフォーマンスはまったく心配する必要はないと思います。そうは言っても、@ Clashsoftが彼のコメントで述べたように、JITはおそらく変数をインライン化し、どちらの方法でも同じ結果になります。

22

あなたより読みやすいと思うバージョンを選択してください。

名前付き変数が読みやすさを向上させる正当なケースがあります。例えば

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

コンパイラは通常、この種のものを適切に最適化するのに十分賢いです。ウィキペディアの データフローの最適化 を参照してください。

この場合、自分で指定しなくても、結果を格納するために一時変数を割り当てる必要があります。

編集: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
}
5
Vlad