2016-09-23 7 views
0

私が見たの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() 
     { 
      String dateFormat = System.getProperty("date.format"); 
      return new SimpleDateFormat(dateFormat); 
     } 
    }; 

    public String formatIt(Date date) 
    { 
     return formatter.get().format(date); 
    } 
} 

しかし、私は、システムのプロパティを使用するのではなく、それが作成された時点で、必要な情報を持つクラスを提供したいしたくない場合。それ、どうやったら出来るの。すべては静的なので、私はコンストラクタを使用することはできません。

私がシステムプロパティのアプローチが気に入らない理由はたくさんあります。 1つは、そのクラスが周囲のことを知ることを望んでいないので、読むべきシステムプロパティがあります。できるだけシンプルにし、すべての依存関係を注入する必要があります。私は、コーディングの方法が、例えば、テスト容易性を向上させると思う。フォーマットはの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); 
    } 

} 
+0

java 8を使用していますか? –

+0

いいえ、Java 1.6を使用しています。 – Mattias

+0

Wyさんが投票しましたか?私はこれを広範に研究しており、経験豊富なプログラマーです。私は学校に通っているのではなく、皆さんに任務を手伝ってもらいたいのです。これはプロダクションで使用されます。私に下投票をした人がそれが些細な問題だと思うなら、答えを出してください。 – Mattias

答えて