Java 如何反序列化 Class 对象,同时保留其与当前加载的 Class 对象的身份?
How can Java deserialize Class objects while preserving their identity to currently loaded Class objects?
如果我序列化一个 Class
对象(例如,HashMap.class
),然后在另一个 JVM 实例中反序列化它,事实证明反序列化的 class 与当前加载的那个:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
final class DeserializationTest {
static String path = "/home/suseika/test.ser";
static Class<HashMap> cls = HashMap.class;
public static void main(String[] args) throws Exception {
if (args[0].equals("serialize")) {
serialize();
} else if (args[0].equals("deserialize")) {
final Object deserialized = deserialize();
// The important line, prints "true"
System.out.println(deserialized == cls);
}
}
static Object deserialize() throws Exception {
ObjectInputStream in = new ObjectInputStream(new FileInputStream(path));
return in.readObject();
}
static void serialize() throws Exception {
FileOutputStream fileOut = new FileOutputStream(path);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(cls);
out.close();
fileOut.close();
}
}
在这种情况下,Java 如何能够反序列化对象以保留身份? Class
似乎没有实现 writeObject()
/readObject()
/readResolve()
.
是否可以通过在序列化期间加载特定 class/using 特定 classloader/using 特定 JVM setup/doing 某些内容来打破此行为?是否存在加载的 Class
与反序列化的不同的实例?换句话说,我可以在我的应用程序中依靠这种行为来序列化和反序列化 Class
个对象吗?
How is Java able to deserialize objects in this case so that identity is preserved? Class
doesn't seem to implement writeObject()/readObject()/readResolve()
.
它不需要实现 readObject()
或 writeObject()
来完成这个,但它可以通过实现 readResolve()
或通过 ObjectInputStream
中的特殊逻辑来实现.
How is Java able to deserialize objects in this case so that identity is preserved?
这是因为 class 个实例由 classloader 缓存。
Does Java guarantee that Object.getClass() == Object.getClass()?
Can this behavior be broken with loading a particular class/using a particular classloader/using a particular JVM setup/doing something during serialization?
对于来自不以 java.*
开头的包的 classes 的序列化实例,这可以在 ObjectInputStream
中使用不同的 classloader 来打破(例如 here).
对于 java.*
中的 classes,就像你的情况 (java.lang.Class
),只有 Bootstrap class 加载程序可以加载它们,并且鉴于 class 定义在每个 class 加载程序中是唯一的(由 JVM spec 保证)
In other words, can I rely on this behavior in my application to serialize and deserialize Class objects
是
如果我序列化一个 Class
对象(例如,HashMap.class
),然后在另一个 JVM 实例中反序列化它,事实证明反序列化的 class 与当前加载的那个:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
final class DeserializationTest {
static String path = "/home/suseika/test.ser";
static Class<HashMap> cls = HashMap.class;
public static void main(String[] args) throws Exception {
if (args[0].equals("serialize")) {
serialize();
} else if (args[0].equals("deserialize")) {
final Object deserialized = deserialize();
// The important line, prints "true"
System.out.println(deserialized == cls);
}
}
static Object deserialize() throws Exception {
ObjectInputStream in = new ObjectInputStream(new FileInputStream(path));
return in.readObject();
}
static void serialize() throws Exception {
FileOutputStream fileOut = new FileOutputStream(path);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(cls);
out.close();
fileOut.close();
}
}
在这种情况下,Java 如何能够反序列化对象以保留身份? Class
似乎没有实现 writeObject()
/readObject()
/readResolve()
.
是否可以通过在序列化期间加载特定 class/using 特定 classloader/using 特定 JVM setup/doing 某些内容来打破此行为?是否存在加载的 Class
与反序列化的不同的实例?换句话说,我可以在我的应用程序中依靠这种行为来序列化和反序列化 Class
个对象吗?
How is Java able to deserialize objects in this case so that identity is preserved?
Class
doesn't seem to implementwriteObject()/readObject()/readResolve()
.
它不需要实现 readObject()
或 writeObject()
来完成这个,但它可以通过实现 readResolve()
或通过 ObjectInputStream
中的特殊逻辑来实现.
How is Java able to deserialize objects in this case so that identity is preserved?
这是因为 class 个实例由 classloader 缓存。
Does Java guarantee that Object.getClass() == Object.getClass()?
Can this behavior be broken with loading a particular class/using a particular classloader/using a particular JVM setup/doing something during serialization?
对于来自不以 java.*
开头的包的 classes 的序列化实例,这可以在 ObjectInputStream
中使用不同的 classloader 来打破(例如 here).
对于 java.*
中的 classes,就像你的情况 (java.lang.Class
),只有 Bootstrap class 加载程序可以加载它们,并且鉴于 class 定义在每个 class 加载程序中是唯一的(由 JVM spec 保证)
In other words, can I rely on this behavior in my application to serialize and deserialize Class objects
是