2017-04-19 11 views
1

これはJava map with values limited by key's type parameterの拡張です。しかし、私はを格納するためにMapを使用しようとしています。Java - タイプセーフな異種コンテナパターンを格納する関数

private static Map<Class<?>, Function<?, JSONObject>> serializers = new HashMap<>(); 

private static <T> void addSerializer(Class<T> klass, Function<T, JSONObject> fn) { 
    serializers.put(klass, fn); 
} 

private static <T> Function<T, JSONObject> getSerializer(Class<T> klass) { 
    return (Function<T, JSONObject>) serializers.get(klass); 
} 

static { 
    // add entries with addSerializer 
} 

public static JSONObject serialize(Object object) { 
    Class<?> klass = object.getClass(); 

    return serializers.get(klass).apply(klass.cast(object)); 
} 

私は、リンクされたSOの質問で説明したパターンに従ったが、私はMapに保存されているFunctionためapplyメソッドを呼び出すようにしようとしています最後の行、上の問題に実行しています。

私は取得していますエラーメッセージが

The method apply(capture#6-of ?) in the type Function<capture#6-of ?,JSONObject> is not applicable for the arguments (capture#7-of ?) 

ですが、私はこれを回避するために何かできることはありますか、私は同じ目標を達成するために使用できる別の構造がありますか?ここ

+0

私は2つのタイプの疑いがありますか?同じものとみなされています。同じ地点でジェネリックを定義する代わりに、関数を定義する別のクラスを作成したいと思うかもしれません。 – Jason

答えて

0

コンパイラはklassobject -s種類を表すClassであることを知らせるためにいくつかの魔法である:

public static JSONObject serialize(Object object) { 
    Class cls = object.getClass(); 
    return serialize(cls, cls.cast(object)); 
} 

private static <T> JSONObject serialize(Class<T> klass, T object) { 
    return getSerializer(klass).apply(object); 
} 

最初serializeメソッドがクラスを検索(またはNullPointerExceptionをスロー)、オブジェクトをキャストそれ自身の型に変換し、次に第2のserializeメソッドを呼び出します。現在、2番目のserializeメソッドは独自の型パラメータTを持っていますので、Function.applyを安全に呼び出すことができます。

残念ながら、klassランタイムタイプのトークンが実際のオブジェクトに属するトークンであることをコンパイラに知らせるには、この種の間接参照が必要です。

関連する問題