フレデリックBeister:
ジャクソン2.9.5のために、以下の(失敗)JUnitテストを考慮すると:
package de.azamir.test;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import org.junit.Test;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonFinalTest {
private static final class MyClass {
@JsonProperty("myProperty")
public final String myProperty = "myPropertyValueInit";
}
@Test
public void doTest() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, JsonParseException, JsonMappingException, IOException {
final MyClass deserializedMyClass1 = new ObjectMapper().readValue("{\"myProperty\":\"myPropertyValueDeserialized\"}", MyClass.class);
// "myPropertyValueInit"
final String directValue = deserializedMyClass1.myProperty;
// "myPropertyValueDeserialized"
final String reflectValue = (String) MyClass.class.getDeclaredField("myProperty").get(deserializedMyClass1);
assertEquals(directValue, reflectValue);
}
}
Iは、ジャクソン(リフレクションを介して)によって書き込まれた値のみ反射を介して再度検索することができるように、最終的なフィールドへの最適化アクセスへのJava VMを疑います。私たちのコードベースのバグを見つけるための非常に微妙とハードにこのちょうど今日リード。
これは、ジャクソンによって何らかの形で対処されている問題ですか?私の直感は、「見る」んジャクソンコードのための方法がないことになり、この誰が知っています。
私は、次のようなこのコードを改善する複数の方法があります知っています
- 取り外し
@JsonProperty
とミューテータとして、最終的なフィールドを無効にします - 宣言時にはなく、コンストラクタ内のフィールドを初期化しません
- すべてのフィールドは、最終的な作りではありません
しかし、(警告を知らないかもしれない)私たちのチームには、開発者がこれを行わないことを確認することが推奨される方法はありますか?
sfiss:
(からのアイデア:だから方法があり、この答えも、素敵読むには、この質問の代わりに使用しての)定数式を直接宣言サイトで変数を割り当てる、あなたのコンストラクタで、最終的な変数を初期化。あなたが使用している場合、変更を参照してくださいMyClass2
:
public class JacksonFinalTest {
private static final class MyClass {
@JsonProperty("myProperty")
public final String myProperty = "myPropertyValueInit";
}
private static final class MyClass2 {
@JsonProperty("myProperty")
public final String myProperty;
public MyClass2() {
myProperty = "myPropertyValueInit";
}
}
@Test
public void doTest() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, JsonParseException, JsonMappingException, IOException {
final String json = "{\"myProperty\":\"myPropertyValueDeserialized\"}";
final MyClass2 deserializedMyClass1 = new ObjectMapper().readValue(json, MyClass2.class);
// "myPropertyValueInit"
final String directValue = deserializedMyClass1.myProperty;
// "myPropertyValueDeserialized"
final String reflectValue = (String) MyClass2.class.getDeclaredField("myProperty").get(deserializedMyClass1);
assertEquals(directValue, reflectValue);
}
}