2009-07-01 20 views
0

いくつかのJavaコードを見るとこれはちょうど正しいとは思わない。それは、バッキングフィールドJavaの静的メソッド

public static HashMap<String,WsdlProject> projects = new HashMap<String,WsdlProject>(); 

public Object[] argumentsFromCallSoapui(CallT call, Vector<String> soapuiFiles, HashMap theDPLs,int messageSize) 
{ 
    try { 
     for (String soapFileName:soapuiFiles){ 
      System.out.println("Trying "+soapFileName); 
      WsdlProject project ; 
      if (projects.get(soapFileName) != null){ 
       project = projects.get(soapFileName); 
      } else { 
       project = new WsdlProject(soapFileName); 
       projects.put(soapFileName,project); 
      } 
     } 
    } ... 
} 
+0

待ちを、質問は再び何ですか? –

+0

方法の途中で混合されていたので、それを方法として読んでください。 –

答えて

3

ハズレを持つべきであるように私には、それはあなたがプロジェクトを呼び出すたびのように見える、新しいハッシュマップを取得します、このステートメントは常に偽になるよう

projects.get(soapFileName) != null 

は思えます。 Javaでは、静的変数は一度しか初期化されません。

したがって、この行は1回だけ呼び出されます。

0

プロジェクトのメソッドを呼び出すたびに、新しいHashMapが取得されることはありません。新しいHashMapが一度作成されますが、クラスのすべてのインスタンスは単一のHashMapを共有します。

2

projectsと呼びなさい - それはフィールドであり方法ではありません。

静的フィールドなので、正確に1回初期化されます(複数のクラスローダーで同じ型をモジュロにロード)。

+0

彼はたぶん使用を意識しています:/ – AlbertoPL

+0

おそらく、おそらくそれは重要な違いです。 –

3

プロジェクト変数は、クラスが最初に読み込まれるときに1回初期化されます。

一般的に、この種の静的マップは悪い考えです。それらは、耐用年数を過ぎてもエントリを保持すると、メモリリークになることがよくあります。

この特定のケースでは、スレッドの安全性についても心配しています。このメソッドを呼び出す複数のスレッド(Webサービスを扱うコードの可能性が高い)がある場合は、マップへのアクセスを同期させる必要があります。そうしないと、マップが破損する可能性があります。

そして、一般的な文体ノートでは、最も制約のクラスを使用して変数を定義することをお勧めします。この場合、インターフェース地図ではなく、具体的なクラスHashMapの。あなたは、静的初期化子(?静的コンストラクタ)あなただけのクラスがロードされて初めて初期化される静確認することができます追加した場合

+0

スレッドセーフではありません。それは漏れる。テストするのは難しいです。根本的な問題は、変化する静的な統計は、うんざりしたデザインの不良を示しているということです。 –

+0

はい、実装はConcurrentHashMapに切り替える必要がありますが、他の潜在的な問題は修正されません。 –

1

public class Hello { 
    static { System.out.println("Hello static World!"); } 

    ... 
} 
+0

スタティック初期化子 –

関連する問題