【发布时间】:2011-01-26 13:26:56
【问题描述】:
我得到字节和对象类型的函数消息数组,我需要从字节中恢复对象。 Java 中有没有像 C++ 那样的演员表?
【问题讨论】:
标签: java
我得到字节和对象类型的函数消息数组,我需要从字节中恢复对象。 Java 中有没有像 C++ 那样的演员表?
【问题讨论】:
标签: java
不,您可以改用serialization。
【讨论】:
Java 中没有办法让任意字节块,然后告诉编译器“您需要将其视为 X 类型的对象”。
您想要“恢复到对象”的那些字节最初是如何创建的?
Java 有一种序列化机制,可以将对象转换为字节流,反之亦然。
【讨论】:
我不确定您在这里问的是什么,但 Java 中的每个对象(包括数组)都有与之关联的运行时类型信息。因此,当您将对象转换为不同的类型时,如果新类型不匹配,则会立即引发异常。这与 C/C++ 非常不同,在 C/C++ 中,您可以告诉编译器将内存块视为您想要的任何对象。
如果您正在寻找将任意字节集转换为对象的代码,反之亦然,您需要采用不同的方式,使用内置的序列化工具或滚动您自己的转换代码.
【讨论】:
不,您需要序列化您的对象。 http://java.sun.com/developer/technicalArticles/Programming/serialization/
如果您的对象数据预计可以用其他语言读取,这可能没有用。
【讨论】:
reinterpret_cast 可以在 Java 中进行相当程度的模拟,但不能直接反序列化整个对象。正如其他人所建议的那样,Java 的内置序列化机制或其他第三方序列化库将是您的朋友,除非您自己可以在发送端将对象分解为更简单的类型。
至于Java是否有reinterpret_cast等价物的具体问题,答案是部分肯定的。如果您尝试从二进制数据流中读取原语,ByteBuffer 是您的朋友。将它包裹在一个字节数组中,告诉它数据是小端还是大端,然后使用它的各种方法来解码数据。这可以用来模拟各种 C++ reinterpret_cast 从字节到 32 位整数或浮点数的转换。
【讨论】:
如果你真的想占用一块内存,并把它重新解释为一个java对象,你可以通过sun.misc.Unsafe来实现。
您需要迭代对象的类/类型,找到您需要设置的所有有效字段,从堆外内存缓冲区中读取它们的特定类型,并通过反射设置它们。
我不建议这样做,使用其他序列化机制会是更好的选择。
编辑:可能是这样的:
class Test {
int x;
int y;
}
public static void main(String[] args) throws Exception {
final Unsafe unsafe = Unsafe.getUnsafe();
final int count = 2;
final long address = unsafe.allocateMemory(Integer.BYTES * count);
for (int i = 0; i < count; ++i) {
unsafe.putInt(address + i * Integer.BYTES, ThreadLocalRandom.current().nextInt(0, 10));
}
final Class<Test> klass = Test.class;
final Test test = klass.newInstance();
int i = 0;
for (final Field f : klass.getDeclaredFields()) {
f.setAccessible(true);
f.putInt(test, unsafe.getInt(address + i * Integer.BYTES));
++i;
}
}
当然,您可以轻松地将这些原语重新解释为任何东西。我什至不必Unsafe#putInt,但显然我需要根据Test的整数
【讨论】: