これは、 SunのJavaチュートリアルからの抜粋です。
スイッチは、、、、
byteおよびプリミティブデータ型shortで機能します。また、列挙型(クラスと継承で説明)および特定のプリミティブ型を「ラップ」するいくつかの特別なクラス(、、、、および(単純データオブジェクトで説明))でも機能します。charintCharacterByteShortInteger
longプリミティブデータ型が許可されないのには十分な理由があるはずです。誰もがそれが何であるか知っていますか?
これは、 SunのJavaチュートリアルからの抜粋です。
スイッチは、、、、
byteおよびプリミティブデータ型shortで機能します。また、列挙型(クラスと継承で説明)および特定のプリミティブ型を「ラップ」するいくつかの特別なクラス(、、、、および(単純データオブジェクトで説明))でも機能します。charintCharacterByteShortInteger
longプリミティブデータ型が許可されないのには十分な理由があるはずです。誰もがそれが何であるか知っていますか?
ある程度、スイッチの典型的な使用法に基づく恣意的な決定だったと思います。
スイッチは基本的に2つの方法(または原則として組み合わせ)で実装できます。少数のケース、または値が広く分散しているケースの場合、スイッチは基本的に一時変数の一連のifと同等になります(オンになっている値は一度だけ評価する必要があります)。値がほぼ連続している適度な数のケースでは、スイッチテーブルが使用され(JavaのTABLESWITCH命令)、ジャンプ先の場所がテーブル内で効果的に検索されます。
これらの方法のいずれも、原則として整数ではなく長い値を使用できます。しかし、命令セットとコンパイラの複雑さと実際のニーズのバランスをとるのは、おそらく実際的な決定だったと思います。本当に長い間切り替える必要がある場合は、次のように書き直さなければならないほどまれです。一連のIFステートメント、または他の方法で回避します(問題の長い値が互いに近い場合は、Javaコードで最小値を減算した結果を切り替えることができます)。
彼らはバイトコードに必要な命令を実装していなかったので、コードがどれほど「本番環境に対応」していても、それほど多くのケースを書きたくないのです...
[編集:この回答へのコメントから抽出し、背景にいくつかの追加を加えた]
正確には、2³²は多くの場合であり、それ以上を保持するのに十分な長さのメソッドを持つプログラムは、まったく恐ろしいものになります。任意の言語で。(どの言語のどのコードでも、私が知っている最長の関数は6k SLOCを少し超えています-はい、それは大きいです-switchそしてそれは本当に管理不能です。)次に、2つの実際の選択肢があります。longint
をに圧縮するには、ハッシュ関数をテーマにしたいくつかのバリアントを使用longしintます。タイプを間違えた場合にのみ使用する最も簡単な方法は、キャストすることです。これを行うと、より便利になります。
(int) ((x&0xFFFFFFFF) ^ ((x >>> 32) & 0xFFFFFFFF))
結果をオンにする前に。テスト対象のケースを変換する方法も検討する必要があります。しかし、実際には、それは多くの場合の本当の問題に対処していないので、それでも恐ろしいです。
非常に多くのケースで作業している場合のはるかに優れた解決策はMap<Long,Runnable>、特定の値をディスパッチする方法を調べているように、または類似のものを使用するように設計を変更することです。これにより、ケースを複数のファイルに分割できます。これにより、ケース数が多くなると管理がはるかに簡単になりますが、関連する実装クラスのホストの登録を整理するのはより複雑になります(注釈を付けると役立つ場合があります)登録コードを自動的に作成します)。
FWIW、私はこれを何年も前に(プロジェクトの途中で新しくリリースされたJ2SE 1.2に切り替えました)、超並列ハードウェアをシミュレートするためのカスタムバイトコードエンジンを構築しました(いいえ、JVMの再利用は根本的に適切ではなかったでしょう)さまざまな値と実行モデルが関係しています) switch、Cバージョンのコードが使用していたビッグに比べてコードが大幅に簡素化されました。
持ち帰りのメッセージを繰り返すと、switchaをオンにしたいというlongことは、プログラムのタイプが間違っているか、クラスを使用する必要があるほど多くのバリエーションを含むシステムを構築していることを示しています。どちらの場合も、再考する時が来ました。
ルックアップテーブルのインデックスは32ビットでなければならないためです。
長い32ビットアーキテクチャでは、2つの単語で表されます。ここで、同期が不十分なために、switchステートメントの実行で、ある書き込みからの上位32ビットと、別の書き込みからの下位32ビットのlongが観測された場合に何が起こるか想像してみてください。それはどこに行こうとするかもしれません....誰がどこを知っていますか!基本的にどこかランダム。両方の書き込みがswitchステートメントの有効なケースを表していたとしても、それらの面白い組み合わせはおそらく最初のケースにも2番目のケースにもつながりません。さらに悪いことに、別の有効な、しかし無関係なケースにつながる可能性があります。
少なくともint(またはそれ以下の型)では、どんなにひどく混乱しても、switchステートメントは、「空中」の値ではなく、少なくとも誰かが実際に書いた値を読み取ります。
もちろん、実際の理由はわかりませんが(15年以上経ちますが、それほど長い間注意を払っていませんでした!)、そのような構造がどれほど危険で予測不可能であるかを理解すれば、同意するでしょう。これは、longをオンにしないという非常に良い理由です(そして、しゃれが意図されている限り、32ビットマシンが存在するので、この理由は引き続き有効です)。