我見過的ThreadLocal的每個實例返回不能動態地設置,類似這樣的例子有SimpleDateFormat的,每次它總是返回相同的SimpleDateFormat值:ThreadLocal的初始化
public class Foo
{
// SimpleDateFormat is not thread-safe, so give one to each thread
private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
@Override
protected SimpleDateFormat initialValue()
{
return new SimpleDateFormat("yyyyMMdd HHmm");
}
};
public String formatIt(Date date)
{
return formatter.get().format(date);
}
}
但可以說,我希望能夠配置返回的值。一種方法是使用系統屬性是這樣的:
public class Foo
{
// SimpleDateFormat is not thread-safe, so give one to each thread
private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
@Override
protected SimpleDateFormat initialValue()
{
String dateFormat = System.getProperty("date.format");
return new SimpleDateFormat(dateFormat);
}
};
public String formatIt(Date date)
{
return formatter.get().format(date);
}
}
但是,如果我不希望使用系統屬性,而是想用它創建時的必要信息提供類的東西。我怎麼做。一切都是靜態的,所以我不能使用構造函數。
我不喜歡系統屬性方法的原因很多。對於一個我不想讓這個班級瞭解其周圍環境的東西,那就是應該閱讀的系統屬性。它應該儘可能簡單,並注入所有的依賴關係。例如,我認爲這種編碼方式可以提高可測性。
最終解決
格式是通過調用setFormat和formatIt所有來電設置一次後,使用相同的格式。
public class Foo {
private static volatile String FORMAT;
private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat(FORMAT);
}
};
/**
* Set the format. Must be called before {@link #formatIt(Date)}. Must only be called once.
*
* @param format
* a format, e.g. "yyyyMMdd HHmm".
* @throws IllegalStateException
* if this method has already been called.
*/
public static void setFormat(String format) {
if (Foo.FORMAT != null) {
throw new IllegalStateException("Format has already been set");
}
FORMAT = format;
}
/**
* @return the formatted date.
* @throws IllegalStateException
* if this method is called before {@link #setFormat(String)} has been called.
*/
public static String formatIt(Date date) {
if (Foo.FORMAT == null) {
throw new IllegalStateException("Format has not been set");
}
return formatter.get().format(date);
}
}
你用java 8嗎? –
不,我使用Java 1.6。 – Mattias
Wy的投票?我對此進行了廣泛的研究,並且我是一位經驗豐富的程序員。這不像我在學校,只是想讓你們幫我完成作業。這將用於生產。如果給我棄權的人認爲這是一個微不足道的問題,請提供答案。 – Mattias