序列化java.lang.class

时间:2012-07-07 10:40:34

标签: java reflection classloader binary-serialization

我在DB中持久化Class对象时遇到了问题。

我尝试使用对象ObjectArrayOutputStreamByteArrayOutputStream将对象转换为字节数组,如下所示,并将其保存为字节数组:

Class klazz = getClassForClassDef();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(klazz);
baos.toByteArray();

但是我收到如下错误:

java.lang.ClassFormatError: Incompatible magic value 2901213189 in class file

我认为构造字节数组的方式存在问题。但我不知道如何创建一个正确的.class等价的类对象。

3 个答案:

答案 0 :(得分:2)

如果您真的想存储Class本身

您可以在此处详细了解:https://stackoverflow.com/a/2390763/1001027

如果您尝试存储对象

您使用Class作为writeObject方法的参数。而不是你应该使用你拥有的实例。


// write the class
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(objectToSerialize);

// this you need to store
byte[] data = baos.toByteArray();

// read it again (just a test)
ByteArrayInputStream bais = new ByteArrayInputStream(data);
Object restored = new ObjectInputStream(bais).readObject();

// write what came from the deserialization
System.out.println(restored);

在示例中,变量objectToSerialize将保存要存储的对象。


您确定要将java序列化对象存储到数据库中吗?有一些替代方案。您可以使用ORM框架(如Hibernate)创建正式模型。

如果您认为这太动态了,您可以使用XML序列化,例如XStream甚至是JSON序列化,这很好,因为它们是可读格式,这意味着您可以看到实际存储的内容,从而无需对其进行反序列化使用Java应用程序来检查状态。

答案 1 :(得分:1)

要序列化一个对象,你必须在对象本身而不是它的类中写入流。此外,对象实例必须实现Serializable接口,并且其所有内部字段应该是可序列化的或瞬态的。

在您的代码中,您应该编写oos.writeObject(klazz);而不是oos.writeObject(obj);,而提供obj是您要保存的对象实例。

但是,如果您正在尝试将Java对象存储到数据库中(我们讨论的是关系数据库,不是吗?)我会将对象映射到表,将其每个属性存储为值的值列。这样你就可以使用SQL和列的值执行搜索和连接,但你不能索引二进制字段。

答案 2 :(得分:1)

.class文件不是序列化的Class对象。它是完全不同的东西,你将无法使用任何简单的Java代码生成它。但是,你为什么要这样做?您已经在磁盘上拥有该.class文件,这就是您的Java程序了解该类的方式。你为什么不复制那个.class文件?这只是一个找到它来自何处的问题(什么是JAR)。