google / google/gson

JsonSerializable interface to mark classes as serializable

Open
#2,788 1 comment 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Java
Stars
24.2k
Forks
4.5k
Avg merge
6d 4h
Merged PRs (30d)
12

Description

# Problem solved by the feature

Allow classes to be marked as serializable without needing another class as the serializer.
Is this similar to #594?

# Feature description

It would work similarly to Java's `Comparable` interface, so you wouldn't need a serializer in another class.
Currently, you need to either add a TypeAdapter as an external class through `@JsonAdapter` or `GsonBuilder`, but it would be much more convenient if the instance (of the object we're serializing) could serialize itself.

The implementation could look a little something like this (not the best code, triple nested anonymous classes my beloved) (I code in 4 spaces so the formatting may be a bit wonk):
```java
public interface JsonSerializable {
TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
@Override
public TypeAdapter create(final Gson gson, final TypeToken type) {
return !JsonSerializable.class.isAssignableFrom(type.getRawType()) ?
null : // return early if it isn't JsonSerializable
new TypeAdapter<>() { // SerializationDelegatingTypeAdapter? not sure what it does
private TypeAdapter delegate;
private JsonSerializationContext context;

@Override
public void write(JsonWriter out, T value) throws IOException {
if (value instanceof JsonSerializable) // implicit null check
Streams.write(((JsonSerializable)value).serialize(type.getType(), context()), out);
else
delegate().write(out, value);
}

@Override
public T read(JsonReader in) throws IOException {
return delegate().read(in);
}

private TypeAdapter delegate() { // taken from Excluder
TypeAdapter d = delegate;
return d != null
? d
: (delegate = gson.getDelegateAdapter(JsonSerializable.FACTORY, type));
}

private JsonSerializationContext context() {
JsonSerializationContext jsc = this.context;
return jsc != null
? jsc
: (context = new JsonSerializationContext() { // expose GsonContextImpl?
@Override
public JsonElement serialize(Object src) {
return gson.toJsonTree(src);
}

@Override
public JsonElement serialize(Object src, Type typeOfSrc) {
return gson.toJsonTree(src, typeOfSrc);
}
});
}
};
}
};

JsonElement serialize(Type thisType, JsonSerializationContext context);
}
```

# Alternatives / workarounds

Implement the serializer or TypeAdapter in another class.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.