我有以下问题:我希望通过线路发送一个类型(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, ..
但遗憾的是我没有看到如何检索已加载类的bytcode。 我正在寻找类似的东西:
byte[] byteCode = MyClass.class.toByteArray();
这是否可以使用标准JDK,或者是否有任何小型lib可以做到这一点?
答案 0 :(得分:5)
我不认为你想要什么是完全普遍的。从字节码定义类的行为是不可逆的。但是,您应该能够直接读取字节码文件(假设它是URLClassLoader
):
MyClass.class.getResourceAsStream("Myclass.class")
或者,您可以通过HTTP访问类文件,并直接在接收方使用URLClassLoader
。
答案 1 :(得分: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/
答案 2 :(得分:0)
您应该检查java serialization interface
编辑:
我重新阅读了你的帖子,而你正在谈论在另一方面定义课程。这让我想到你要完成的是distribute objects across the network。
此外,如果您的服务器和客户端共享相同的界面,您只需通过java reflection
创建对象答案 3 :(得分:-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。
无论您使用哪个平台,序列化都是一个问题。