4

Java は通常、Genericsコンパイル時にデータを消去しますが、その情報を取得する可能性があります (JacksonObjectMapperはそれをかなりうまく行っています)。

私の問題: リストのプロパティを持つクラスがあります:

public class User {
    public List<Long> listProp;//it is public only to keep the example simple
}

クラスのインスタンス (User.class) とプロパティ名 (listProp)を持つ正しいリスト型にプログラムで JSON 文字列をマップできるように、正しいTypeReference(または?) を取得するにはどうすればよいですか? 私が意味するのはこれです:JavaTypeClass

TypeReference typeReference = ...;//how to get the typeReference?
List<Long> correctList = om.readValue(jsonEntry.getValue(), typeReference);//this should return a List<Long> and not eg. a List<Integer>
4

3 に答える 3

5

マッパーのconstructTypeメソッドを試しましたか?

Type genericType = User.class.getField("listProp").getGenericType();
List<Long> correctList = om.readValue(jsonEntry.getValue(), om.constructType(genericType));
于 2013-07-10T11:40:09.210 に答える
4

ジャクソンは TypeReference を使用してジェネリック型を構築します

TypeReference typeReference =new TypeReference<List<Long>>(){}

jackson は JavaType を使用してジェネリック型を構築します

JavaType jt = om.getTypeFactory().constructArrayType(Long.class);

ジャクソンサポート3種類

  1. クラス
  2. Java タイプ
  3. TypeReference

私はJavaTypeを使用するのが好きです。ジェネリック型の方がより明確で、通常のオブジェクトの使用クラス

于 2014-12-24T07:17:32.613 に答える
0

おそらく、ジェネリック型を逆シリアル化するためのそれほど風変わりでないアプローチは、具象型内にラップすることです。

class ListLongWrapper extends ArrayList<Long> {} // package scope
... or ...
static class ListLongWrapper extends ArrayList<Long> {} // class scope

それから

String jsonStr = objMapper.writeValueAsString(user1.listProp); // serialize
user2.listProp = objMapper.readValue(jsonStr,ListLongWrapper.class); // deserialize

interface の代わりにextendsクラス型 (ここでは を使用) が必要であることに注意してください。ArrayListList


これは、指定された例に対するさらに直接的なアプローチを示唆しています --Userはすでにラッパーです (そしてlistPropですpublic):

public class User {
    public List<Long> listProp;
}

それから

String jsonStr = objMapper.writeValueAsString(user1); // serialize
var user2 = objMapper.readValue(jsonStr,User.class); // deserialize

この場合、インターフェイスListをラッピング クラス内のフィールド タイプとしてそのまま使用できますが、これは、Jackson が使用する具体的なタイプを制御できないことを意味します。

于 2020-04-13T20:43:12.010 に答える