I am using the Gson library. What is a clean / idiomatic way to ask Gson to serialize only the fields of the base class when the object give to Gson is of the base class type? Note that this is different from similar questions (e.g. this one) which ask how to always exclude specific fields. In my use case I only want the inherited class fields excluded when the Gson library is passed a derived class object through a base class-typed reference. Otherwise, i.e. if the Gson library is passed a derived class object through a derived-class-typed reference then I want the fields to appear in the serialization.
SSCCE follows:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
class A {
public int a;
public A(final int a) {
this.a = a;
}
}
class B extends A {
public int b;
public B(final int a, final int b) {
super(a);
this.b = b;
}
}
public class Main {
public static void main(String args[]) {
final A a = new B(42, 142);
final Gson gson = new GsonBuilder().serializeNulls().create();
System.out.printf("%s\n", gson.toJson(a));
}
}
The above prints:
{"b":142,"a":42}
I am looking for a clean way to make it print:
{"a":42}
However if the following code is used:
final B b = new B(42, 142);
... then I want gson.toJson(b)
to indeed return:
{"b":142,"a":42}
Is there a clean way to achieve that?
UPDATE
The accepted answer at the time of this writing suggests using toJson(o, A.class)
which does work in this case. However, it appears that this method does not scale well to generics. E.g.:
class A {
public int a;
public A(final int a) {
this.a = a;
}
}
class B extends A {
public int b;
public B(final int a, final int b) {
super(a);
this.b = b;
}
}
class Holder<T> {
public final T t;
public Holder(final T t) {
this.t = t;
}
}
final A a = new B(42, 142);
final Holder<A> holder = new Holder<A>(a);
final Gson gson = new GsonBuilder().serializeNulls().create();
final Type TYPE= new TypeToken<Holder<A>>() {}.getType();
System.out.printf("%s\n", gson.toJson(holder, TYPE));
Regrettably, the above prints:
{"t":{"b":142,"a":42}}