2

我有以下问题:我想通过网络发送一个类型(java.lang.Class)并在另一端“定义”类。

我试过这样:

ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(MyClass.class);

在接收端:

ByteArrayInputStream bis = new ByteArrayInputStream(request.getBytes());
ObjectInputStream ois = new ObjectInputStream(bis);
Class c = (Class) ois.readObject(); // ClassNotFoundException

所以很明显我需要发送类的原始字节码并做一个

ClassLoader.defineClass(bytes, ..

但不幸的是,我看不到如何检索已加载类的字节码。我正在寻找类似的东西:

byte[] byteCode = MyClass.class.toByteArray();

这甚至可以使用标准 JDK,还是有任何小的库可以做到这一点?

4

4 回答 4

5

我不认为你想要的东西是可能的。从字节码定义类的行为是不可逆的。但是,您应该能够做的是直接读取字节码文件(假设它是一个URLClassLoader):

MyClass.class.getResourceAsStream("Myclass.class")

或者,您可以通过 HTTP 访问类文件并直接URLClassLoader在接收端使用。

于 2009-06-02T21:34:44.557 回答
1

你不能凭记忆做到这一点。您必须有定义类的字节码,对于大多数类,可以通过询问 JVM 找到。http://www.exampledepot.com/egs/java.lang/ClassOrigin.html中的这段代码应该可以帮助您入门:

// Get the location of this class
Class cls = this.getClass();
ProtectionDomain pDomain = cls.getProtectionDomain();
CodeSource cSource = pDomain.getCodeSource();
URL loc = cSource.getLocation();  // file:/c:/almanac14/examples/
于 2009-06-02T22:12:50.113 回答
0

你应该检查java序列化接口

编辑 :

我重新阅读了您的帖子,您正在谈论在另一边定义课程。这使我认为您要完成的是通过网络分发对象

此外,如果您的服务器和客户端共享相同的接口,您可以简单地通过java 反射创建对象

于 2009-06-02T21:25:53.547 回答
-3

您可以编写自己的序列化方法。

所以

public byte[] Serialize()
{

// serialize each field in turn here.

return data;
}


public void Deserialize(byte[] data)
{

// deserialize data in the same order it was serialized.

}

这是我们在 .Net 中实现的用于序列化的方法。这种方法的关键是它让您完全负责序列化。如果您不打算拥有此类通信的任何版本,但随着产品的增长,对于多个版本,这是我们发现的为数不多的可靠方法之一。

我们通过实现iserializable接口(java中可能不存在,不过是自己实现的简单接口),使用内存流对象写出各个数据域,复杂对象的级联写入。

我们在企业服务器上使用与在客户端上相同的 dll。

无论您在哪个平台上,序列化都是一个问题。

于 2009-06-02T21:25:54.670 回答