【问题标题】:Java: (Partial) Serialization of classes (not objects!)Java:(部分)类的序列化(不是对象!)
【发布时间】:2014-12-11 20:49:32
【问题描述】:

我目前正在执行一项任务,将组件及其依赖项打包在一起,并从中制作一个独立的组件,其中包含所有需要的东西。

我的情况是,我可能有用户定义的类,我也需要在这个组件中包含这些类。

我正在寻找一种以苗条/智能方式对它们进行序列化的方法。例如,这些类具有继承层次结构:

FrameWorkSuper
--------------
UserSuper 
UserClass

有没有办法只序列化类的用户定义部分以保持占用空间小?源自框架的任何东西都肯定包含在最终组件中。因此,我想序列化并稍后仅加载整个用户定义的部分,以便类获得框架部分也在包中。

有没有办法实现这个目标或我应该使用的任何建议?

【问题讨论】:

  • 序列化正在持久化对象的状态。当您说“任何源自框架的东西都肯定包含在最终组件中”时,意味着您已经将数据存储在某个地方,可用于输入框架类或如何重新填充框架类对象的数据/属性?
  • 如果你说的是类的而不是instances,那么子类肯定不包含超类的东西吗?子类 instance 将被序列化以包含来自超类的字段,但子类本身不应包含超类的字段和方法。

标签: java serialization classloader


【解决方案1】:

我认为您要做的是传输用户定义类的实际字节码。

  1. 如果你没有类的字节码而只有源代码,你需要先编译它。我建议使用JavaCompiler
    • 由于将所有内容编译到磁盘然后再次读取到字节数组有点繁琐,您可能希望使用自己的 FileManager 和 JavaFileObject 实现,如有必要,我可以提供有关此步骤的详细信息。
  2. 获得类的字节码后,将其发送到您想要的任何位置(文件、数据库、远程站点)。
  3. 当“反序列化”时(正如其他人指出的,序列化并不是真正正确的术语),从您拥有的任何地方加载字节码。
  4. 创建一个自定义类加载器,它获取所有类的字节码并将其 findClass 方法覆盖为类似

    // first try our cache of loaded classes
    if (loadedClasses.containsKey(name)) {
        return loadedClasses.get(name);
    }
    
    // that didn't work, maybe the class was compiled but not yet loaded
    if (compiledClasses.containsKey(name)) {
        // get the representation from the cache
        InMemoryClassJavaFileObject inMemoryRepresentation = compiledClasses.get(name);
        // let our parent define the class
        Class<?> clazz = defineClass(name, inMemoryRepresentation.getData(), 0, inMemoryRepresentation.getData().length);
        // and store it in the cache for later retrieval
        loadedClasses.put(name, clazz);
        return clazz;
    }
    

    注意不需要创建InMemoryClassJavaFileObject,直接使用字节数组即可。

  5. 要实现上述目标,您需要从其字节码中获取类的完全限定名。单独提供该信息或使用this method

这使您可以访问远程站点上的类本身:您可以创建实例并使用它们的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-15
    • 2014-09-24
    • 1970-01-01
    • 2015-11-14
    相关资源
    最近更新 更多