1. ホーム
  2. java

[解決済み] Javaスイッチにおける変数の宣言と初期化

2022-11-20 04:35:55

質問

Javaスイッチについて、おかしな質問があります。

int key = 2;

switch (key) {
    case 1:
        int value = 1;
        break;
    case 2:
        value = 2;
        System.out.println(value);
        break;
    default:
        break;
}

シナリオ1 key が 2 の場合、値を 2 として正常に表示します。

シナリオ2 - 私がコメントするとき value = 2case 2: という鳴き声がします。 ローカル変数の値が初期化されていない可能性があります。 .

質問です。



シナリオ1:もし実行フローが case 1: に行かない場合(その時 key = 2 のように)、ではどうやって値変数の型を知るのでしょうか? int ?



シナリオ 2 : もしコンパイラが値変数の型として int という型がわかっている場合、コンパイラはその型にアクセスするために int value = 1; の式にアクセスしなければなりません。 case 1: .宣言と初期化)。では、なぜsqawrkするのかというと、コメントするときに value = 2case 2: を言うと、その ローカル変数の値が初期化されていない可能性があります。 .

どのように解決するのですか?

Switch文は、基本的にスコープがおかしいです。から セクション 6.3 の :

ブロック内の局所変数宣言のスコープ (§14.4) は、宣言が現れたブロックの残りの部分であり、それ自身のイニシャライザから始まり、局所変数宣言文の右側にあるさらなる宣言子も含まれます。

あなたの場合 case 2 が同じ ブロック として case 1 の後に表示され、たとえ case 1 は決して実行されないのに、その後に表示されます。したがって、ローカル変数はスコープ内で 書き込み 宣言は論理的に決して実行されないにもかかわらずです。(初期化はそうですが、宣言は実際には "実行可能" ではありません)。

をコメントアウトすると value = 2; をコメントアウトしても、コンパイラはどの変数を参照しているかを知っていますが、それに値を割り当てる実行パスを通過していないため、他の定義されていないローカル変数を読もうとしたときと同じようにエラーが発生します。

私が強くお勧めするのは ではなく で宣言されたローカル変数を使用しないことを強くお勧めします。私が switch 文でローカル変数を導入する場合 (これはめったに行わないようにしています。case は非常に短いのが理想的です)、通常は新しいスコープを導入することを好みます。

case 1: {
    int value = 1;
    ...
    break;
}
case 2: {
    int value = 2;
    ...
    break;
}

この方がわかりやすいと思います。