If jsonString is generated by you, you can consider to add type info and then use it to convert deserialized object. You could refer to this post for how to do it.
If jsonString is generated by other services beyond your control, then there's no type info you can get so you can only try it one by one, @Sachin Gupta's answer would be a nice choice.
I'd like to provide an additional option: define an all-in-one entity including all fields of MyClass1, MyClass2 and MyClass3, and make MyClass1, MyClass2 and MyClass3 be separated wrapper and only expose related fields for each. Code as follows:
Class AllInOne:
public class AllInOne {
protected String a;
protected String b;
protected String c;
public A asA() {
return new A(this);
}
public B asB() {
return new B(this);
}
public C asC() {
return new C(this);
}
}
Class A:
public class A {
private AllInOne allInOne;
public A(AllInOne allInOne) {
this.allInOne = allInOne;
}
public String getA() {
return allInOne.a;
}
}
Class B:
public class B {
private AllInOne allInOne;
public B(AllInOne allInOne) {
this.allInOne = allInOne;
}
public String getB() {
return allInOne.b;
}
}
Class C:
public class C {
private AllInOne allInOne;
public C(AllInOne allInOne) {
this.allInOne = allInOne;
}
public String getC() {
return allInOne.c;
}
}
Test code:
public class Main {
public static void main(String[] args) throws IOException {
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
String jsonA = "{\"a\":\"a value\"}";
String jsonB = "{\"b\":\"b value\"}";
String jsonC = "{\"c\":\"c value\"}";
needTypeA(om.readValue(jsonA, AllInOne.class).asA());
needTypeB(om.readValue(jsonB, AllInOne.class).asB());
needTypeC(om.readValue(jsonC, AllInOne.class).asC());
}
private static void needTypeA(A a) {
System.out.println(a.getA());
}
private static void needTypeB(B b) {
System.out.println(b.getB());
}
private static void needTypeC(C c) {
System.out.println(c.getC());
}
}
With implementation like this, we erased the specific type info at deserialization step, and bring it back at the moment we really need/use it. And as you can see there's not too much extra code, because what we actually did is just moving all fields declaration together, and added couple methods.
Notes:
- I declare fields in
AllInOne to be protected, putting all POJO class in the same package will make A, B and C be able to access them directly, but not for other classes outside.
- Setting
om.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); to make jackson deserialize by field, so that we can remove duplicate setter and getter from AllInOne class
- If you do need to know the type info, you could add methods like
isA inside AllInOne based on the fields info