2009-10-22 17 views
5
public Configuration(Node node, File file) { 
    HashMap<String, String> conf = (HashMap<String, String>) SerializationUtils.deserialize(new FileInputStream(file)); 
} 

をデシリアライズするとき、私は理由を理解し、これは危険なキャストの警告を与えるが、何が安全にこれを行うための最善/受け入れの方法ですか?良い方法はありますか?安全でない一般的なキャストコレクション

答えて

2

Java言語のみを使用して、完全に型が安全な方法でこの状況を処理することはできません。

これが繰り返し行われるように、あなたが本当にそれを回避することはできません持っているものですので、私はgenreic方法を使用することをお勧めして汎用オブジェクトを読み、キャストする:

@SuppressWarnings("unchecked") 
public static <T> T readObject(
    ObjectInputStream in 
) throws IOException, ClassNotFoundException { 
    return (T)in.readObject(); 
} 

しかし、私がお勧め有効な警告を抑止するために、このようなメソッドを一般的に使用していないことを確認してください。

+0

これは私が恐れていたものです。/ –

+0

壊れた言語機能の設計のコンテキストでのみ有効な警告です! –

+1

型の消去でなければ、これらのオブジェクトを逆シリアル化できません。私はそれが勝利だと思う。 –

2

あなたは(すなわちString)をチェックしたいコンパイル時の型情報は実行時に使用できないため、これを適切に行うための任意の方法は、(すなわち、キャストが実際に発生した場合には)消去として知られるプロセスを通じて、本当にありません。

Map<?,?> conf = deserialize(rsrc); 
Map<String, String> checked = checkMap(conf, String.class, String.class); 
//can use checked freely 

@SuppressWarnings("unchecked") 
public static <K, V> Map<K,V> checkMap(Map<?,?> map, Class<? extends K> k, Class<? extends V> v) { 
    for (Map.Entry<?, ?> e : map) { 
     k.cast(e.getKey()); //will throw ClassCastException 
     v.cast(e.getValue()); 
    } 
    return (Map<K,V>) map; //unchecked 
} 
+0

誰かが、完全に有効で正しい答えが下落した理由を解明していますか?それは、私が何とか無効で間違った答えを下落させたからですか? –

+0

私はdownvoterではありませんでしたが、これは、例えば、マルチスレッドアクセスの場合にはうまくいかないことがわかります。 1つのスレッドはチェッカーを実行し、別のスレッドはチェックの後に「間違った」タイプを挿入するために元の参照を使用します。ブーム、ClassCastException。 –

+0

@Steven - マルチスレッド環境では「安全ではないかもしれません」と私は思っていません。私は私の答えにもう少し詳細を追加しました。この方法は単にこのように動作するようには設計されておらず、従って平衡のために –

1

以前の回答に構築するには、私は通常、さらに少し行く私は最善の方法は、あなたには、いくつかの特注「チェッカー」を通して、あなたの非直列化されたコレクションを渡すためのものであることを考えます警告を抑制する。私は、抑制の範囲を減らすために、メソッドの代わりに注釈をローカル変数に置きます。これは、誰かが後でメソッドを拡張すると、意図しない抑制がないことを意味します。別のコード行が追加されますが、トレードオフはそれに値すると思います。

public static <T> T readObject(
    ObjectInputStream in 
) throws IOException, ClassNotFoundException { 
    @SuppressWarnings("unchecked") 
    T val = (T)in.readObject(); 
    return val; 
} 

残念ながら、式に注釈を追加することはできません(少なくともまだはありません)。

+0

メソッドの全体が警告を抑制するため、メソッドに注釈を置く傾向があります。 –

関連する問題