当前位置: 首页 > 知识库问答 >
问题:

如何使用自定义类加载器反序列化对象?

洪伟彦
2023-03-14

在一个项目中,我需要用自定义类加载器扩展标准类加载器。这样做的主要动机是在运行时扩展类路径。(有关此问题的解决方案,请参阅:https://stackoverflow.com/a/51584718/231397 ).

通过

ObjectOutputStream out;
try {
  FileOutputStream fos = new FileOutputStream(filename);
  out = new ObjectOutputStream(fos);
  out.writeObject(object);
}
catch(FileNotFoundException e) {}
catch (IOException e) { }
finally {
  out.close();
}

工作正常,同时通过反序列化对象

Object object = null;
ObjectInputStream in;
try {
  FileInputStream fis = new FileInputStream(filename);
  ObjectInputStream in = new ObjectInputStream(fis);
  object = in.readObject();
}
catch(FileNotFoundException e) {}
catch (ClassNotFoundException e) {}
finally {
  in.close();
}

失败,出现ClassNotFoundExctive异常。原因是调用了标准类加载器,它不知道自定义类加载器。

问:使用自定义类加载器反序列化对象的正确方法是什么?

共有1个答案

江同化
2023-03-14

(注:在网上搜索了解决方案后,我对自己的问题给出了答案。一个人在网上找到的一些解决方案是“几乎正确的”:它不适用于内部类)。

解决方案是扩展ObjectInputStream并重写方法resolveClass(ObjectStreamClass)这可以通过匿名类完成。然后使用类。forName内部使用自定义类加载器解析类。就是

Object object = null;
try {
  FileInputStream fis = new FileInputStream(filename);
  ObjectInputStream in = new ObjectInputStream(fis) {
    @Override
    public Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
      try {
        return Class.forName(desc.getName(), true, customClassLoader);
      } catch (Exception e) { }

      // Fall back (e.g. for primClasses)
      return super.resolveClass(desc);
    }
  };

  object = in.readObject();
}
catch(FileNotFoundException e) {}
catch (ClassNotFoundException e) {}
finally {
  in.close();
}

备注:您可能会找到建议使用的解决方案

customClassLoader.loadClass(desc.getName());

而不是

Class.forName(desc.getName(), true, customClassLoader)

虽然这在许多情况下可能有效,但它可能有问题。例如,我发现CustClassLoader.loadClass(desc.getName())不适用于内部类(可能是由于包p解析为p时内部类B的命名不同。另请注意,loadClass不会初始化类,请参见https://stackoverflow.com/a/7099453/231397

 类似资料:
  • JSON文档有一个属性,其中包含一组对象(也可以是使用属性名称作为键的映射)。这是唯一一个在JSON中完全序列化columns对象的地方。在其他任何地方,列都使用唯一的属性进行引用 引用可用于映射键和值 我想将此文档反序列化并: 解析属性中对应对象的引用 使用相同的java对象实例(列类是不可变的),而不是每次都创建一个新的。(我想减少对象的数量) JsonIdtyInfoesnt不适用于地图键。

  • 问题内容: 确定,所以我编辑了问题,因为它不够清楚。 编辑2 :更新了JSON文件。 我在Android应用程序中使用GSON,我需要解析来自服务器的JSON文件,这些文件有点太复杂了。我不想让我的对象结构太沉重,所以我想简化内容: 所以我的对象的结构将不是JSON文件的结构。 例如,如果在JSON中,我有以下内容: 我不想保留我当前的对象结构,即一个对象,其中包含一个和一个“总计”。但是我只想将

  • 问题内容: 我有一堂课 我想将下面的JSON数据反序列化到上面的类/对象中 我的想法是在JSON中是一个对象,但我只想获取(在JSON中)在反序列化期间将像在类中那样传递。 如何使用Json.NET实现该目标? 我相信我可以使用CustomJsonConverter完成它。但是我很困惑。docs中的示例仅用于,但不适用。 问题答案: 我只是使用上面在问题中提到的方法解决了我的问题。在我完整的代码下

  • 我得到了。了解调用相同的反序列化器。是否有一种方法可以在custome反序列化器中使用或?

  • 我想通过扩展默认的反序列化器来创建自己的反序列化器,在其后面设置更多的值: 如您所见,我还想将此DTO母类重用于其他DTO。 我没有找到任何这样的例子。我真的是世界上第一个 反序列化的“AsUsual”(p,ctxt)应该是什么 我应该使用什么motherclass?JsonDeserializer/StdDeserializer/UntypedObjectDeserializer 反序列化程序会

  • 问题内容: 我有以下课程,将其用作字典中的键: 我正在运行的测试在这里: 测试失败,因为Json.Net似乎正在使用字典键上的方法,而不是正确地序列化它们。上面测试得出的json是: 这显然是错误的。我如何使它工作? 问题答案: 这应该可以解决问题: 序列化: 通过调用,您正在序列化一个对象数组而不是字典。 反序列化: 在这里,您可以反序列化数组,然后通过调用检索字典。 我不确定输出是否满足您的期