与杰克逊的圆形仿制药

时间:2012-12-22 17:14:48

标签: java generics jackson

使用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()方法。

我发现了两种可能导致这种情况发生变化并显示所需行为的变化。第一种是在界面中不使用循环泛型。仅仅删除它就足以防止问题发生。第二种是使用使用mapper.writerWithType(Set.class)创建的显式类型编写器(使用@JsonSerialize注释as似乎不会这样做。后者对我的用例来说并不是一个好的解决方法,除非我能以某种方式弄清楚如何在注释中反映出来。

不完全属于同一类别,但到目前为止我只在R某种形式的java.util.Collection时才看到它。如果我将其声明为class TestSet<E> implements CRDT<Integer, TestSet<E>>则没有错误。

我的问题是:是否存在一些我缺少的基本内容或一些已知的注释方法?

0 个答案:

没有答案