Moff Kalast
Moff Kalast

Reputation: 1043

What exactly is serialized Class data?

I've been wondering if you serialize class data in an object like so:

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

What data is actually serialized and saved as type?

Is it possible to get info like simplename and fullname from type even if you don't have that class loaded at the time?

Upvotes: 3

Views: 156

Answers (2)

Vince
Vince

Reputation: 15156

Is it possible to get info like simplename and fullname from type even if you don't have that class loaded at the time?

As long as the class for the type is present, the class which the Class object refers to will be loaded.


Using the code below:

class Test implements Serializable {
    // verion UID

    public Class type;

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

I serialized a Test object which contained the Class for a different type: Second

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

Now, reading it back in:

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

There's no reference to the Second class in this code. If Second is loaded when running the program above, we can assume it was due to deserialization rather than direct reference.

And it does:

enter image description here

So yes, attempting to obtain things like type.getSimpleName() will work.

Running:

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

Prints

Second

When you delete the Second class, you get ClassNotFoundException as expected. By reading the stacktrace, you can see that the program attempts to load the Second class:

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)

Upvotes: 3

GhostCat
GhostCat

Reputation: 140573

Simple: this will serialize all non-transient fields that exist in that Class class.

In that sense: turn to the source of Class.java if you really care about the details.

The second question (if it is possible to deserialize a class which can't be loaded) - I am making an educated guess: I think this should fail. The point is: the Class object would allow you to query for fields, methods,... Which is not possible without full knowledge about that class.

But that should be pretty easy to test. In case nobody comes up with a better answer tonight... I will check tomorrow and let you know.

Upvotes: 0

Related Questions