19

名前を定数として使用する Javaswitchステートメントを使用したいと思います。なんとなく可能ですか?または、クラス名を複製する必要がありますか?classcase

コンパイラ エラーのため、次のコードは機能しません。

ケース式は定数式でなければなりません

String tableName = "MyClass1";

...

switch (tableName) {
case MyClass1.class.getSimpleName():
    return 1;
case MyClass2.class.getSimpleName():
    return 2;
default:
    return Integer.MAX_VALUE;
}

この問題のオンライン デモンストレーションを次に示します ( openjdk 1.8.0_45): http://goo.gl/KvsR6u

4

3 に答える 3

13

コンパイラエラーはすでにそれを言っています。ケース ラベルは定数式である必要があり、クラス リテラルもgetSimpleName()それらを呼び出した結果も定数式ではありません。

実用的な解決策は次のとおりです。

String tableName = "MyClass1";
...
switch (tableName) {
    case "MyClass1":
        return 1;
    case "MyClass2":
        return 2;
    default:
        return Integer.MAX_VALUE;
}

MyClass1.class.getSimpleName()は よりも単純ではありませんが、もちろん、名前が既存のクラスと一致するかどうか、およびリファクタリング ツールまたは難読化ツールがクラスと文字列リテラル"MyClass1"の関係に気付かないかどうかのコンパイル時のチェックはありません。MyClass1"MyClass1"

それに対する解決策はありません。問題を軽減するためにできる唯一のことは、関連するクラス内でキーを宣言して関係を文書化することです。

class MyClass1 {
    static final String IDENTIFIER = "MyClass1";
    ...
}
class MyClass2 {
    static final String IDENTIFIER = "MyClass2";
    ...
}
...
String tableName = MyClass1.IDENTIFIER;
...
switch (tableName) {
    case MyClass1.IDENTIFIER:
        return 1;
    case MyClass2.IDENTIFIER:
        return 2;
    default:
        return Integer.MAX_VALUE;
}

これはリーダーとの関係を文書化しますが、ツールは実際の文字列の内容がクラス名と一致することを保証しません。ただし、何を実現したいかによっては、文字列の内容がクラス名と一致するかどうかは、もはや無関係になる可能性があります…</p>

于 2016-01-05T15:59:05.203 に答える
8

スイッチを使用する代わりに、マッピングをマップに保存してみませんか?

String から Integer へのマップを作成し、すべてのクラス名をそれらの戻り値にマップします。

要求時に、エントリが存在しない場合は、デフォルト値を返します。それ以外の場合は、マップ内の値を返します。

于 2016-01-05T13:54:30.570 に答える