Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix and add the documentation for Built-in Serializers and Deserializers #2441

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 57 additions & 3 deletions UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -378,10 +378,64 @@ This approach is practical only if the array appears as a top-level element or i

### Built-in Serializers and Deserializers

Gson has built-in serializers and deserializers for commonly used classes whose default representation may be inappropriate, for instance
Gson has built-in serializers and deserializers for commonly used classes whose default representation may be inappropriate.
Gson provides built-in serializers and deserializers for basic Java types (e.g., primitive types, strings, arrays) as well as some commonly used classes like `Date`, `BigInteger`, `BigDecimal`, and more. When you use Gson to convert Java objects to JSON or JSON to Java objects, these built-in serializers and deserializers handle the conversion automatically for these basic types and classes.

* `java.net.URL` to match it with strings like `"https://github.com/google/gson/"`
* `java.net.URI` to match it with strings like `"/google/gson/"`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would be good to include URL and URI in the list below again with a description like "Serialized as their string representation" or similar, since these types might also be somewhat common.

For example, suppose you have a Java class `Person`:

```java
public class Person {
private String name;
private int age;
// constructors, getters, setters, etc.
}
```
You can serialize an instance of `Person` to JSON using Gson like this:

```java
Person person = new Person("John Doe", 30);
Gson gson = new Gson();
String json = gson.toJson(person);
```
The output JSON would be: `{"name":"John Doe","age":30}`.

And you can deserialize the JSON back to a `Person` object like this:

```java
String json = "{\"name\":\"Jane Smith\",\"age\":25}";
Person person = gson.fromJson(json, Person.class);
```
The `gson.fromJson()` method uses the built-in deserializers to convert the JSON back into a `Person` object.

Gson also allows you to customize serialization and deserialization by providing your own custom serializers and deserializers for specific types if needed.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this section here with the Person example is needed since there are already multiple examples for object serialization above, and also this is not directly about the built-in serializers.


Below is a list of some of the classes supported by Gson's built-in serializers and deserializers:

Copy link
Collaborator

@Marcono1234 Marcono1234 Jul 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a specific reason why you chose to use a numbered list here? A numbered list suggests some kind of ordering or priorities and I am not sure if that is correct here, or needed. Maybe a regular unordered list would be better?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Marcono1234 Sure, changed to unordered list.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Lalitha333, just to clarify, you are still working on these changes, right? Or did you forget to push the commits?

Copy link
Author

@Lalitha333 Lalitha333 Jul 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Marcono1234 Sorry for the delay, yes I’m going to push the changes as per review comments.

1. Primitive Types:
* `int, Integer, long, Long, float, Float, double, Double, boolean, Boolean, char, Character, byte, Byte, short, Short.`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please format each type separately as code, e.g. int, long, ...
Having this formatted as one single code line looks a bit weird.

Also, maybe omit the wrapper types and just add something like "(and their wrappers)" at the end to make it easier to read.

2. Arrays:
* Arrays of primitive types and their wrappers.
* Arrays of objects.
3. Collections:
* java.util.List: List of objects.
* java.util.Set: Set of objects.
* java.util.Map: Map of key-value pairs.
Copy link
Collaborator

@Marcono1234 Marcono1234 Jul 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe instead of listing List and Set separately, write something like the following because Gson actually supports any Collection:

  • java.util.Collection: Collection of objects, and collection subtypes such as List or Set.

And also in general maybe format the class names here and below as code, e.g. "java.util.Map" instead of just "java.util.Map".

4. Date and Time:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this should also refer to GsonBuilder.setDateFormat(...)

* java.util.Date: Serialized as a Unix timestamp (milliseconds since January 1, 1970, 00:00:00 GMT).
* java.sql.Date: Serialized as a string in the format "yyyy-MM-dd".
* java.sql.Time: Serialized as a string in the format "HH:mm:ss".
* java.sql.Timestamp: Serialized as a string in the format "yyyy-MM-dd HH:mm:ss".
Comment on lines +425 to +428
Copy link
Collaborator

@Marcono1234 Marcono1234 Jul 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The format you are describing here for all of these date and time types seems to be incorrect. They might be what one would hope or expect, but sadly due to legacy reasons Gson is not using these formats by default.

Maybe the documentation could say something like:

For legacy reasons the serialized output for these types is in a human-readable format. It is recommended to either use GsonBuilder.setDateFormat(String) to specify a stable machine-readable format, or to register a custom TypeAdapter for these types which produces the desired output.

5. BigInteger and BigDecimal:
* java.math.BigInteger: Serialized as a string.
* java.math.BigDecimal: Serialized as a string.
Comment on lines +430 to +431
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Serialized as a string" is misleading, because they are actually serialized as JSON number. Maybe it should say something like this?

Serialized as a JSON number.

6. Enumerations:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe call it "Enum Types" in the header here as well, that might be clearer than "Enumerations".

* Enum types are serialized as strings by default. You can also customize the serialization using @SerializedName annotation.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe reword this a bit, otherwise it sounds they might actually be serialized as something other than a JSON string:

Suggested change
* Enum types are serialized as strings by default. You can also customize the serialization using @SerializedName annotation.
* Enum constants are serialized using their name by default. You can also customize the serialization using the `@SerializedName` annotation on an enum constant.

7. Optional:
* java.util.Optional: Serializes the value if present; otherwise, it serializes as null.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong? See #1102

8. Custom Objects:
* Gson can automatically serialize and deserialize custom Java objects using reflection. It serializes the non-static, non-transient fields of an object.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Gson can automatically serialize and deserialize custom Java objects using reflection. It serializes the non-static, non-transient fields of an object.
* Gson can automatically serialize and deserialize custom Java objects using reflection. By default, it serializes the non-static, non-transient fields of an object.

(Because this can be customized)


It's important to note that Gson's built-in serializers and deserializers can handle nested objects and collections of objects as well. If a class is not supported by Gson's default behavior, you can provide custom serialization and deserialization logic using Gson's JsonSerializer and JsonDeserializer interfaces.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this should rather recommend TypeAdapter since the documentation for JsonSerializer and JsonDeserializer also recommend TypeAdapter for performance reasons.

Suggested change
It's important to note that Gson's built-in serializers and deserializers can handle nested objects and collections of objects as well. If a class is not supported by Gson's default behavior, you can provide custom serialization and deserialization logic using Gson's JsonSerializer and JsonDeserializer interfaces.
It's important to note that Gson's built-in serializers and deserializers can handle nested objects and collections of objects as well. If a class is not supported by Gson's default behavior, you can provide custom serialization and deserialization logic using Gson's `TypeAdapter` class.

Or maybe even omit this sentence because the section "Custom Serialization and Deserialization" is directly below this.


For many more, see the internal class [`TypeAdapters`](gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe reword this a bit to give a bit more context, for example:

Suggested change
For many more, see the internal class [`TypeAdapters`](gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java).
For more of the built-in serializers and deserializers, see the internal class [`TypeAdapters`](gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java).


Expand Down