首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >序列化/反序列化机制

序列化/反序列化机制
EN

Stack Overflow用户
提问于 2011-12-21 07:46:34
回答 4查看 20.7K关注 0票数 5

比如说,我有一个类X,它有一个字段值,也就是说,

代码语言:javascript
复制
class X implements Serializable {
    private int value;
    // ...
}

此外,这里没有显示getter和setter。这个类是序列化的。在反序列化中,端同级有值字段,访问说明符是公共的。此外,该类没有getter和setter。所以,我的问题是:

  1. 如果字段的访问说明符发生更改,或者反序列化结束时类中的部分或所有方法丢失,反序列化是否失败?
  2. 在反序列化过程中,字段分配值的机制是什么?
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-12-21 08:11:42

一些好的链接Java序列化算法揭示

1)在字段的访问说明符发生更改或反序列化结束时类中部分或所有方法丢失时,反序列化是否失败?

使用反射进行序列化

Java使用

private static final long serialVersionUID

默认情况下包含一个哈希码。序列化根据以下信息创建一个类型为long的单一哈希代码:

  • 类名和修饰符
  • 类实现的任何接口的名称。
  • 所有方法和构造函数的描述(私有方法和构造函数除外)
  • 所有字段的描述(私有、静态和私有瞬变除外)

序列化机制的默认行为是一种经典的“比对不起更安全”的策略。序列化机制使用suid (默认为非常敏感的索引)来判断类何时发生了更改。如果是这样,序列化机制拒绝使用与旧类序列化的数据创建新类的实例。

2)在反序列化过程中,字段分配值的机制是什么?

票数 5
EN

Stack Overflow用户

发布于 2011-12-21 08:20:49

真正的细节可以在Java对象序列化规范中阅读。

回答你的问题:

  1. 序列化具有基本的健全性检查,以查看序列化结束时是否使用了类的相同版本:serialVersionUID成员必须相等。阅读流唯一标识符一节,了解更多有关它的信息。基本上,它是一个静态值,您可以通过在类上声明它来管理自己,或者让编译器为您生成一个。如果编译器生成它,对类的任何更改都会导致serialVersionUID的更改,因此,如果端点没有完全相同的类,反序列化就会失败。如果要避免这种情况,请自己声明变量,并在对类的成员变量的更改确实使类不兼容时手动更新它。
  2. Java在这里有很多神奇之处,它可以直接访问所有内部状态,而不需要getter(标记为transientstatic的字段没有序列化)。另外,虽然Serializable接口没有指定实现的任何方法,但是您可以声明一些“神奇的方法”来影响序列化过程。阅读"writeObject方法“部分并继续了解更多信息。但是要注意,您应该谨慎地使用这些,因为它们可能会混淆任何维护开发人员!
票数 3
EN

Stack Overflow用户

发布于 2011-12-21 08:00:03

您不需要使用getters/setter来使用java序列化来序列化/反序列化,例如,检查以下代码:

代码语言:javascript
复制
public class Main {

    public static class Q implements Serializable {
        private int x;
        public Q() {
            x = 10;
        }
        public void printValue() {
            System.out.println(x);
        }
    }

    public static void main(String[] args) throws Exception {
        Q q = new Q();
        FileOutputStream fos = new FileOutputStream("c:\\temp.out");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(q);
        fos.close();

        FileInputStream fis = new FileInputStream("c:\\temp.out");
        ObjectInputStream oin = new ObjectInputStream(fis);
        Q q2 = (Q)oin.readObject();
        fis.close();
        q2.printValue();

    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8586511

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档