在java中查找系统的终结性

在java中查找系统的终结性,java,jvm,endianness,Java,Jvm,Endianness,我发现当机器是bigindian或littleindian时,checkink的算法(INTC)是 int is_big_endian(void) { union { uint32_t i; char c[4]; } bint = {0x01020304}; return bint.c[0] == 1; } 我怎样才能在*java中找到这样的东西?*我不想使用内置libs,因为这是一个面试问题。我想在java中找到它。JVM,因此ja

我发现当机器是bigindian或littleindian时,checkink的算法(INTC)是

int is_big_endian(void)
{
    union {
        uint32_t i;
        char c[4];
    } bint = {0x01020304};

    return bint.c[0] == 1; 
}

我怎样才能在*java中找到这样的东西?*我不想使用内置libs,因为这是一个面试问题。我想在java中找到它。

JVM,因此java,严格地说是big-endian,而不管主机平台如何

然而,在关联字符编码中,可以提取关于系统默认编码的信息,该编码可能具有尾端性(事实上,它可能具有尾端性)

以下是一些代码:

boolean is_big_endian()
{
    return true;
}
编辑:

请参阅以下参考答案:


公平地说,调用本机代码是可能的,在那里您可以得到本机字节顺序的东西。

我对此不负责,但是您可以尝试:

import java.nio.ByteOrder;

if (ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN)) {
  System.out.println("Big-endian");
} else {
  System.out.println("Little-endian");
}
如何在java中找到这样的东西?*我不想使用内置的libs,因为这是一个面试问题。我想在java中找到它

在纯Java中,如果不调用库,就无法做到这一点。这是因为,

  • Java说,如果可以避免,就不应该关心这些事情
  • 作为一种语言,Java的功能相对较差,它依赖于它的库来做很多事情,而这些事情可能是另一种语言的语言功能
  • 大多数人不区分语言的功能和内置库,因为这种区别很少有用
  • 字节码/虚拟机本身不是big-endian或little-endian,只有真正的实现才是。;)
较旧的库只支持big-endian(大多数处理器都使用big-endian,Intel是一个显著的例外),较新的库可以以这种或那种方式设置

很少有人需要知道如何重新编写内置功能,如果你知道了,你会阅读代码了解它是如何完成的(即使你知道如何完成)

我见过许多人重新开发内置功能,这是有缺陷的,更难使用,因为它的行为方式出乎意料,性能不如内置库。写一些比JDK更快或更定制的东西是很有可能的,但是知道如何从你的头脑中跳出来却很少有用

我确实不时会收到这些问题,在回答问题之前,我会指出你不愿意这样做的所有原因

公共静态void getEndian(){
int a=0;
//0x0…01
int b=1;
//0x0..0,0.01,0..0,0..0

int combine=(b在具有sun.misc.Unsafe类并在名为“theUnsafe”的静态实例变量中存储不安全单例的JVM上,可以使用以下方法。我在Oracle JVM和openjdk上成功地测试了这一点。代码通过向内存写入一个短(2字节)值1,然后读取第一个字节来工作

import java.lang.reflect.Field;
import sun.misc.Unsafe;

public class Endianness {
    private static Unsafe getUnsafe() {
        Unsafe unsafe = null;
        try {
            Field f = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
            f.setAccessible(true);
            unsafe = (Unsafe) f.get(null);
        } catch (Exception e) {}
        return unsafe;
    }

    public static void main(String[] args) {
        Unsafe unsafe = getUnsafe();
        long address = unsafe.allocateMemory(2);
        short number = 1;
        unsafe.putShort(address, number);
        if (unsafe.getByte(address) == 0)
            System.out.println("Big Endian");
        else
            System.out.println("Little Endian");
        unsafe.freeMemory(address);
    }
}

据我所知,Java是严格意义上的big-endian。没有办法(事实上也没有理由)在不调用本机代码的情况下找出底层体系结构的终结性。我认为你运气不好。JVM会屏蔽你,使你免受这些特定于实现的细节的影响。吹毛求疵:这种使用
union
是否会触发未定义的行为?我会使用
char const*
替换为
uint32\u t
。好的。同意java这样做不允许你找到机器的endianess。但是我如何才能用java代码找到jvm本身的endianess呢?这只是为了采访的目的。我想知道这一点的唯一原因是创建二进制文件供非java应用程序使用,或者用java构建编译器。这一点相当模糊。同意。但这是一个采访stion@user93796:那又怎样?这会神奇地使JVM的工作方式无效吗?不会。我必须想出一个算法来检测JVM是大还是小。不会MAGIC@PeterClark真的吗?如果是这样的话,那么它就不符合编写此答案时的JVM规范。@Marcin我对代码进行了更深入的研究,发现我正在使用的代码调用了native(c/c++)代码(
bitmap.copyPixelsToBuffer
)以执行内存的实际复制。这可能是我返回的缓冲区是little endian的原因(它肯定是,它是一个每个颜色通道有1字节的图像,我得到的是BGRA而不是ARGB)。我不能100%确定JVM本身是否使用little endian,我可能猜不出JVM规范是否明确说明了这一点。ByteOrder.nativeOrder()上的文档提到常量存在,因为性能敏感的代码可以在本机运行。@user93796,这是一个“系统”库,它不是第三方库,IMO,公平的游戏。这以最简单的方式解决了问题-你需要一个乱七八糟的东西做什么?它不是库,它是一个内置类。没有它们,你在Java中不会走得很远。事实上,没有它们,你不会有任何进展。如果他们不喜欢你的答案,问问自己:我真的想要f吗还是一家问了这么愚蠢问题的公司?@user93796,谁说的?如果有人给我设置了一个测试,而问题的关键不是实现排序算法,我会使用现有的实现。在我看来,任何其他方法都是愚蠢的。你会雇用自己编写(可能有缺陷)排序()的人吗方法,而不是使用经过测试、理解良好的内置方法。事实上,我强烈怀疑是否有其他方法可以做到这一点。Java被设计为独立于平台,所以它的几乎所有方法都会在大端或小端机器上给你相同的结果。目前为止最好的答案是,伙计,指出为什么你会这样做不应该这样做。即使你不应该这样做,你仍然需要证明你可以这样做。我会说,看看它是如何完成的,这应该是一个合理的答案。最近我不得不创建一个自定义的替罪羊树状图,它使用
int
作为键和该键的多个值,并回收其所有节点。当然,我复制了代码的好部分om TreeMap并尽可能保持名称不变。这个问题不是问你为什么不想这样做,我已经问过了
import java.lang.reflect.Field;
import sun.misc.Unsafe;

public class Endianness {
    private static Unsafe getUnsafe() {
        Unsafe unsafe = null;
        try {
            Field f = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
            f.setAccessible(true);
            unsafe = (Unsafe) f.get(null);
        } catch (Exception e) {}
        return unsafe;
    }

    public static void main(String[] args) {
        Unsafe unsafe = getUnsafe();
        long address = unsafe.allocateMemory(2);
        short number = 1;
        unsafe.putShort(address, number);
        if (unsafe.getByte(address) == 0)
            System.out.println("Big Endian");
        else
            System.out.println("Little Endian");
        unsafe.freeMemory(address);
    }
}
System.out.println(ByteOrder.nativeOrder());