gpt4 book ai didi

java - 在构造函数中调用可覆盖的方法,即使我们指定它来自父类(super class)?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:58:54 29 4
gpt4 key购买 nike

我理解为什么在构造函数中调用可重写方法是一种不好的做法并且会导致错误。但是,我尝试使用前缀 super 调用可覆盖方法,以指定我想从父类(super class)而不是任何其他类调用该方法。

考虑我下面的例子:

public class ObjectMapperExtended extends ObjectMapper {
// fields and stuff, irrelevant to the problem

public ObjectMapperExtended () {
super();
super.registerModule(new Hibernate4Module());
}
}

在这里,我调用了 registerModule,它是父类(super class)中的一个可覆盖方法。然而,我清楚地表明我想从父类(super class)调用该方法,而不是任何其他类,但我仍然收到警告,指出我不应该从构造函数调用可覆盖的方法。我从 SonarQube(准确地说是 squid:S1699)收到了警告,我正在运行它以对我的代码进行静态分析。

我是不是误会了什么?在这种特殊情况下指定 super 没有任何区别吗?

PS:使用的ObjectMapper 类来自http://fasterxml.github.io/jackson-databind/javadoc/2.3.0/com/fasterxml/jackson/databind/ObjectMapper.html

最佳答案

从某种意义上说,您的代码是“安全的”,如果类覆盖了该方法,将始终调用 super 的方法——也许 SonarQube 过于谨慎了。

但是,无论是否可重写,this 都逃脱了构造函数 - 正在初始化的实例可能会从 registerModule() 以不完全/不一致的初始化方式传递给另一个进程状态 - 所以无论哪种方式都是不好的做法。即使该方法的当前实现可能不会将其传递出去,但 future 的实现可能会传递出去(即升级库可能会引入错误)。

要解决此问题,您可以使用 //NOSONAR 标记有问题的行以明确忽略(所有)警告:

public class ObjectMapperExtended extends ObjectMapper {
public ObjectMapperExtended () {
super.registerModule(new Hibernate4Module()); //NOSONAR
}
}

或(最佳实践)使用工厂方法:

public class ObjectMapperExtended extends ObjectMapper {
private ObjectMapperExtended () {}

public static ObjectMapperExtended create() {
ObjectMapperExtended obj = new ObjectMapperExtended();
obj.registerModule(new Hibernate4Module());
return obj;
}
}

顺便说一下,调用 super(); 是多余的;它可以在不改变行为的情况下被删除。

关于java - 在构造函数中调用可覆盖的方法,即使我们指定它来自父类(super class)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31057213/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com