1

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.Collectionclass TestSet<E> implements CRDT<Integer, TestSet<E>>エラーがないので宣言すれば。

私が持っている質問は次のとおりです。私が見逃している基本的な何か、または注釈を使用してこれを行うための既知の方法はありますか?

4

0 に答える 0