{@code 32 | * abstract class Shape { 33 | * int x; 34 | * int y; 35 | * } 36 | * class Circle extends Shape { 37 | * int radius; 38 | * } 39 | * class Rectangle extends Shape { 40 | * int width; 41 | * int height; 42 | * } 43 | * class Diamond extends Shape { 44 | * int width; 45 | * int height; 46 | * } 47 | * class Drawing { 48 | * Shape bottomShape; 49 | * Shape topShape; 50 | * } 51 | * }52 | *
Without additional type information, the serialized JSON is ambiguous. Is 53 | * the bottom shape in this drawing a rectangle or a diamond?
{@code 54 | * { 55 | * "bottomShape": { 56 | * "width": 10, 57 | * "height": 5, 58 | * "x": 0, 59 | * "y": 0 60 | * }, 61 | * "topShape": { 62 | * "radius": 2, 63 | * "x": 4, 64 | * "y": 1 65 | * } 66 | * }}67 | * This class addresses this problem by adding type information to the 68 | * serialized JSON and honoring that type information when the JSON is 69 | * deserialized:
{@code 70 | * { 71 | * "bottomShape": { 72 | * "type": "Diamond", 73 | * "width": 10, 74 | * "height": 5, 75 | * "x": 0, 76 | * "y": 0 77 | * }, 78 | * "topShape": { 79 | * "type": "Circle", 80 | * "radius": 2, 81 | * "x": 4, 82 | * "y": 1 83 | * } 84 | * }}85 | * Both the type field name ({@code "type"}) and the type labels ({@code 86 | * "Rectangle"}) are configurable. 87 | * 88 | *
{@code 92 | * RuntimeTypeAdapterFactory95 | * Next register all of your subtypes. Every subtype must be explicitly 96 | * registered. This protects your application from injection attacks. If you 97 | * don't supply an explicit type label, the type's simple name will be used. 98 | *shapeAdapterFactory 93 | * = RuntimeTypeAdapterFactory.of(Shape.class, "type"); 94 | * }
{@code 99 | * shapeAdapter.registerSubtype(Rectangle.class, "Rectangle"); 100 | * shapeAdapter.registerSubtype(Circle.class, "Circle"); 101 | * shapeAdapter.registerSubtype(Diamond.class, "Diamond"); 102 | * }103 | * Finally, register the type adapter factory in your application's GSON builder: 104 | *
{@code 105 | * Gson gson = new GsonBuilder() 106 | * .registerTypeAdapterFactory(shapeAdapterFactory) 107 | * .create(); 108 | * }109 | * Like {@code GsonBuilder}, this API supports chaining:
{@code 110 | * RuntimeTypeAdapterFactory115 | */ 116 | public final class RuntimeTypeAdapterFactoryshapeAdapterFactory = RuntimeTypeAdapterFactory.of(Shape.class) 111 | * .registerSubtype(Rectangle.class) 112 | * .registerSubtype(Circle.class) 113 | * .registerSubtype(Diamond.class); 114 | * }