在Java中是否存在类似于C ++中的<reinterpret_cast> </reinterpret_cast>

时间:2011-01-26 13:26:56

标签: java

我得到了我的函数消息字节数组和对象类型,我需要从字节中恢复对象。在Java中是否存在类似C ++的演员?

7 个答案:

答案 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