Jackson 2.1.2(com.fasterxml.jackson
パッケージ)を使用し@JsonValue
て、関連するサブクラスとは異なるタイプの可能性がある共通インターフェースを定義しようとしていますが、インターフェースのジェネリックが循環している場合でも、循環している場合でも問題が発生します。ジェネリックは、実装クラスで直接使用されません。
私は次のようなインターフェースを持っています:
public interface C<S, R extends C<S,R>> {
}
(メソッドはありますが、ここでの目的には重要ではないことがわかります)。
public class TestSet<E> extends ForwardingSet<E> implements
C<Set<E>, TestSet<E>> {
@JsonIgnore
private final Set<E> delegate = Sets.newLinkedHashSet();
@Override
protected Set<E> delegate() {
return delegate;
}
@JsonValue
public Set<E> view() {
return delegate;
}
}
次のテストケースを実行しようとすると、次のようになります。
@Test
public void test() throws Exception {
TestSet<String> tst = new TestSet<String>();
tst.add("one");
System.out.println(mapper.writeValueAsString(tst));
}
:を生成しjava.lang.StackOverflowError
ます
java.lang.StackOverflowError
at java.lang.Class.getDeclaringClass(Native Method)
at com.fasterxml.jackson.databind.type.TypeBindings._resolveBindings(TypeBindings.java:269)
at com.fasterxml.jackson.databind.type.TypeBindings._resolve(TypeBindings.java:203)
at com.fasterxml.jackson.databind.type.TypeBindings.findType(TypeBindings.java:121)
at com.fasterxml.jackson.databind.type.TypeFactory._fromVariable(TypeFactory.java:807)
at ...
調査の結果、このシナリオではview()メソッドが呼び出されないことがわかりました。
これが起こらないようにし、望ましい動作を示す2つの可能な変更を見つけました。1つは、インターフェイスで循環ジェネリックを使用しないことです。問題が発生しないようにするには、単に削除するだけで十分です。2つ目は、で作成された明示的に型指定されたライターを使用することですmapper.writerWithType(Set.class)
(@JsonSerialize
注釈を使用as
すると、それを実行するようには見えません)。後者は、アノテーションに反映する方法をどうにかして理解できない限り、私のユースケースにとって実際には良い回避策ではありません。
R
まったく同じカテゴリではありませんが、これまでのところ、が何らかの形である場合にのみ見ましたjava.util.Collection
。class TestSet<E> implements CRDT<Integer, TestSet<E>>
エラーがないので宣言すれば。
私が持っている質問は次のとおりです。私が見逃している基本的な何か、または注釈を使用してこれを行うための既知の方法はありますか?