什么是序列化的类数据?

时间:2017-06-27 18:43:14

标签: java class serialization

我一直在想你是否在类似的对象中序列化类数据:

public Something implements Serializable{
     private static final long serialVersionUID = 1L;
     public Class type;
}

实际序列化哪些数据并保存为类型

即使您当时没有加载该类,是否可以从 type 获取simplename和fullname等信息?

2 个答案:

答案 0 :(得分:3)

  

即使您当时没有加载该类,是否可以从类型中获取simplename和fullname等信息?

只要存在类型的类,就会加载Class对象引用的类。

使用以下代码:

class Test implements Serializable {
    // verion UID

    public Class type;

    public Test(Class type) {
        this.type = type;
    }
}

我序列化了一个Test对象,其中包含Class其他类型的对象:Second

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("text.obj"));
out.writeObject(new Test(Second.class));
out.close();

现在,请阅读:

ObjectInputStream in = new ObjectInputStream(new FileInputStream("text.obj"));
Test test = (Test) in.readObject();
in.close();

此代码中没有对Second类的引用。如果在运行上面的程序时加载Second,我们可以假设它是由于反序列化而不是直接引用。

确实如此:

enter image description here

是的,尝试获取type.getSimpleName()之类的内容会有效。

运行:

ObjectInputStream in = new ObjectInputStream(new FileInputStream("text.obj"));
Test test = (Test) in.readObject();
System.out.println(test.type.getSimpleName());
in.close();

打印

Second

删除Second课程后,您会按预期获得ClassNotFoundException。通过读取堆栈跟踪,您可以看到程序尝试加载Second类:

Exception in thread "main" java.lang.ClassNotFoundException: test.Second
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at java.io.ObjectInputStream.resolveClass(Unknown Source)
    at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
    at java.io.ObjectInputStream.readClassDesc(Unknown Source)
    at java.io.ObjectInputStream.readClass(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)

答案 1 :(得分:0)

简单:这将序列化该Class类中存在的所有非瞬态字段。

从这个意义上说:如果你真的关心细节,请转向Class.java的源代码。

第二个问题(如果可以反序列化一个无法加载的类) - 我正在做一个有根据的猜测:我认为这应该失败。重点是:Class对象允许您查询字段,方法,......如果没有关于该类的完全知识,这是不可能的。

但这应该很容易测试。万一今晚没有人能得到更好的答案......明天我会检查并告诉你。