如何在Java中创建类似于C语言风格的联合体?

9

我需要将我的一个代码段从C语言转换成Java语言。下面是给出的代码:

union commandString{
    char commndStr[20];
    struct{
        char commnd[4];
        char separator1;
        char agr1[5];
        char separator2;
        char arg2[3];
        char separator3;
        char additionalArg[5];
    };
};

我不想使用任何显式解析器,或者我不想使用。
System.arraycopy

方法。 有没有办法按照我的喜好来做呢?


1
如果你真的想使用C结构来完成Java故意不提供的功能,你可以编写C代码并通过Java Native Interface进行调用。但我不建议这样做。为什么不编写帮助方法来提取commndStr的每个部分呢? - user2357112
我已经成功地让它工作了。但出于好奇心,我问了这个问题,是否有其他方法。 - Saikat
直接将习语从一种语言翻译成另一种语言是愚蠢的行为。与其在Java中编写C,你应该问什么是以你的格式解析字符串的最佳方法。 - that other guy
直接将习语从一种语言翻译成另一种语言是愚蠢的行为。与其在Java中编写C,不如询问以您的格式解析字符串的最佳方法。我只是出于好奇而问。 - Saikat
3个回答

12

Java语言不支持像C语言那样直接控制内存布局或使用union。但是,Oracle提供了一个后门,可以通过使用sun.misc.Unsafe类来实现。虽然需要一些工作,但Martin Thompson在他的博客中已经记录了所有细节。

另一个选择是用C编写,并通过JNI从Java作为本地函数进行访问。


呃...我不会用Unsafe来做那个。太容易出错了... - Stephen C
1
不需要直接使用Unsafe。最接近C结构体的是Javolution库中的Structs库。http://javolution.org/apidocs/javolution/io/Struct.html,它还支持http://javolution.org/apidocs/javolution/io/Union.html。 - Peter Lawrey
@PeterLawrey,Javolution看起来很吸引人,让我去看看。无论如何,谢谢。 - Saikat
1
@Stephen,每次使用Jdk时,底层都有可能使用unsafe。例如atomicboolean或readwritelock。如果一个人花时间学习如何使用unsafe,并接受其风险,那么就没有理由避免它。目前正在进行将unsafe的部分移入核心语言和API的辩论。然而,PeterLawrey说得很好,将其放在抽象后重复使用。Peter在这个领域做了一些出色的工作,我赞同他推荐查看javolition和他自己的java lang。 - Chris K

2
结构体和联合体最好的库是 Javolutions,它已经存在多年了。这些都是为此而设计的。
我建议如果您要使用这些 Unsafe,请将其封装在一个库中,以将其抽象化。这可以避免不断遇到会导致 JVM 崩溃的错误(我是指 C 程序员能理解的崩溃)。
我有一个名为 Java-Lang 的库,允许您执行 Java 通常不允许的操作,例如 63 位大小的非堆内存和内存映射、线程安全的非堆操作、在同一台机器上的 JVM 之间共享内存。正如我所说,我使用自己的库来抽象化使用 Unsafe。

1
阅读有关Javolution Union的内容引导我了解了ByteBuffer,它可以用作Union。作为一个只提供一个类的抽象类,您可能需要使用File.createTempFile()创建临时文件,RandomAccessFile(File,“rw”),FileChannel RandomAccessFile.getChannel(),MappedByteBuffer FileChannel.map()。 它具有控制字节与其他类型之间的大端(默认)或小端关系的控件。 如果您只需要一个Union来将类型映射到字节,例如用于trie,则这足够了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接