Bean Subtypes
In addition to the bean type name support, Juneau provides simplified support for bean subtypes via the @Marshalled(dictionary=…) attribute declared on a parent bean class.
Bean subtypes are similar in concept to bean type names, with two convenience differences:
- You declare the list of possible subclasses through an annotation on the parent bean class, rather than registering them individually.
- You do not need to register the subtype classes on the bean dictionary of the parser — the parser
discovers them from the parent class's
dictionary.
Example
In the following example, the abstract superclass declares its two concrete subclasses, and each
subclass declares its _type name:
// Abstract superclass declares its subtypes.
@Marshalled(
dictionary={A1.class, A2.class}
)
public abstract class A {
public String f0 = "f0";
}
// Subclass 1
@Marshalled(typeName="A1")
public class A1 extends A {
public String f1;
}
// Subclass 2
@Marshalled(typeName="A2")
public class A2 extends A {
public String f2;
}
When serialized, the concrete subtype is emitted as a virtual _type property:
A1 object = new A1();
object.f1 = "f1";
String json = Json5.of(object);
assertEquals("{_type:'A1',f1:'f1',f0:'f0'}", json);
When parsed back into the abstract type, the _type property is used to instantiate the correct
concrete subclass:
A object = Json.to(json, A.class);
assertTrue(object instanceof A1);
The _type property name
The _type property name is the default type-discriminator key. It can be changed globally via
MarshallingContext.Builder.typePropertyName(String),
or per-class via
@Marshalled(typePropertyName=…).
See also
- Bean Dictionaries — the general bean-dictionary mechanism.
- @Marshalled(typeName) Annotation — declaring type names.