17

ループ内で変数を宣言するのは悪い習慣ですか?以下の最初のコードブロックに見られるように、そうすると、ループの各反復で新しい文字列が作成されるため、2番目のメモリの10倍のメモリが使用されるように思われます。これは正しいです?

for (int i = 0; i < 10; i++) {
  String str = "Some string";
}

対。

String str;
for (int i = 0; i < 10; i++) {
  str = "Some String";
}
4

5 に答える 5

26

ループ内で変数を宣言するのは悪い習慣ですか?

全くない!変数をその使用場所にローカライズします。

以下の最初のコードブロックに見られるように、そうすることで、2番目のメモリの10倍のメモリを使用するように思われます。

コンパイラは、メモリの使用効率を維持するために物事を最適化する場合があります。final参考までに:キーワードを使用して、変数にオブジェクトへの固定参照があることを伝えると、それを助けることができます。

注:コンストラクターで複雑なコードを実行している、より複雑なオブジェクトがある場合は、単一の実行と複数の実行について心配し、ループの外側でオブジェクトを宣言する必要があります。

于 2010-12-21T16:29:29.653 に答える
7

どちらの例でも、文字列「SomeString」を同じ回数含む新しい文字列オブジェクトをインスタンス化します。

ループ内で宣言する最初の例ではstr、forループの完了後にその文字列へのすべての参照が失われ、Javaのガベージコレクターが文字列のすべてのインスタンスをメモリから削除できるようになります。ただし、ループの外側で宣言する2番目の例ではstr、最後に作成した文字列にはループの外側での参照が含まれ、Javaのガベージコレクターは、インスタンス化された文字列のうち10個のうち9個のみをメモリから削除します。

そのため、文字列の参照を保持せず、ガベージコレクタがまだ使用されているかどうかを判断する機能を妨げるため、最初の方法の方が適しています。

于 2010-12-21T16:33:02.530 に答える
2

@Jason Sが言ったこと以外に、コードの読みやすさについても考えることをお勧めします。

たとえば、参照に1回だけ書き込む場合は、次のようなものを使用する意図がより明確になります。

String str = "write once";
while(condition){
    //do stuff with str
}

対:

String str = null;
while(condition){
    str = "write once";
    //do stuff with str
}

同様に、文字列の値が実際にループの反復に固有のものに基づいている場合は、ループ内で変数を宣言します。

于 2010-12-21T16:36:02.193 に答える
1

変数参照で使用されるメモリは小さいです。アイテムは使用場所に近く、読みやすくなるため、通常はループ内でアイテムを宣言することをお勧めします。

于 2010-12-21T16:30:20.227 に答える
0

場合によります。非効率性は、コンパイラが何も変更しないと仮定して、Stringオブジェクトを作成するオーバーヘッドに起因します。スコープ外になると、メモリはクリアされます。

于 2010-12-21T16:31:25.260 に答える