1. 概述
虽然 Java 是跨平台的,但在某些场景下我们仍需调用本地库(native libraries)。此时就需要根据 JVM 的位数来加载对应的本地库。
本文将介绍几种判断 Java 程序是运行在 32 位还是 64 位 JVM 上的方法:
- 使用
System
类获取系统属性 - 使用 Java Native Access(JNA) 来检测 JVM 架构
⚠️ 注意:有些方法依赖于特定厂商实现(如 Oracle JDK),并不适用于所有 JVM 实现。
2. 使用 sun.arch.data.model
系统属性
Java 中的 System
类提供了访问外部定义的属性和环境变量的能力。我们可以利用 sun.arch.data.model
这个系统属性来判断当前 JVM 是 32 位还是 64 位:
System.getProperty("sun.arch.data.model");
返回值为字符串 "32"
或 "64"
,分别表示 32 位或 64 位 JVM。
✅ 优点:简单粗暴
❌ 缺点:该属性不是标准属性,在非 Oracle JDK(如 OpenJDK、IBM JDK)中可能不存在,返回 "unknown"
示例代码如下:
public class JVMBitVersion {
public String getUsingSystemClass() {
return System.getProperty("sun.arch.data.model") + "-bit";
}
//... 其他方法
}
单元测试验证逻辑:
@Test
public void whenUsingSystemClass_thenOutputIsAsExpected() {
if ("64".equals(System.getProperty("sun.arch.data.model"))) {
assertEquals("64-bit", jvmVersion.getUsingSystemClass());
} else if ("32".equals(System.getProperty("sun.arch.data.model"))) {
assertEquals("32-bit", jvmVersion.getUsingSystemClass());
}
}
3. 使用 JNA API 检测 JVM 架构
JNA(Java Native Access)是一个社区维护的库,用于简化 Java 对本地代码的调用,支持 macOS、Windows、Linux 等多个平台。
3.1. 使用 Native
类中的 POINTER_SIZE
JNA 提供了一个 com.sun.jna.Native
类,其中包含一个常量 POINTER_SIZE
表示当前平台上指针的大小(单位为字节):
if (com.sun.jna.Native.POINTER_SIZE == 4) {
// 32-bit
} else if (com.sun.jna.Native.POINTER_SIZE == 8) {
// 64-bit
}
✅ 优点:跨平台兼容性好
⚠️ 需要引入 JNA 依赖:
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.13.0</version>
</dependency>
3.2. 使用 Platform
类中的 is64Bit()
方法
JNA 还提供了一个更高级的封装类 com.sun.jna.Platform
,其内部实现了更可靠的判断逻辑。
关键方法是:
Platform.is64Bit()
其实现大致如下:
public static final boolean is64Bit() {
String model = System.getProperty("sun.arch.data.model",
System.getProperty("com.ibm.vm.bitmode"));
if (model != null) {
return "64".equals(model);
}
if ("x86-64".equals(ARCH)
|| "ia64".equals(ARCH)
|| "ppc64".equals(ARCH) || "ppc64le".equals(ARCH)
|| "sparcv9".equals(ARCH)
|| "mips64".equals(ARCH) || "mips64el".equals(ARCH)
|| "amd64".equals(ARCH)
|| "aarch64".equals(ARCH)) {
return true;
}
return Native.POINTER_SIZE == 8;
}
其中 ARCH
是通过 os.arch
属性推导出的操作系统架构名称。
✅ 优点:
- 跨平台、跨 JDK 厂商
- 更加健壮,不依赖特定属性
4. 总结
方法 | 依赖 | 可靠性 | 推荐程度 |
---|---|---|---|
sun.arch.data.model |
Oracle JDK | ⚠️ 一般 | ❌ 不推荐 |
JNA Native.POINTER_SIZE |
JNA 库 | ✅ 高 | ✅ 推荐 |
JNA Platform.is64Bit() |
JNA 库 | ✅ 最高 | ✅✅ 强烈推荐 |
📌 小贴士:如果你的应用需要适配多种操作系统或 JVM 厂商,建议使用 JNA 提供的方案,它比直接读取系统属性更可靠。
完整代码可参考 GitHub 仓库:https://github.com/eugenp/tutorials/tree/master/core-java-modules/java-native