2010-09-02 77 views
13

我有一個類,類似於此,findbugz是抱怨(initialize(),並且killStaticfield())「從實例方法寫入靜態字段」。我無法在ctor中設置靜態字段。解決這個'從實例方法'寫入靜態字段findbugs警告的最好方法是什麼?

  • ,這是什麼問題的最佳解決?
  • 是否將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; 
        } 
    } 
    
+3

爲什麼它必須是'在首位static'?什麼是功能要求?你以任何方式理解「靜態」是什麼意思?用你自己的話說出來? – BalusC 2010-09-02 19:28:44

+11

是的,當然我知道什麼是靜態的意思;不,我不需要證明給你。 – darrickc 2010-09-02 19:59:06

+0

要回答你的問題,這個字段是靜態的,因爲get方法需要是靜態的,所以其他對象可以訪問staticField而不必引用Something對象。 – darrickc 2010-09-02 20:07:07

回答

13

住在儘可能靠近你原來的設計...

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; 
    } 
} 
+2

+1,我最喜歡第二個更好的版本。 – emory 2010-09-03 01:00:32

+0

但是沒有同步的設計也意味着沒有killStaticField。 – extraneon 2010-09-03 13:34:03

+0

你知道......看第一個解決方案,它仍然不是線程安全的,即使變量是易變的。你必須在if-null-then-new部分周圍放置一個同步{}塊...我肯定會更喜歡第二個選項。 – romacafe 2010-09-03 15:59:31

4

的問題是要與靜態字段做什麼。如果它對於你創建的每個類都有所改變,那麼根本就不是一個好主意。如果它只被初始化一次,你應該懶惰地將它初始化爲一個單例。

public class Something 
{ 
    private static SomeClass staticField = null; 

    public Something() 
    { 

    } 

    public static SomeClass getStaticField() 
    { 
     if(staticField == null) 
      staticField = new SomeClass();; 
     return staticField; 
    } 
} 
+0

不要忘記讓'getStaticField'方法'synchronized'! – 2010-09-02 19:39:28

+0

注意,不能只將靜態方法定義同步,因爲靜態方法使用Something.class來同步! – darrickc 2010-09-02 20:08:07

+1

我認爲在討論任何高級線程問題之前,應該清楚使用靜態變量。對不起,但你的問題聽起來並不像你理解什麼時候使用靜態變量,以及什麼時候沒有。也許你可以澄清你的問題多一點。 – Daff 2010-09-02 20:11:38

4

如果靜態字段不是靜態的,則從靜態字段中移除靜態字段。

使kill和getStaticField自己靜態。而且你通常通過類名引用static,而不是通過(隱含的)this來清楚地表明它是靜態的,並且可能在其他thReads中引起意想不到的後果。

如果有疑問,請勿對非常量字段使用靜態。

+0

你不需要「當有疑問」。 – 2010-09-02 23:22:53

相關問題