2

私はこれに完全に混乱しています。単体テストに相当する完全なパッケージを実行しています。以下は、多くの JUnit テストで使用される関連する共有コードです。

private static Map<String, JAXBContext> jaxbContexts = 
                             new HashMap<String, JAXBContext>();

private synchronized JAXBContext getJAXBContext(Class clazz) throws JAXBException {
    JAXBContext context = null;
    if (jaxbContexts.containsKey(clazz.getName())) {
        context = jaxbContexts.get(clazz.getName());
    } else {
        context = JAXBContext.newInstance(clazz);
        System.out.println("Created new context for '" + clazz.getName() + "'");
        jaxbContexts.put(clazz.getName(), context);
    }
    return context;
}

JUnit 実行のコンソール出力には、次の 2 つの連続するエントリが含まれます。

Created new context for 'com.somecompany.xmlschema.providepensionpaymentinfo.Interface'
Created new context for 'com.somecompany.xmlschema.providepensionpaymentinfo.Interface'

私は何が欠けていますか?jaxbContexts.containsKey()JUnit 実行中の他の 46 回とは異なり、このインスタンスで文字列ベースのキーが機能しなかったのはなぜですか? テストを並行して実行していませんが、違いが生じる場合はアスペクトを使用します。

4

5 に答える 5

3

それをデバッグし、この getJAXBContext() メソッドを含むクラスが 1 回だけインスタンス化されていることを確認します (呼び出しごとにデバッグ モードで同じメモリ ID を持っていることを確認します)。インスタンス化が異なる場合、synchronized キーワードは異なるロックをロックし、異なるマップを使用します。

于 2011-01-20T14:21:51.633 に答える
1

個人的には、containsKey は気にしません。

String name = clazz.getName();
context = jaxbContexts.get(name);
if (context == null) {
    context = JAXBContext.newInstance(clazz);
    System.out.println("Created new context for '" + name + "'");
    jaxbContexts.put(name, context);
}
于 2011-01-20T14:21:06.527 に答える
1

キーとして文字列を含む Map について特別なことは何もありません。println を置き換えるだけで、new Exception().printStackTrace()何が起こっているかがわかります。マップを保持するクラスの 2 つのインスタンスなどを作成している可能性があります。

于 2011-01-20T14:24:24.157 に答える
0

レースを除いて..でもあなたは物事を並行して実行しないと言っています...

とにかく、私は に電話context = jaxbContexts.get(clazz.getName())してテストcontextしたでしょうnull

ああ、複数のクラスが同じ名前を持つ可能性があるため、クラス自体をキーとして使用しました(クラスローダーを考えてください)

于 2011-01-20T14:22:28.543 に答える
-1

マップは、より簡単に使用するためにMap<Class, JAXBContext>代わりにすることができます。Map<String, JAXBContext>

于 2011-01-20T14:52:36.960 に答える