6

GuavaTypeTokenクラスを使用して、任意のタイプのインスタンスを他のタイプのオブジェクトに割り当てることができるかどうかをテストしています。

次のコードスニペットでは、Listから割り当て可能であると宣言されたタイプList<String>、およびその逆かどうかをテストしています。

TypeToken rawListType = new TypeToken<List>(){};
TypeToken parameterizedListType = new TypeToken<List<String>>(){};
System.out.println(rawListType.isAssignableFrom(parameterizedListType)); //true
System.out.println(parameterizedListType.isAssignableFrom(rawListType)); //false

以下のコードがコンパイルされるので、 (警告付きで)から割り当てることができるのに、なぜ2番目の呼び出しがisAssignableFrom戻るのですか?:falseList<String>List

List l = null;
List<String> l2 = null;
l = l2; 
l2 = l; //Type Safety Warning 

私の直感では、これらのタイプのインスタンスが警告なしで割り当て可能かどうか(?)、Guavaが答えています。それが正しければ、2番目のコードスニペットに示されているように、(警告の有無にかかわらず)オブジェクトを別のオブジェクトに割り当てることができるコンパイラの意味で割り当て可能性を確認するにはどうすればよいですか?

4

1 に答える 1

3

あなたが言ったように、コンパイラーはジェネリック型を生の型から割り当てることを許可することを知っていますが、それは割り当て可能性を意味するものではありません。コンパイラーは暗黙のチェックされていないキャストを実行しています(したがって警告)。

対応するrawタイプの割り当て可能性を本当に確認したいので、を使用TypeToken.getRawTypeしてから使用することができますClass.isAssignableFrom

編集:あなたが指摘したように、この方法論は数えられ、お互いに割り当て可能ですList<Integer>List<String>それを回避するには、より一般化されたソリューションが必要だと思います。

boolean checkRawAssignability(TypeToken<?> assigned, TypeToken<?> from) {

    //if from is a raw type, compare raw types instead
    final Type fromType = from.getType();
    if (fromType instanceof Class<?>) {
        return assigned.getRawType().isAssignableFrom((Class<?>)fromType);
    }

    //otherwise use normal methodology
    return assigned.isAssignableFrom(from);
}

このソリューションは配列型を考慮しないことに注意してください。

于 2013-02-24T18:27:08.290 に答える