1. Overview
1.概述
In this tutorial, we’re going to learn how to serialize and deserialize primitive values with Gson. Google developed the Gson library to serialize and deserialize JSON. Additionally, we’re going to learn about some specific quirks that the Gson library has when it comes to dealing with primitives.
在本教程中,我们将学习如何用Gson对原始值进行序列化和反序列化。Google 开发了 Gson 库来序列化和反序列化 JSON。此外,我们还将了解Gson库在处理基元时的一些特殊怪癖。
On the other hand, if we need to work with arrays, collections, nested objects, or other customization, we have additional tutorials on serializing with Gson and deserializing with Gson.
另一方面,如果我们需要处理数组、集合、嵌套对象或其他定制,我们还有额外的教程,即用Gson进行序列化和用Gson进行反序列化。
2. Maven Dependency
2.Maven的依赖性
To work with Gson, we must add the Gson dependency to the pom:
为了与Gson一起工作,我们必须将Gson依赖性添加到pom。
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
3. Serializing Primitive Types
3.序列化原始类型
Serializing with Gson is pretty straightforward. We’ll use the following model as an example:
用Gson进行序列化是非常直接的。我们将使用下面的模型作为例子。
public class PrimitiveBundle {
public byte byteValue;
public short shortValue;
public int intValue;
public long longValue;
public float floatValue;
public double doubleValue;
public boolean booleanValue;
public char charValue;
}
First, let’s initialize an instance with some test values:
首先,让我们用一些测试值初始化一个实例。
PrimitiveBundle primitiveBundle = new PrimitiveBundle();
primitiveBundle.byteValue = (byte) 0x00001111;
primitiveBundle.shortValue = (short) 3;
primitiveBundle.intValue = 3;
primitiveBundle.longValue = 3;
primitiveBundle.floatValue = 3.5f;
primitiveBundle.doubleValue = 3.5;
primitiveBundle.booleanValue = true;
primitiveBundle.charValue = 'a';
Next, we can serialize it:
接下来,我们可以将其序列化。
Gson gson = new Gson();
String json = gson.toJson(primitiveBundle);
Finally, we can see the serialized result:
最后,我们可以看到序列化的结果。
{
"byteValue":17,
"shortValue":3,
"intValue":3,
"longValue":3,
"floatValue":3.5,
"doubleValue":3.5,
"booleanValue":true,
"charValue":"a"
}
We should note a few details from our example. For starters, the byte value is not serialized as a string of bits like it was in the model. In addition to that, there is no distinction between short, int and long. Also, there is no distinction between float and double.
我们应该从我们的例子中注意到一些细节。首先,字节值没有像模型中那样被序列化为一串比特。除此之外,short、int和long之间也没有区别。另外,float和double之间也没有区别。
Another thing to notice is that a string represents the character value.
另一个需要注意的是,一个字符串代表的是字符值。
Actually, these last three things don’t have anything to do with Gson, but it is the way JSON is defined.
实际上,最后这三点与Gson没有任何关系,但这是JSON的定义方式。
3.1. Serializing Special Floating-Point Values
3.1.串行化特殊浮点值
Java has constants Float.POSITIVE_INFINITY and NEGATIVE_INFINITY to represent infinity. Gson can’t serialize these special values:
Java有常量Float.POSITIVE_INFINITY和NEGATIVE_INFINITY来表示无穷大。Gson不能序列化这些特殊的值。
public class InfinityValuesExample {
public float negativeInfinity;
public float positiveInfinity;
}
InfinityValuesExample model = new InfinityValuesExample();
model.negativeInfinity = Float.NEGATIVE_INFINITY;
model.positiveInfinity = Float.POSITIVE_INFINITY;
Gson gson = new Gson();
gson.toJson(model);
Trying to do so raises an IllegalArgumentException.
试图这样做会引发一个IllegalArgumentException。
Trying to serialize NaN also raises an IllegalArgumentException because this value is not allowed by the JSON specification.
尝试序列化NaN也会引发IllegalArgumentException,因为JSON规范不允许这个值。
For the same reason, trying to serialize Double.POSITIVE_INFINITY, NEGATIVE_INFINITY, or NaN also throws an IllegalArgumentException.
出于同样的原因,试图序列化Double.POSITIVE_INFINITY、NEGATIVE_INFINITY或NaN也会抛出IllegalArgumentException。
4. Deserializing Primitive Types
4.反序列化原始类型
Let’s take a look now at how we would deserialize the JSON string obtained in the previous example.
现在让我们来看看我们如何反序列化前面例子中得到的JSON字符串。
The deserialization is as easy as the serialization:
反序列化和序列化一样简单。
Gson gson = new Gson();
PrimitiveBundle model = gson.fromJson(json, PrimitiveBundle.class);
Finally, we can verify the model contains the desired values:
最后,我们可以验证该模型包含所需的值。
assertEquals(17, model.byteValue);
assertEquals(3, model.shortValue);
assertEquals(3, model.intValue);
assertEquals(3, model.longValue);
assertEquals(3.5, model.floatValue, 0.0001);
assertEquals(3.5, model.doubleValue, 0.0001);
assertTrue(model.booleanValue);
assertEquals('a', model.charValue);
4.1. Deserializing String Values
4.1.对字符串值进行反序列化
When a valid value is put within a String, Gson parses it and handles it expectedly:
当一个有效的值被放在一个字符串中时,Gson会解析它并进行预期的处理。
String json = "{\"byteValue\": \"15\", \"shortValue\": \"15\", "
+ "\"intValue\": \"15\", \"longValue\": \"15\", \"floatValue\": \"15.0\""
+ ", \"doubleValue\": \"15.0\"}";
Gson gson = new Gson();
PrimitiveBundleInitialized model = gson.fromJson(json, PrimitiveBundleInitialized.class);
assertEquals(15, model.byteValue);
assertEquals(15, model.shortValue);
assertEquals(15, model.intValue);
assertEquals(15, model.longValue);
assertEquals(15, model.floatValue, 0.0001);
assertEquals(15, model.doubleValue, 0.0001);
It is worth noting that string values can’t be deserialized into boolean types.
值得注意的是,字符串值不能被反序列化为布尔类型。
4.2. Deserializing Empty String Values
4.2.反序列化空的字符串值
On the other hand, let’s try to deserialize the following JSON with empty strings:
另一方面,让我们尝试用空字符串反序列化下面的JSON。
String json = "{\"byteValue\": \"\", \"shortValue\": \"\", "
+ "\"intValue\": \"\", \"longValue\": \"\", \"floatValue\": \"\""
+ ", \"doubleValue\": \"\"}";
Gson gson = new Gson();
gson.fromJson(json, PrimitiveBundleInitialized.class);
This raises a JsonSyntaxException because empty strings are not expected when deserializing primitives.
这将引发一个JsonSyntaxException,因为在反序列化基元时不希望出现空字符串。
4.3. Deserializing Null Values
4.3.对空值进行反序列化
Trying to deserialize a field with the value null will result in Gson ignoring that field. For example, with the following class:
试图反序列化一个值为null的字段,将导致Gson忽略该字段。例如,用下面这个类。
public class PrimitiveBundleInitialized {
public byte byteValue = (byte) 1;
public short shortValue = (short) 1;
public int intValue = 1;
public long longValue = 1L;
public float floatValue = 1.0f;
public double doubleValue = 1;
}
Gson ignores the null fields:
Gson忽略了空字段。
String json = "{\"byteValue\": null, \"shortValue\": null, "
+ "\"intValue\": null, \"longValue\": null, \"floatValue\": null"
+ ", \"doubleValue\": null}";
Gson gson = new Gson();
PrimitiveBundleInitialized model = gson.fromJson(json, PrimitiveBundleInitialized.class);
assertEquals(1, model.byteValue);
assertEquals(1, model.shortValue);
assertEquals(1, model.intValue);
assertEquals(1, model.longValue);
assertEquals(1, model.floatValue, 0.0001);
assertEquals(1, model.doubleValue, 0.0001);
4.4. Deserializing Values That Overflow
4.4.对溢出的值进行反序列化
This is a very interesting case that Gson handles unexpectedly. Trying to deserialize:
这是一个非常有趣的案例,Gson的处理方式出乎意料。试图进行反序列化。
{"value": 300}
With the model:
有了这个模型。
class ByteExample {
public byte value;
}
As a result, the object has a value of 44. It is handled poorly because in these cases an exception could be raised instead. This would prevent undetectable mistakes propagating through the application.
结果,该对象的值为44。它的处理方式很差,因为在这些情况下,可以提出一个异常来代替。这将防止无法检测的错误在应用程序中传播。
4.5. Deserializing Floating-Point Numbers
4.5.对浮点数字进行反序列化
Next, let’s try to deserialize the following JSON into a ByteExample object:
接下来,让我们尝试将下面的JSON反序列化为一个ByteExample对象。
{"value": 2.3}
Gson here does the right thing and raises a JsonSyntaxException whose subtype is a NumberFormatException. It doesn’t matter which discrete type we use (byte, short, int or long), we get the same result.
Gson在这里做了正确的事情,引发了一个JsonSyntaxException,其子类型是NumberFormatException。不管我们使用哪种离散类型(byte, short, int or long),我们都会得到相同的结果。
If the value ends in “.0”, Gson will deserialize the number as expected.
如果该值以”.0 “结尾,Gson将按照预期对该数字进行反序列化。
4.6. Deserializing Numeric Boolean Values
4.6.对数字布尔值进行反序列化
Sometimes, a boolean is codified as 0 or 1 instead of “true” or “false”. Gson doesn’t allow this by default. For example, if we try to deserialize:
有时,一个布尔值被编为0或1,而不是 “真 “或 “假”。Gson默认是不允许这样的。例如,如果我们尝试反序列化。
{"value": 1}
into the model:
进入模型。
class BooleanExample {
public boolean value;
}
Gson raises a JsonSyntaxException with an exception subtype of IllegalStateException. This is in contrast with the NumberFormatException raised when numbers didn’t match. If we wanted to change that we could use a custom deserializer.
Gson会引发一个JsonSyntaxException,其异常子类型为IllegalStateException。这与数字不匹配时引发的NumberFormatException形成对比。如果我们想改变这一点,我们可以使用自定义反序列化器。
4.7. Deserializing Unicode Characters
4.7.对Unicode字符进行反序列化
It is worth noting that deserialization of Unicode characters requires no extra configuration.
值得注意的是,Unicode字符的反序列化不需要额外的配置。
For example, the JSON:
例如,JSON。
{"value": "\u00AE"}
Will result in the ® character.
将导致®字符。
5. Conclusion
5.结论
As we have seen, Gson provides a straightforward way to work with JSON and Java primitive types. There are some unexpected behaviors to be aware of, even when dealing with simple primitive types.
正如我们所看到的,Gson提供了一种直接的方式来处理JSON和Java的原始类型。即使在处理简单的原始类型时,也有一些意外的行为需要注意。
The full implementation of this article can be found in the GitHub project – this is an Eclipse based project, so it should be easy to import and run as it is.
本文的完整实现可以在GitHub项目中找到 – 这是一个基于Eclipse的项目,所以应该很容易导入并按原样运行。