JDK17中如何让Gson序列化java.nio.HeapByteBuffer这类私有类?
解决Gson中ByteBuffer子类无法匹配自定义TypeAdapter的问题
问题原因
你给ByteBuffer.class注册了自定义TypeAdapter,但运行时生成的实例是私有子类HeapByteBuffer。Gson的registerTypeAdapter仅匹配精确类型,不会自动适配子类,因此序列化时找不到对应适配器,只能默认输出对象的字段信息。
解决方案
改用GsonBuilder的registerTypeHierarchyAdapter方法,该方法会匹配指定类及其所有子类的类型,无论实例是HeapByteBuffer还是DirectByteBuffer,都会使用你的自定义适配器。
修改后的代码示例
- 自定义TypeAdapter(优化后兼容DirectByteBuffer):
class ByteBufferTypeAdapter implements JsonDeserializer<ByteBuffer>, JsonSerializer<ByteBuffer> { @Override public JsonElement serialize(ByteBuffer src, Type typeOfSrc, JsonSerializationContext context) { byte[] bytes; // 兼容HeapByteBuffer和DirectByteBuffer if (src.hasArray()) { bytes = src.array(); } else { bytes = new byte[src.remaining()]; // 读取字节后重置缓冲区位置,避免影响后续使用 src.get(bytes).rewind(); } return new JsonPrimitive(Base64.getEncoder().encodeToString(bytes)); } @Override public ByteBuffer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { byte[] bytes = Base64.getDecoder().decode(json.getAsString()); return ByteBuffer.wrap(bytes); } }
- 调整Gson构建代码:
private static Gson GSON = new GsonBuilder() // 替换registerTypeAdapter为registerTypeHierarchyAdapter .registerTypeHierarchyAdapter(java.nio.ByteBuffer.class, new ByteBufferTypeAdapter()) .registerTypeAdapter(Instant.class, (JsonSerializer<Instant>) (src, typeOfSrc, context) -> new JsonPrimitive(src.toString())) .create();
验证效果
重新运行测试代码:
ByteBuffer test = ByteBuffer.wrap("Hello".getBytes(StandardCharsets.UTF_8)); String asJson = GSON.toJson(test);
此时会调用自定义serialize方法,输出Base64编码的字符串,而非对象字段信息。
内容的提问来源于stack exchange,提问作者Jeroen Dirks
相关产品推荐
相关产品推荐

