0

Java アプリケーションが奇妙な動作を示しており、解決策を見つけるのに苦労しています。

このコード スニペットはLinkedHashMap、キーと値の両方が型である a の内容を取得Stringし、それらをテキスト ファイルに書き込みます。configWriterタイプPrintWriterです。

for (Map.Entry<String, String> entry : configMap.entireSet()) {

    configWriter.println(entry.getKey() + "=" + entry.getValue());
}

マップは次のように宣言されました。

LinkedHashMap<String, String> configMap = new LinkedHashMap<String, String>();

Scannerこれは、クラスを使用してテキスト ファイルからトークンを読み取ることによって生成されます。

マップ内の値の 1 つは、String数値 (整数) のみを含む ですが、ループがこの値に到達すると、 from から にキャストできないというメッセージがスローされClassCastExceptionます。これは完全に理にかなっていますが、値の型は String です。IntegerString

Javaにこの値を強制的に保持させる方法はありStringますか?

4

2 に答える 2

7

rawtypeがどこかで使用さIntegerれており、マップに忍び込んでいることはほぼ確実です。

マップのどこIntegerに挿入されているかを特定する最も簡単な方法は、の初期化をに置き換えることですconfigMap

Map<String, String> configMap = Collections.checkedMap(
  new LinkedHashMap<String, String>(), String.class, String.class);

マップにa以外のものStringが挿入された場合、実際には例外がスローされます。私はそれを本番コードで個人的に使用することはありませんが、これはおそらくバグを「消し去る」ための最も簡単な方法です。Integer正確に挿入されている場所の例外とスタックトレースが表示されます。

現状では、型消去を使用してジェネリックを実装する方法は、非値がマップに挿入されるのを実際に阻止するものが何もないことを意味します。Stringコンパイラはそれを防ぐためにいくらかの努力をしますが、rawtypesとレガシーコードはそれを回避することができます。ただし、を使用Collections.checkedMapすると問題が発生します。

于 2012-06-14T02:30:52.820 に答える
2

Louis Wasserman が、あなたの問題の考えられる原因を説明しました。

あなたの質問の考え方にはいくつかの欠陥があることを指摘したいだけです。

LinkedHashMapの読み取り時にJavaが文字列から整数に自動的にキャストするのはなぜですか

Stringまず、 aから an にキャストできませんInteger。Java 参照型では、オブジェクトがその型のインスタンスまたはその型のサブタイプである場合にのみ、オブジェクトをその型にキャストできます。型はのStringサブタイプではないIntegerため、JVM の操作上のセマンティクスにより、このようなキャストは禁止されています。これを実行しようとするコンパイル可能なコードを記述した場合、実行時例外が発生します。

第二に、LinkedHashMap... または他のコレクション クラスには、要素/キー/値のインスタンスを、指示せずにからに変換するものは何もありません。行儀の良い (Java) API は、そのようなことはしません。StringInteger

Louis の診断に戻ります。何か (コードなど) がそのIntegerオブジェクトを値として追加しました。生の型を使用したり、「未チェックの変換」警告を抑制/無視したりすると、このようなことが起こります。

于 2012-06-14T02:49:08.823 に答える