使用getter/setter实现嵌套抽象类

4
我有以下抽象类结构:

public abstract class A {
    ...
    private List<B> b;

    public List<B> getB() {
        return b;
    }
    public void setB(List<B> b) {
        this.b = b;
    }
    public static abstract class B {

    }
}

然后像这样实现:

public class AA extends A {
    public static class BB extends B {
        ...
    }

当我现在使用jackson将Json映射到AA时,我会得到一个错误,它无法创建A $ B的实例。我认为这是因为A中的getter/setter仍然引用B而不是BB,这导致了错误。有没有办法可以这样做,而不必在子类中也放置getter/setter?

我认为对于内部类,你应该以静态方式调用它 A.B - Rookie007
3个回答

2
您可以添加类型捕获,以确保 b 始终正确地被输入类型,如下所示:
public abstract class A<T extends A.B> {
    ...
    private List<T> b;

    public List<T> getB() {
        return b;
    }
    public void setB(List<T> b) {
        this.b = b;
    }
    public static abstract class B {
        ...
    }
}

然后

public class AA extends A<AA.BB> {
    ...
    public static class BB extends B {
        ...
    }

我试过了,它按照预期为我工作。这就是我一直在寻找的解决方案。使用public class AA extends A<AA.bb>并没有造成任何编译错误。 - j0h4nn3s

1
有几种反序列化的选项。如果没有注释,Jackson 可能会回退到使用最近的超类的构造函数,该构造函数具有无参数的公共构造函数。创建空对象后,它使用反射设置字段。
反射将绕过构造函数中的任何验证,如Objects.requireNotNull
更精细的使用 Jackson 的方法是在构造函数中使用 @JsonCreator@JsonProperty,命名所有参数。
这使您可以强制 Jackson 使用您创建的构造函数并验证对象。
我对这种相当不寻常的结构感到非常不确定。毕竟,您在一个抽象类中嵌套了一个抽象类,我见过很多东西,但我没有看到过这样的东西。有好的理由吗?或者将内部类移动到自己的文件中是否没有问题?(它是public static

实际上,由于它是一个公共静态类,它就像是两个不同的类,只是代码位置的问题。 - Carlo Moretti
是的,它们很可能相互独立。将其移至外部将消除至少一些问题。 - Vlasec
一开始我并不想使用注解,因为它可以在没有注解的情况下工作,并且对我来说似乎更容易。将内部类移动到自己的文件中没有什么好的理由,只是想尽可能地让Java类保持与JSON结构的接近。 - j0h4nn3s
另外,你确定你永远不需要在其他类中重新使用 BB 吗?如果例如 CC 返回 AA.BB,那么这是相当奇怪的,如果你有一个 CC.BB 类是复制粘贴的代码,那就更糟了。 - Vlasec
或者,想象一下有多个级别的JSON。你会使用AA.BB.CC吗?在我工作的产品中,我们有相当简单的JSON消息,但是仍然通过一些封装轻松地达到了四个级别。为每个类创建一个单独的文件和良好的包结构使得维护变得更加容易。 - Vlasec

0
如果您创建一个 AA 的实例,您需要一个抽象类 B 的实例,并且您没有定义使用哪个实例。仅提供一些实现 (BB) 是不够的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接