2014-07-11 89 views
3

我有我的代碼如下。我看到從實例方法寫入靜態字段

public MyClass{ 

    private static DataSource dataSource = null; 

    private static DataSource getDataSource(){ 
     if (dataSource == null) { 
      try { 
       dataSource = // something. 
      } catch (Exception e) { 
       // some exception. 
      } 
     } 

     return dataSource; 
    } 

    public List doSomething(){ 

     // ... 

     if(dataSource == null){ 
      dataSource = getDataSource(); 
     } 

     dataSource.getConnection(); 
     // ... 

    } 
} 

我在sonar anaylsis中看到以下消息。

Dodgy - Write to static field from instance method 

This instance method writes to a static field. This is tricky to get correct if multiple instances are being manipulated, and generally bad practice. 
findbugs:ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD Sep12 Reliability > Architecture 

除了我們正在改變doSomething方法中的靜態變量之外,我在這個實現中看到一切都沒問題。我們如何解決這個問題?

+1

待辦事項靜態方法中的賦值? – chrylis

回答

3

不知道如何使你的靜態分析工具的工作原理,但 -

嘗試通過靜態二傳手寫你的價值:

private synchronized static void setDataSource(DataSource ds) { 
    dataSource = ds; 
} 

,這樣就可以做

if(dataSource == null){ 
     setDataSource(getDataSource()); 
    } 
+0

我認爲這個標記爲答案的帖子只有在靜態設置器中再次對數據源進行空檢查時纔是完整的。否則,它仍然不是線程安全的。 – sujit

+0

繼續前進並編輯,成爲我的客人 –

2

你有兩個解決方案之間進行選擇,第一個是在你的數據源類添加getDatasource()方法和同步你實例化你的靜態字段塊:

private static DataSource getDataSource(){ 
    synchronize(DataSource.class){ 
      if (dataSource == null) { 
       try { 
        dataSource = // something. 
       } catch (Exception e) { 
        // some exception. 
       } 
      } 
     } 
     return dataSource; 
     } 

,那麼你只會調用這個方法從doSomething()方法

public void doSomething(){ 
// 
DataSource dataSource=DataSource.getDataSource(); 
// 
} 

第二種解決方案是在類加載時使用靜態塊或直接從聲明實例化您的字段。

static { 
dataSource = // something. 
} 
相關問題