@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")); }
@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 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 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); }
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); }
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);  }