2

確かに、私はこれらすべてのJavaにまったく慣れていないので、質問があります。WCFサービスで取得した応答を逆シリアル化しようとしていますが、すべて正常に機能しますが、これを行うための汎用関数を作成しようとしています。 。

基本的に私がしていることは

public List<msg> GetService(String method){
    List<msg> response = new ArrayList<msg>();

    Type msgType = new TypeToken<List<msg>>(){}.getType();

    //Obtaining result
    response = uJSON.fromJson(serviceResponse, msgType);
    //uJSON is an instance of Gson library, for deserializing it just needs
    //the service response and a Class<T> or Type to reflect the obtained message
}

私がやろうとしているのは、Type "msg"ジェネリックを取得することです。つまり、...

public <thing> void GetInstanceService(String method){
     List<thing> response = new ArrayList<thing>();

     Type rType2 = new TypeToken<List<thing>>(){}.getType(); //Got java.util.List<thing>

     //And when I'm trying to deserialize I just obtain a List of object 
     //[java.lang.Object@5c7a987e, java.lang.Object@74b1a7a0]

     type2 = uJSON.fromJson(new String(entity), rType2);
}

しかし、私はこのように呼んでいます。

comm.<msgType>GetInstanceService("listTestType");

したがって、「GetInstanceService」を呼び出すと、「thing」は「msgType」タイプに なります。また、応答は?の代わりにList<thing>すべきではありません。List<msgType>List <Object>

さらに、「Type」パラメータを介して型を明示的に渡そうとすると、このようなコンパイル時エラーが発生します。

public void GetInstanceService(Type type){
    List<type> type2 = new ArrayList<type>();  //Compilation time error

    //Or
    msgType oType = new msgType();
    Class classType = oType.getClass();
    List<classType> type3;    //Compilation time error
}

それで、これらの試みのどれも効果的でなかった場合、どうすれば逆シリアル化のタイプを設定できますか?

4

2 に答える 2

3

Guava クラスTypeTokenは、その使用モードをサポートしていません。型変数を使用して型トークンを作成していますが、から再構築するための十分な情報がありませList<String>List<T>TypeToken必要なすべてのコンパイル時の情報がある場所のインスタンスを作成する必要があります。

ドキュメントには次のように記載されています。

実際の型引数がサブクラスによって運ばれることが重要であることに注意してください。次のコードは、メソッド シグネチャの<T> 型変数のみをキャプチャするため、間違っています。listType()while<String>は消去で失われます:

class Util {
  static <T> TypeToken<List<T>> listType() {
    return new TypeToken<List<T>>() {};
  }
}

TypeToken<List<String>> stringListType = Util.<String>listType();

ただし、上記のように、TypeTokenすべての型情報が利用可能な at call-site をインスタンス化し、それをパラメーターとして渡すことができます。このようなもの:

public <thing> void GetInstanceService(String method, TypeToken<List<thing>> token){
     List<thing> response = new ArrayList<thing>();

     Type rType2 = token.getType();

     type2 = uJSON.fromJson(new String(entity), rType2);
}

comm.GetInstanceService("listTestType", new TypeToken<List<msgType>>() {});

アップデート

Paul Bellora は、 parameter を受け入れて、そこからメソッド内でTypeToken<thing> tokena を構築することもできると述べています。TypeToken<List<thing>>token

public <thing> void GetInstanceService(String method, TypeToken<thing> token) {
     List<thing> response = new ArrayList<thing>();

     Type rType2 = new TypeToken<List<thing>>() {}
         .where(new TypeParameter<thing>() {}, token); // where() binds "thing" to token
         .getType();

     type2 = uJSON.fromJson(new String(entity), rType2);
}

comm.GetInstanceService("listTestType", new TypeToken<msgType>() {});
于 2012-12-30T22:00:11.960 に答える
2

type eraserと呼ばれるものが原因で、必要なクラス オブジェクトが実行時に利用できません。

ただし、標準的な回避策があります。次のように、型トークンをメソッドに渡します。

public <T> List<T> getService(String method, Class<T> c) {
    // the caller has passed in the class object
    List<T> list = new ArrayList<T>();
    // fill list
    return list;
}
于 2012-12-30T21:29:55.067 に答える