我得到了我的函数消息字节数组和对象类型,我需要从字节中恢复对象。在Java中是否存在类似C ++的演员?
答案 0 :(得分:7)
不,您可以改用serialization。
答案 1 :(得分:5)
Java中没有任何方法可以使用任意字节块,然后告诉编译器“你需要将它视为X类型的对象”。
您想要“恢复到对象”的那些字节是如何创建的?
Java有一个序列化机制,可以将对象转换为字节流,反之亦然。
答案 2 :(得分:3)
我不确定你在这里问什么,但Java中的每个对象(包括数组)都有与之关联的运行时类型信息。因此,当您将对象转换为其他类型时,如果新类型不匹配,则会立即抛出异常。这与C / C ++非常不同,你可以告诉编译器将内存块视为你想要的任何对象。
如果您正在寻找将任意字节集转换为对象的代码,反之亦然,您需要以不同的方式执行此操作,使用内置的序列化工具或滚动您自己的转换代码
答案 3 :(得分:2)
不,您需要序列化您的对象。 http://java.sun.com/developer/technicalArticles/Programming/serialization/
如果您希望对象数据可以在其他语言中读取,那么这可能没用。
答案 4 :(得分:0)
这是完成你想要的方法。
public static Object toObjectFromByteArray(byte[] byteArr) {
if (byteArr == null) {
return null;
}
Object resultObj = null;
ByteArrayInputStream bin = null;
ObjectInputStream ooin = null;
try {
bin = new ByteArrayInputStream(byteArr);
ooin = new ObjectInputStream(bin);
resultObj = ooin.readObject();
}
catch (Exception ex) {
throw new RuntimeException(ex);
}
finally {
try {
if (ooin != null) {
ooin.close();
}
if (bin != null) {
bin.close();
}
}
catch (IOException ex1) {
ex1.printStackTrace();
}
}
return resultObj;
}
public static byte[] toByteArray(Object obj) {
ByteArrayOutputStream barr = null;
ObjectOutputStream oout = null;
byte[] bytearr = null;
try {
byte[] b2 = null;
barr = new ByteArrayOutputStream(10000);
oout = new ObjectOutputStream(barr);
oout.writeObject(obj);
oout.flush();
oout.close();
bytearr = barr.toByteArray();
}
catch (Exception ex) {
throw new RuntimeException(ex);
}
finally {
try {
if (oout != null) {
oout.close();
}
if (barr != null) {
barr.close();
}
}
catch (IOException ex1) {
ex1.printStackTrace();
}
}
return bytearr;
}
答案 5 :(得分:0)
<bean id="connectionFactory" class="org.springframework.jms.connection.DelegatingConnectionFactory">
<property name="targetConnectionFactory">
<jee:jndi-lookup jndi-name="someConnectionFactory"/>
</property>
<property name="shouldStopConnections" value="true"/>
</bean>
可以在Java中进行一定程度的仿真,尽管不能直接反序列化整个对象。正如其他人所建议的那样,除非您自己有能力在发送端将对象分解为更简单的类型,否则Java的内置序列化机制或其他第三方序列化库将是您的朋友。
对于Java是否具有等效reinterpret_cast
的特定问题,答案是部分肯定的。如果您尝试从二进制数据流中读取基元,那么reinterpret_cast
是您的朋友。将其包装在一个字节数组周围,告诉它数据是小字节序还是大字节序,然后使用其各种方法来解码数据。可以用来模拟各种C ++ ByteBuffer
从字节到32位整数或浮点数的转换。
答案 6 :(得分:0)
如果您真的想占用一块内存,并将其重新解释为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