Reputation: 1043
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
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:
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
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