文字列にswitch文が使えないのはなぜですか? 質問する

文字列にswitch文が使えないのはなぜですか? 質問する

この機能は、今後の Java バージョンに組み込まれる予定ですか?

switchJava のステートメントが技術的に機能する理由など、なぜこれができないのかを誰か説明してもらえますか?

ベストアンサー1

ケース付きスイッチ文がString実装されましたJava SE 716歳以上最初にリクエストされた後。遅延の明確な理由は明らかにされていないが、パフォーマンスに関係している可能性が高い。

JDK 7での実装

この機能は現在、javac 「脱糖」プロセスを経て;String宣言で定数を使用するクリーンな高レベルの構文は、caseコンパイル時にパターンに従ってより複雑なコードに拡張されます。結果として得られるコードは、常に存在する JVM 命令を使用します。

switchコンパイル時に、case付きのはString2 つのスイッチに変換されます。最初のスイッチは、各文字列を一意の整数 (元のスイッチ内の位置) にマップします。これは、最初にラベルのハッシュ コードをオンにすることで行われます。対応する case は、if文字列の等価性をテストするステートメントです。ハッシュに衝突がある場合、テストはカスケード になりますif-else-if。2 番目のスイッチは、元のソース コードのそれをミラーリングしますが、case ラベルを対応する位置に置き換えます。この 2 段階のプロセスにより、元のスイッチのフロー制御を簡単に保持できます。

JVM のスイッチ

のより技術的な詳細についてはswitch、JVM仕様を参照してください。switch文のコンパイルについて説明します。簡単に言うと、ケースで使用される定数のスパース性に応じて、スイッチに使用できる 2 つの異なる JVM 命令があります。どちらも、効率的に実行するために、各ケースに整数定数を使用することに依存しています。

定数が密な場合、それらは(最小値を減算した後)命令ポインターのテーブル(命令)へのインデックスとして使用されますtableswitch

定数がまばらな場合は、正しいケース(lookupswitch命令)のバイナリ検索が実行されます。

switchオブジェクトで をデシュガーリングする場合String、両方の命令が使用される可能性があります。 は、lookupswitchケースの元の位置を見つけるためのハッシュ コードの最初のスイッチに適しています。 結果として得られる序数は に自然に適合しますtableswitch

どちらの命令も、各ケースに割り当てられた整数定数をコンパイル時にソートする必要があります。実行時には、O(1)のパフォーマンスはのパフォーマンスtableswitchよりも一般的に優れているように見えますが、テーブルが空間と時間のトレードオフを正当化するのに十分な密度であるかどうかを判断するには、ある程度の分析が必要です。Bill Venners は次のように書いていますO(log(n))lookupswitch素晴らしい記事では、この点についてさらに詳しく説明するとともに、他の Java フロー制御命令の内部についても説明します。

JDK 7以前

JDK 7より前では、ベースのスイッチenumを近似できましたString。これは、静的valueOfコンパイラによってすべてのenum型に対して生成されるメソッド。例:

Pill p = Pill.valueOf(str);
switch(p) {
  case RED:  pop();  break;
  case BLUE: push(); break;
}

おすすめ記事