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

强制序列化不可序列化的Java对象?

斜高翰
2023-03-14

我正在试验Stanford CoreNLP库,我想序列化主要的StanfordCoreNLP管道对象,尽管它抛出了一个java.io.NotSerializableException。

完整故事:每当我运行我的实现时,将管道注释器和分类器加载到内存中大约需要15秒。最终进程的内存约为600MB(很容易小到可以存储在我的机箱中)。我想在第一次创建管道后保存它,这样我就可以在以后将其读入内存。

然而,它会抛出一个NotSerializableException。我尝试制作一个实现Serializable的简单子类,但StanfordCoreNLP具有不实现此接口的注释器和分类器属性,并且我无法为所有这些创建子类。

有没有Java库可以序列化一个没有实现Serializable的对象?我想它必须通过它的属性递归,并对任何类似的对象执行相同的操作。

我尝试的序列化代码:

static StanfordCoreNLP pipeline;
static String file = "/Users/ME/Desktop/pipeline.sav";
    static StanfordCoreNLP pipeline() {
    if (pipeline == null) {
        try {
            FileInputStream saveFile = new FileInputStream(file);
            ObjectInputStream read = new ObjectInputStream(saveFile);
            pipeline = (StanfordCoreNLP) read.readObject();
            System.out.println("Pipeline loaded from file.");
            read.close();
        } catch (FileNotFoundException e) {
            System.out.println("Cached pipeline not found. Creating new pipeline...");
            Properties props = new Properties();
            props.put("annotators", "tokenize, ssplit, pos, lemma, ner, parse, dcoref");
            pipeline = new StanfordCoreNLP(props);
            savePipeline(pipeline);
        } catch (IOException e) {
            System.err.println(e.getLocalizedMessage());
        } catch (Exception e) {
            System.err.println(e.getLocalizedMessage());
        }
    }
    return pipeline;
}

static void savePipeline(StanfordCoreNLP pipeline) {
    try {
        FileOutputStream saveFile = new FileOutputStream(file);
        ObjectOutputStream save = new ObjectOutputStream(saveFile);
        save.writeObject(pipeline);
        System.out.println("Pipeline saved to file.");
        save.close();
    } catch (FileNotFoundException e) {
        System.out.println("Pipeline file not found during save.");
    } catch (IOException e) {
        System.err.println(e.getLocalizedMessage());
    }
}

共有2个答案

琴献
2023-03-14

如果它不可序列化的唯一原因是它没有标记为Serializable,那么您可能可以使用一些非默认的序列化策略。例如,您可以尝试Jackson或XStream。

这就是说,如果一开始就有充分的理由证明它不可序列化,那么这些策略很可能会以有趣的方式崩溃。彻底测试!

濮丰
2023-03-14

一般来说,表示数据对象的Stanford NLP类(Tree、Lce alizedParser等)是可序列化的,而表示处理器的类(StanfordCoreNLP、Lce alizedParserQuery、CRF分类器)则不是。为了实现您的要求,您需要使许多类可序列化,但它们不是,并处理由此产生的任何后果。

然而,我认为你在你的底层思维中是错误的。StanfordCoreNLP在那15秒内加载的东西主要是标准的java序列化对象。NER分类器和解析器语法是标准的序列化java对象。(有几件事不是这种形式的但只是二进制数据,包括用于POS标记器的数据,主要是由于历史原因。)事实是,用标准Java序列化加载很多对象并不是那么快......你可以在网络上找到关于Java序列化速度的讨论,以及替代方案的速度如何比较。制作一个新的甚至更大的序列化对象,其中包含所有当前的序列化对象,这不可能使它更快。(通过将所有内容都放在一个连续的数据流中,您可能会获得一小部分,但除非您做额外的工作来标记不需要序列化的瞬态字段,否则您几乎肯定会因序列化数据结构的大小增加而失败。)

相反,我认为解决这个问题的关键是只需支付加载系统一次的费用,然后在处理多个句子时将其保存在内存中。

 类似资料:
  • 本文向大家介绍java对象的序列化和反序列化,包括了java对象的序列化和反序列化的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了java对象的序列化和反序列化,供大家参考,具体内容如下 1. 什么是序列化        将对象转换为字节流保存起来,比如保存到文件里,并在以后还原这个对象,这种机制叫做对象序列化。(补充一句:把对象保存到永久存储设备上称为持久化) 2. 怎么实现序列化

  • 问题内容: 我有: 在MyClass2中是无法序列化的属性。如何序列化(和反序列化)此对象? 更正:MyClass2当然不是接口,而是类。 问题答案: 正如其他人指出的那样,Josh Bloch的Effective Java的 第11章是有关Java序列化的必不可少的资源。 该章中与您的问题有关的几点: 假设您要序列化MyClass2中不可序列化字段的状态,则MyClass必须可以直接访问该字段,

  • 问题内容: 如何序列化未实现Serializable的对象?我不能将其标记为Serializable,因为该类来自第3方库。 问题答案: 您不能序列化未实现的类,但可以将其包装在可以实现的类中。为此,您应该在包装器类上实现和,以便可以以自定义方式序列化其对象。 首先,使您的非序列化字段。 在中,首先调用流以存储所有非瞬态字段,然后调用其他方法来序列化不可序列化对象的各个属性。 在中,首先调用流以读

  • 错误: java.lang.ClassNotFoundException:testprocedure.tp$3在java.net.URLClassLoader$1上运行(未知源)在java.net.URLClassLoader上运行(未知源)在java.security.accessController.doprivileged(本机方法)在java.net.URLClassLoader.find

  • 问题内容: 我在android / java中对Location的子类进行序列化遇到了麻烦 位置不可序列化。我有一个名为FALocation的第一个子类,它没有任何实例变量。我已经宣布它可序列化。 然后,我有一个名为Waypoint的第二个类,看起来像这样: 序列化工作正常。 反序列化会产生跟随翼异常(腿对象包含一个航路点): 问题答案: 序列化位置绝对必要吗?也许您可以将其标记为瞬态,并在反序列

  • 如果接口只是一个标记接口,用于在 java 中传递有关类的某种元数据 - 我有点困惑: 在阅读了java的序列化算法(元数据从下到上,然后从上到下的实际实例数据)的过程之后,我无法真正理解哪些数据不能通过该算法进行处理。 简而言之: 哪些数据可能导致? 我怎么知道我不应该为我的类添加子句?