### Question:
RestrictSerializationToBaseClassFactory implements TypeAdapterFactory { @Override public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) { Class incoming = type.getRawType(); if (subClasses != null) { boolean matched = false; for (Class<? extends B> subClass : subClasses) { if (incoming == subClass) { matched = true; break; } } if (!matched) return null; } else { if (incoming == baseClass || !baseClass.isAssignableFrom(incoming)) return null; } TypeAdapter<T> adapter = new TypeAdapter<T>() { @Override public T read(JsonReader reader) throws IOException { final TypeAdapter subAdapter = gson.getDelegateAdapter( RestrictSerializationToBaseClassFactory.this, type); return (T) subAdapter.read(reader); } @Override public void write(JsonWriter writer, T value) throws IOException { final TypeAdapter<B> baseAdapter = gson.getAdapter(baseClass); baseAdapter.write(writer, (B) value); } }; return adapter; } RestrictSerializationToBaseClassFactory(Class<B> baseClass);  RestrictSerializationToBaseClassFactory(Class<B> baseClass, Class<? extends B>... subClasses); @Override TypeAdapter<T> create(final Gson gson, final TypeToken<T> type);  }### Answer:
@SuppressWarnings("unchecked") @Test public void testSerializeTopLevel() { Gson gson = new GsonBuilder() .registerTypeAdapterFactory(new RestrictSerializationToBaseClassFactory<Base>(Base.class, Sub1.class, Sub2.class)) .create(); String json = gson.toJson(new Sub1()); assertTrue(json.contains("\"a\":1")); assertFalse(json.contains("b")); json = gson.toJson(new Sub2()); assertTrue(json.contains("\"a\":1")); assertFalse(json.contains("c")); }
@Test public void testDeserializeTopLevel() { Gson gson = new GsonBuilder() .registerTypeAdapterFactory(new RestrictSerializationToBaseClassFactory<Base>(Base.class)) .create(); String json = "{'a':5,'b':6,'c':7}"; Sub1 sub1 = gson.fromJson(json, Sub1.class); assertEquals(5, sub1.a); assertEquals(6, sub1.b); Sub2 sub2 = gson.fromJson(json, Sub2.class); assertEquals(5, sub2.a); assertEquals(7, sub2.c); }
@SuppressWarnings("unchecked") @Test public void testSerializeAsField() { Gson gson = new GsonBuilder() .registerTypeAdapterFactory(new RestrictSerializationToBaseClassFactory<Base>(Base.class, Sub1.class, Sub2.class)) .create(); String json = gson.toJson(new Container()); assertTrue(json.contains("\"a\":1")); assertFalse(json.contains("\"b\"")); assertFalse(json.contains("\"c\"")); }
@SuppressWarnings("unchecked") @Test public void testSerializeUnrestrictedSubTypeFields() { Gson gson = new GsonBuilder() .registerTypeAdapterFactory(new RestrictSerializationToBaseClassFactory<Base>(Base.class, Sub1.class)) .create(); String json = gson.toJson(new Container()); assertTrue(json.contains("\"a\":1")); assertFalse(json.contains("\"b\"")); assertTrue(json.contains("\"c\":3")); }
@Test public void testDeserializeAsField() { Gson gson = new GsonBuilder() .registerTypeAdapterFactory(new RestrictSerializationToBaseClassFactory<Base>(Base.class)) .create(); String json = "{'sub1':{'a':5,'b':6},'sub2':{'a':5,'c':7}}"; Container container = gson.fromJson(json, Container.class); Sub1 sub1 = container.sub1; assertEquals(5, sub1.a); assertEquals(6, sub1.b); Sub2 sub2 = container.sub2; assertEquals(5, sub2.a); assertEquals(7, sub2.c); }