17

我有一个看起来与此类似的类,并且 findbugz 抱怨“从实例方法写入静态字段”(initialize()killStaticfield())。我无法在 ctor 中设置静态字段。

  • 解决此问题的最佳方法是什么?
  • 将 staticField 放入 AtomicReference 就足够了吗?

     public class Something
     {
      private static SomeClass staticField = null;
      private AnotherClass aClass;
      public Something()
      {
    
      }
    
      public void initialize()
      {
        //must be ctor'd in initialize
        aClass = new AnotherClass();
        staticField = new SomeClass( aClass );
      }
    
      public void killStaticField()
      {
       staticField = null;
      }
    
      public static void getStaticField()
      {
        return staticField;
      }
    }
    
4

4 回答 4

16

尽可能接近您的原始设计...

public class Something {
  private static volatile SomeClass staticField = null;

  public Something() {
  }

  public static SomeClass getStaticField() {
    if(Something.staticField == null)
      Something.staticField = new SomeClass();;
    return Something.staticField;
  }
}

通过类名引用您的静态变量,这将删除 findbugz 警告。将您的静态变量标记为 volatile,这将使引用在多线程环境中更安全。

更好的是:

public class Something {
  private static final SomeClass staticField = new SomeClass();

  public Something() {
  }

  public static SomeClass getStaticField() {
    return Something.staticField;
  }
}
于 2010-09-02T20:30:50.117 回答
4

问题是你想用静态字段做什么。如果它针对您创建的每个类都发生了变化,那么让它完全静态可能不是一个好主意。如果它只被初始化一次,你应该懒惰地将它初始化为一个单例。

public class Something
{
    private static SomeClass staticField = null;

    public Something()
    {

    }

    public static SomeClass getStaticField()
    {
        if(staticField == null)
            staticField = new SomeClass();;
        return staticField;
    }
}
于 2010-09-02T19:31:25.683 回答
4

如果它不应该是静态的,则从 staticField 中删除静态。

使 kill 和 getStaticField 本身成为静态的。而且您通常通过类名而不是(隐式) this 来引用静态,以非常清楚地表明它是静态的,并且可能会在其他线程中导致意外后果。

如有疑问,请勿对非常量字段使用静态。

于 2010-09-02T19:32:16.433 回答
0

最好的办法是不做,尝试找到更好的设计模式。如果真的有必要,这将起作用并使 findbugs/spotbugs 不会抱怨。

public class Something
{
    private static SomeClass staticField = null;

    public Something()
    {
    }

    private void setStaticField(SomeClass value){
        staticField=value;
    } 

    public static SomeClass getStaticField()
    {
        if(staticField == null)
            setStaticField(new SomeClass());
        return staticField;
    }
}
于 2020-06-08T15:37:54.037 回答