2011-12-08 92 views
4

我在類下列方式使用簡單的日期格式在我的應用程序:簡單的日期格式

static SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy"); 

public static myFunction(final String strDate) 
{ 
     Date endDate = null; 
endDate = MyClass.sdf.parse(strDate); 
} 

我使用的FindBugs這是給下面的錯誤在上面的代碼:

「作爲JavaDoc聲明,DateFormats對於多線程使用本質上是不安全的,探測器發現了一個對通過靜態字段獲得的DateFormat實例的調用,這看起來很可疑。

有人可以請解釋一下這個錯誤。我無法理解上面的消息正在試圖說明什麼。

感謝您的閱讀!

+2

可能[重複](http://stackoverflow.com/questions/2409657/call-to-method-of-static-java-text-dateformat-not-advisable)? – Dallas

+0

@達拉斯指出的問題不是相同的措詞,但接受的答案是有用的和相當完整的。 – madth3

+0

大多數開發人員都明白,對於大多數不是線程安全的類,這是由於同時改變狀態。格式建立後,格式化日期不應改變狀態。僅僅在官方文檔中記錄這些不是線程安全的是不夠的。應明確記錄,即使格式化方法在實例變量中保持臨時狀態也不是線程安全的。聲明它爲靜態不只是一個新手的錯誤。類比可以在修改集合(put)和訪問集合(get)之間進行。 – YoYo

回答

4

其他誰回答有關線程安全和從SimpleDateFormat之前刪除靜態關鍵字是正確的,雖然您發佈與您的問題的代碼是根本不可編譯的。

我覺得這是更接近你正在尋找代碼:

public static Date parseDateStr(final String dateStr) throws ParseException 
{ 
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy"); 
return sdf.parse(dateStr); 
} 
+0

另一種方法是將parseDateStr聲明爲synchronized。 – user949300

1

從靜態SimpleDateFormat中刪除靜態sdf = new SimpleDateFormat(「MM/dd/yyyy」);

該var將作爲一個靜態實例保留在此方法的範圍內。這意味着其他線程同時訪問此方法將在不是線程安全的同一實例上調用dateformat。

+0

不能使它成爲非靜態的。實際上它被用在實用程序類中,其中方法是靜態的,因此可以使用類名來調用它。像這樣:return MyUtil.sdf.format(calendar.getTime()); - 任何其他解決方案還是可以忽略FingBugs? – Nik

+0

如果你的應用程序是單線程的,那麼你可以忽略它。 從你的評論我假設sdf是一個類字段,而不是一個方法。如果是這種情況,你應該更新你的問題。 如果你的應用程序是多線程的,那麼我建議不要讓SDF的靜態實例像這樣使用。在這些情況下,它可能會返回不可預知的結果。您可以通過提供對該字段的同步訪問來解決此問題,並使該字段保持專用,以避免任何人繞過此方法。 – Steven

0

盤古的建議繼續前進,你可以在下面測試代碼。

import java.text.ParseException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 



public class Test { 

    public static Date myFunction(final String strDate) throws ParseExceptoion 
    { 
    SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy"); 
     return sdf.parse(strDate); 

    } 


public static void main(String[] args) throws ParseException { 
    System.out.println(myFunction("05/18/1989").toString()); 

} 
} 
0

我在那裏(通過DOS ANT構建和測試腳本)構建Eclipse之外時,JUnit測試不及格的問題,但它跑就好內蝕。

被測代碼是一個批處理作業的類和方法,其SimpleDateFormat聲明爲private static final。

我並不關心線程安全性,因爲這個批處理作業是單線程的。

我也不想在每次需要它的時候實例化一個SimpleDateFormat的新實例,因爲這個過程是在一個處理數千行數據的循環中。

我通過將SimpleDateFormat的聲明從private static final改爲private final transient來解決它。

當然這意味着實例化類,它可能不適用於所有情況,但是如果您要實例化類並且不想每次都創建新實例並且線程安全不成問題,那麼這是一個解決方案。