【问题标题】:FindBugs: static instance initialization within classFindBugs:类内的静态实例初始化
【发布时间】:2016-06-21 20:02:56
【问题描述】:

FindBugs 在我的代码中报告了一个不好的做法, findbugs:SI_INSTANCE_BEFORE_FINALS_ASSIGNED.

类的静态初始化器在分配所有静态最终字段之前创建类的实例。

我的代码看起来像..

public class Foo {

    public static final Foo DEFAULT = new Foo(Bar.A, "baz");

    public enum Bar {
        A, B
    }

    private final Bar bar;
    private final String baz;

    public Foo(Bar bar, String baz) {
        this.bar = bar;
        this.baz = baz;
    }

}

我知道它将 new Foo 用作 Foo 中的静态变量是一种不好的做法,但并没有真正看到问题。

谁能解释为什么这是不好的做法,使用这种不好的做法可能会发生什么意外行为,或者提出一个更好的做法作为替代方案?

【问题讨论】:

  • 如果你看here,它会说:To provide the same capability for class variables, the Java programming language includes static initialization blocks. 你可以使用静态块来实例化类。
  • @Svasa 静态初始化程序没有帮助。已经有一个,隐含的。
  • 您确定您收到了发布源的 Findbugs 消息吗?运行你的代码只会给我一个L P URF_UNREAD_FIELD UrF: Unread field: Foo.baz 警告。
  • @Robert,不,我不认为这是重复的。在发布我的问题之前,我已经阅读了该帖子,它涉及显示该警告所需的阈值水平。它没有讨论警告的含义或可能的修复。我的示例几乎与我的真实代码一模一样,所以我认为它应该给出相同的 FindBugs 错误。或许可以参考您链接到的关于降低 FindBugs 阈值的帖子。

标签: java static findbugs


【解决方案1】:

可以在构造函数中引用DEFAULT,或者构造函数直接或间接调用的方法。如果您这样做了,它的值将是 null,这可能会对您最终分配给 DEFAULT 的实例的初始化产生不良后果。

您不会以这种方式引用它,所以这不是一个真正的问题 - 目前。但是,将来可能会更改该类以意外引用它。

在您的示例代码中,它看起来像是一个非常便宜的实例化类。您可以简单地提供一个静态工厂方法getDefault(),以便在需要时创建一个新实例。如果它在现实中没有那么便宜,您可以采用某种形式的惰性初始化。

【讨论】:

  • 这是一个非常好的观点,我可以从构造函数中引用静态。很惊讶它没有给出一些无限递归循环。谢谢安迪!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 2018-05-09
  • 2020-04-14
  • 1970-01-01
  • 2015-06-26
  • 1970-01-01
相关资源
最近更新 更多