【问题标题】:When extending JAXBEqualsStrategy, generated equals is different than when not extending扩展 JAXBEqualsStrategy 时,生成的 equals 与不扩展时不同
【发布时间】:2014-07-26 14:37:38
【问题描述】:

我们通过 pom 扩展 JAXBEqualsStrategy:

<xjcArg>-Xequals-equalsStrategyClass=com.acme.foo.CustomEqualsStrategy</xjcArg>

CustomEqualsStrategy 扩展了 JAXBEqualsStrategy。在 Eclipse (Keplar) 中运行 MAVEN clean install generate-source 后,我们的模型类具有如下 equals 方法:

    public boolean equals(Object object) {
      final EqualsStrategy strategy = new CustomEqualsStrategy();
      return equals(null, null, object, strategy);
    }

而如果我们不扩展 JAXBEqualsStrategy,我们的模型类就会有这样的 equals 方法:

    public boolean equals(Object object) {
      final EqualsStrategy strategy = JAXBEqualsStrategy.INSTANCE;
      return equals(null, null, object, strategy);
}

JAXBEqualsStrategy 有

    public static EqualsStrategy INSTANCE = new JAXBEqualsStrategy();

我们希望得到

    final EqualsStrategy strategy = CustomEqualsStrategy.INSTANCE;

在生成的 equals 方法中并且正在努力完成它。

【问题讨论】:

    标签: java maven xjc jaxb2-basics


    【解决方案1】:

    您确实想使用CustomEqualsStrategy.INSTANCE。使用new CustomEqualsStrategy() 是正确的,应该是首选,除非您有充分的理由不这样做。

    由于CustomEqualsStrategy 扩展了JAXBEqualsStrategy,这意味着除非您在CustomEqualsStrategy 中定义自己的INSTANCE 字段,否则CustomEqualsStrategy.INSTANCEJAXBEqualsStrategy.INSTANCE 相同,这意味着您将使用毕竟JAXBEqualsStrategy

    另外,使用 INSTANCE 这样的字段有效地表明您的类应该用作单例,因此必须是无状态的。大多数类都不是无状态的,即使是无状态的类,许多这样的类也不需要以单例样式使用。

    简而言之,坚持使用new CustomEqualsStrategy()。代码中的惊喜会更少,你会更开心。 (另外,通过阅读JAXBEqualsStrategy 的代码,也许您应该扩展DefaultEqualsStrategy。)

    【讨论】:

    • 非常感谢您的回复。我们从扩展 JAXBEqualsStrategy 的 Apache 的 ElementAwareEqualsStrategy 中得到启发。问题是调用 equals 会(不必要地?)实例化一个新的 CustomEqualsStrategy。
    • 我认为让策略类完全无状态、可重新输入和单例没有问题。另一方面,在很多情况下,equals 和 hashCode 必须非常快,因此避免创建新的策略实例可能是一个非常好的主意。
    【解决方案2】:

    免责声明:插件作者在这里。

    实际上,您也可以生成 .INSTANCE 或 .getInstance() 调用。请看这段代码:

    https://svn.java.net/svn/jaxb2-commons~svn/basics/trunk/basic/src/main/java/org/jvnet/jaxb2_commons/plugin/util/StrategyClassUtils.java

    所以:

    • 如果您的 equals 策略的类在运行时中为插件所知,并且
    • 您的类有一个正确类型的公共静态getInstance() 方法或
    • 你的类有一个正确类型的公共静态字段INSTANCE

    那么插件将使用YourStrategy.getInstance()YourStrategy.INSTANCE 而不是new YourStrategy()

    我猜你已经有了一个 INSTANCE 方法。请尝试将 JAR 与您的策略一起包含到 XJC 类路径中(以便插件可以在编译时解析您的策略类)。

    也请随时提交问题以支持 -Xequals-equalsStrategyInstanceField=com.acme.foo.CustomEqualsStrategy.INSTANCE 或 InstanceMethod 等语法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-10
      • 2019-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-11
      • 2012-08-22
      相关资源
      最近更新 更多