java—如何序列化实现可序列化但包含不可序列化字段的对象?

nfs0ujit  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(527)

我使用的特定库是apachecommons csv库v1.8(最新版本)。我试图序列化一个包含csvrecord的对象,但让我们看看它的代码:

public final class CSVRecord implements Serializable, Iterable<String> {
    private static final String[] EMPTY_STRING_ARRAY = new String[0];
    private static final long serialVersionUID = 1L;
    private final long characterPosition;
    private final String comment;
    private final long recordNumber;
    private final String[] values;
    private final CSVParser parser;

它实现了 Serializable 但是,它包含一个不可序列化的csvparser:

public final class CSVParser implements Iterable<CSVRecord>, Closeable {
    private final CSVFormat format;
    private final Map<String, Integer> headerMap;
    private final List<String> headerNames;
    private final Lexer lexer;
    private final CSVParser.CSVRecordIterator csvRecordIterator;
    private final List<String> recordList;
    private long recordNumber;
    private final long characterOffset;
    private final Token reusableToken;

有没有什么方法可以绕过这个问题而不改变库,使之成为一个 transient 场?这仅仅是作者的疏忽,还是有什么方法可以序列化csvrecord而我却看不到?

okxuctiv

okxuctiv1#

接得好!:)我也检查了代码,发现没有办法不触及库代码就解决这个问题。但在我看来,即使这样也有问题。
我想原因是 CSVParser 不是 Serializable 是因为它在读取完成之前保持文件打开。如果允许序列化,则意味着在反序列化期间(可能在另一个系统上,或者在文件不再存在时),对象仍然引用文件!
因此,即使您将库代码更改为 finalCSVParser 并编写一个可序列化的子类或make parser 字段 transientCSVRecord ,它仍然没有帮助,因为反序列化类将无法工作,如上所述。
因此,我认为只有非类序列化的方式是可行的(例如,对json或 Map 等)。

hvvq6cgz

hvvq6cgz2#

使用 transient java的关键字。
变量可以标记为transient,以表明它们不是对象持久状态的一部分。
所以上面的可序列化类

public final class CSVRecord implements Serializable, Iterable<String> {
    private static final String[] EMPTY_STRING_ARRAY = new String[0];
    private static final long serialVersionUID = 1L;
    private final long characterPosition;
    private final String comment;
    private final long recordNumber;
    private final String[] values;
    private final transient CSVParser parser;
    ..
    ..
    ..
}

相关问题