1. 概述

在本教程中,我们将深入探讨如何使用 Gson 对 Java 的原始类型(primitive types)进行序列化与反序列化。Gson 是 Google 提供的一个用于处理 JSON 的库,它支持将 Java 对象转换为 JSON 字符串(序列化),以及将 JSON 字符串转换为 Java 对象(反序列化)。

虽然本文主要关注原始类型的处理,但如果你需要了解数组、集合、嵌套对象或自定义序列化等更复杂的内容,可以参考我们其他的 Gson 序列化和反序列化教程。

2. Maven 依赖

要使用 Gson,首先需要添加其 Maven 依赖:

<dependency> 
    <groupId>com.google.code.gson</groupId> 
    <artifactId>gson</artifactId> 
    <version>2.10.1</version> 
</dependency>

3. 原始类型的序列化

使用 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;
}

接着,初始化一个对象并赋值:

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';

然后进行序列化:

Gson gson = new Gson();
String json = gson.toJson(primitiveBundle);

最终的 JSON 输出如下:

{  
   "byteValue":17,
   "shortValue":3,
   "intValue":3,
   "longValue":3,
   "floatValue":3.5,
   "doubleValue":3.5,
   "booleanValue":true,
   "charValue":"a"
}

注意事项 ✅

  • byte 类型不会以二进制字符串形式输出,而是转换为十进制数字;
  • shortintlong 在 JSON 中没有区别;
  • floatdouble 也没有区分;
  • char 类型在 JSON 中被表示为字符串。

这些行为并不是 Gson 的特殊设计,而是 JSON 格式本身的限制。

3.1 特殊浮点值的序列化 ⚠️踩坑点

Java 中使用 Float.POSITIVE_INFINITYNEGATIVE_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); // ❌ 抛出 IllegalArgumentException

同样地,尝试序列化 NaN 也会失败,因为这些值在 JSON 规范中不被允许。

4. 原始类型的反序列化

我们继续用上一节生成的 JSON 字符串进行反序列化操作:

Gson gson = new Gson();
PrimitiveBundle model = gson.fromJson(json, PrimitiveBundle.class);

验证结果:

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 字符串值的反序列化 ✅

当 JSON 中的值是字符串形式时,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);

⚠️注意:字符串不能反序列化为布尔值。

4.2 空字符串的反序列化 ❌

尝试反序列化空字符串会抛出异常:

String json = "{\"byteValue\": \"\", \"shortValue\": \"\", "
  + "\"intValue\": \"\", \"longValue\": \"\", \"floatValue\": \"\""
  + ", \"doubleValue\": \"\"}";

Gson gson = new Gson();
gson.fromJson(json, PrimitiveBundleInitialized.class); // ❌ JsonSyntaxException

4.3 null 值的反序列化 ✅

反序列化时,字段值为 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;
}
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 溢出值的反序列化 ❌

尝试将超出范围的值反序列化到原始类型中,会抛出 JsonSyntaxException

class ByteExample {
    public byte value;
}
@Test(expected = JsonSyntaxException.class)
public void whenDeserializingValueThatOverflows_thenShouldRaiseAnException() {
    Gson gson = new Gson();
    String json = "{\"value\": \"300\"}";
    ByteExample model = gson.fromJson(json, ByteExample.class); // ❌ 抛出异常
}

4.5 浮点数反序列化 ⚠️

如果尝试将小数反序列化为整数类型(如 byteshortintlong),会抛出 NumberFormatException

{"value": 2.3}

但如果以 .0 结尾,如 "2.0",Gson 会正常解析。

4.6 数字布尔值 ❌

Gson 不支持将数字(如 0 或 1)反序列化为布尔值:

{"value": 1}
class BooleanExample {
    public boolean value;
}

会抛出 IllegalStateException 类型的 JsonSyntaxException

若需要支持,可使用自定义反序列化器。

4.7 Unicode 字符 ✅

Gson 可以直接反序列化 Unicode 字符:

{"value": "\u00AE"}

结果为 ® 字符。

5. 总结

Gson 为原始类型的序列化与反序列化提供了简单直观的支持,但在处理一些边界情况时,仍需小心应对。例如空字符串、溢出值、特殊浮点数等都可能导致异常。

本文的完整代码可在 GitHub 项目 中找到,项目基于 Eclipse,可直接导入运行。


原始标题:Working with Primitive Values in Gson