Gson:序列化java.nio.Path会导致堆栈溢出错误

nxagd54h  于 2022-11-06  发布在  Java
关注(0)|答案(2)|浏览(289)

序列化此对象会导致StackOverFlowError:

  1. import java.nio.file.Path;
  2. import java.nio.file.Paths;
  3. public class Tmp{
  4. private Path path=null;
  5. public Tmp() {
  6. path=Paths.get("c:\\temp\\");
  7. }
  8. }

在我看来这是一个bug!或者我做错了什么?有什么解决方法吗(希望编写一些自定义的序列化程序,将路径转换为字符串)

  1. java.lang.StackOverflowError
  2. at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:372)
  3. at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:381)
  4. at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:376)
  5. ...
  6. at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:128)
  7. at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:75)
  8. at com.google.gson.Gson.getAdapter(Gson.java:358)
  9. at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getFieldAdapter(ReflectiveTypeAdapterFactory.java:109)
  10. at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.access$100(ReflectiveTypeAdapterFactory.java:46)
  11. at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:84)
  12. at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:83)
  13. at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:129)
  14. ...

序列化方法为:

  1. public static void saveTo(BatchLogging logging, Path path) throws IOException {
  2. Gson gson=new GsonBuilder().setPrettyPrinting().create();
  3. // String json = gson.toJson(logging);
  4. String json = gson.toJson(new Tmp());
  5. List<String> lines = Arrays.asList(json.split(System.lineSeparator()));
  6. Files.write(path, lines, StandardCharsets.UTF_8);
  7. }
gkl3eglg

gkl3eglg1#

在调试器中检查Paths.get("c:\\temp\\");返回的对象。在我的机器上,它有一个名为fs的字段,其中包含一个WindowsFileSystem。它又有一个字段provider,其中包含一个WindowsFileSystemProvider-provider有一个字段theFileSystem,其中包含与原始fs字段相同的WindowsFileSystem。瞧,循环引用。
Gson使用反射递归地检查和序列化对象中的每个非 transient 字段。像这样的循环引用会将其发送到无限递归中,以StackOverflowError结束。要解决此问题,您将需要实现自定义序列化或序列化Path的特定属性而不是整个对象。将循环中涉及的任何或所有字段标记为transient也可以,但这需要对库代码的写访问权限。

icnyk63a

icnyk63a2#

您可以使用ExclusionStrategy来排除某些类型的类别,也可以使用GsonBuilder.registerTypeAdapter来实作自订序列化/还原序列化。
check out the docs

相关问题