3

公式のJavaチュートリアルに含まれている簡単な「多次元配列で番号を見つける」を書きました。チュートリアルに含まれているコードは次のとおりです。

class LabeledBreak {
    public static void main(String[] args) {
        int [][] numbers = {
            {22, 34, 675, 23, 23},
            {34, 76, 98, 23, 11},
            {65, 234, 87, 23, 76}
        };

        int searchFor = 123;
        boolean found = false;
        int i;
        int j = 0;  // <-- this line

search:
        for (i = 0; i < numbers.length; i++) {
               for (j = 0; j < numbers[i].length; j++) {
                if (searchFor == numbers[i][j]) {
                    found = true;
                    break search;
                }
               }
        }

        if (found == true)
            System.out.println("Found " + searchFor + " at index " + i + ", " + j);
        else
            System.out.println(searchFor + " not found!!!");
    }

ここで「j」を初期化する意味がわかりませんでした。初期化ステートメントを削除して、単なる宣言ステートメントにしてみました。しかし、私はそのエラーを受け取りました:

「変数jが初期化されていない可能性があります」

「j」を初期化する必要があるのはなぜですか?「i」も初期化を必要としなかったのはなぜですか?

4

4 に答える 4

11

0 の場合numbers.length、内側のループは実行されjないため、初期化されません。つまり、 statement に到達することはありませんj = 0;

于 2012-09-07T14:52:25.127 に答える
2

これをコメントに収めることができないので、ここにコードを配置しました。

私見では、これらの問題に遭遇しない構造を使用するのが最善です。

FOUND: {
    for (int i = 0; i < numbers.length; i++)
       for (int j = 0; j < numbers[i].length; j++)
            if (searchFor == numbers[i][j]) {
                System.out.println("Found "+searchFor+" at index "+i+", "+j);
                break FOUND;
            }
    System.out.println(searchFor + " not found!!!");
}

変数のスコープは、安全に使用できる場所に限定されます。

于 2012-09-07T14:59:47.983 に答える
1

次のコードを検討してください。

int j = 1234567;
int end = -100;
for (int i = 0; i < end; i++)
    for (j = 0; j < 10; j++)
        System.println("Hello.");
System.println("j is "+j);

のさまざまな値を試してくださいend。出力が であることに注意してください1234567

于 2012-09-07T14:54:47.030 に答える
0

Javaが初期化されていない変数の読み取りを禁止するのはなぜですか?

このようなコード構成は、非決定論的である傾向があるため、デバッグが難しく、信頼性が低くなります。さらに、無差別にスタック メモリを再利用すると、セキュリティ リークが発生する可能性があります。

Java 言語仕様のセクション 16 では、基本的にコード フロー (構文構造) を調べて、変数を「使用前に確実に割り当てる」ものにするものを定義していますが、他の変数の内容がわかっている場合でも無視し、変数に沿って呼び出されている正確なメソッドを無視します。仕方。

しかし、私は常に初期化しますj

そうです。しかし、それを証明するには、 の初期コンテンツを掘り下げnumbers、メソッドがどのように機能するかを理解し、メイン スレッドの実行中に他のスレッドが参照を取得して配列を変更するlength可能性を排除する必要さえあります。numbers

しかし、設定されjたときにコードパスの外にアクセスせずfound、その結果、`j初期化されました。

あなたが言うように。しかし、JLS セクション 16 ではコード構造のみが考慮され、 などの他の変数の値は考慮されませんfound

なぜi違うのですか?

の初期化はi、その本体が (純粋に仮説的に) まったく実行されない場合でも、外側のループで最初に発生することが純粋に構文的に保証されています。

Java コンパイラが十分にスマートで、初期化されていない変数にアクセスしていないことを確認できたらどうなるでしょうか?

これは、JLS セクション 16 に関する限り、何も変更しません。コンパイラは、そのような形式的な初期化子を節約することを許可されていません。これは、プログラムが、同様にスマートではない可能性のある他の Java コンパイラに移植できない可能性があるためです。

于 2012-09-09T19:32:47.797 に答える