我需要解决JDK 1.5中的Java bug,该问题在1.6中已经修复。我使用以下条件:
if (System.getProperty("java.version").startsWith("1.5.")) {
...
} else {
...
}
这对其他JVM是否适用?有更好的检查方法吗?
java.version
是每个JVM中都存在的系统属性。它有两种可能的格式:
1.6.0_23
、1.7.0
、1.7.0_80
、1.8.0_211
9.0.1
、11.0.4
、12
、12.0.1
这里有一个技巧可以提取主要版本号:如果是 1.x.y_z
版本字符串,则提取字符串索引2处的字符。如果是 x.y.z
版本字符串,则将字符串裁剪到其第一个点字符(如果存在)。
private static int getVersion() {
String version = System.getProperty("java.version");
if(version.startsWith("1.")) {
version = version.substring(2, 3);
} else {
int dot = version.indexOf(".");
if(dot != -1) { version = version.substring(0, dot); }
} return Integer.parseInt(version);
}
现在你可以更加方便地检查版本:
if(getVersion() < 6) {
// ...
}
Runtime.version()
自Java 9起,您可以使用Runtime.version()
方法,它返回一个Runtime.Version
对象:
Runtime.Version version = Runtime.version();
那么从软件包元信息中获取版本呢:
String version = Runtime.class.getPackage().getImplementationVersion();
打印出类似于:
1.7.0_13
Runtime.class.getPackage().getSpecificationVersion()
。 - Wesley HartfordRuntime.class.getPackage().getImplementationVersion()
似乎返回null
。 - tresf这些文章似乎建议检查前缀为1.5
或1.6
,因为它符合正确的版本命名约定。
java.version
系统属性"java.version
系统属性"java.runtime.name
、java.vendor
、java.vm.{name,vendor}
、java.vm.specification.{name,vendor}
。我相信前两个可能会被官方JVM/JLS规范半标准化,而其他可能现在已成为某种标准惯例。根据应用程序中确切的使用情况,通常其中一个或多个属性可以成为决定因素。 - Ti Strga最简单的方法 (java.specification.version):
double version = Double.parseDouble(System.getProperty("java.specification.version"));
if (version == 1.5) {
// 1.5 specific code
} else {
// ...
}
或类似于 (java.version):
String[] javaVersionElements = System.getProperty("java.version").split("\\.");
int major = Integer.parseInt(javaVersionElements[1]);
if (major == 5) {
// 1.5 specific code
} else {
// ...
}
或者如果您想要将其拆分成多个部分(java.runtime.version):
String discard, major, minor, update, build;
String[] javaVersionElements = System.getProperty("java.runtime.version").split("\\.|_|-b");
discard = javaVersionElements[0];
major = javaVersionElements[1];
minor = javaVersionElements[2];
update = javaVersionElements[3];
build = javaVersionElements[4];
java.runtime.version
版本在 Java 9 上出现了问题 (java.lang.ArrayIndexOutOfBoundsException
)。 - Eugène AdellApache Commons Lang 的示例:
import org.apache.commons.lang.SystemUtils;
Float version = SystemUtils.JAVA_VERSION_FLOAT;
if (version < 1.4f) {
// legacy
} else if (SystemUtils.IS_JAVA_1_5) {
// 1.5 specific code
} else if (SystemUtils.isJavaVersionAtLeast(1.6f)) {
// 1.6 compatible code
} else {
// dodgy clause to catch 1.4 :)
}
version < 1.4f
... 当 version = 1.4f
时会发生什么? - ADTCversion <= 1.4f
。不幸的是,SystemUtils
没有提供一个名为 isJavaVersionLessThan
的方法,但是(幸运的是)你也可以把遗留代码放在一个 else
块中,这样会更简洁。 - ADTC1.4f
不应该回退到旧代码吗? - ADTCif (SystemUtils.IS_JAVA_1_5) { /* 1.5 特定代码 */ } else if (SystemUtils.isJavaVersionAtLeast(1.6f)) { /* 现代代码 */ } else { /* 回退到旧版代码 */ }
。在上面是特定代码,在下面是通用代码,最底部是回退代码。 - ADTCSystemUtils.JAVA_VERSION_FLOAT
可以和/或必须与浮点字面量进行比较。这是我唯一的借口 :) - mvanle请注意,在Java 9及以上版本中,命名约定有所不同。System.getProperty("java.version")
返回的是"9"
而不是"1.9"
。
无法运行,需要使用--pos
来评估双倍:
String version = System.getProperty("java.version");
System.out.println("version:" + version);
int pos = 0, count = 0;
for (; pos < version.length() && count < 2; pos++) {
if (version.charAt(pos) == '.') {
count++;
}
}
--pos; //EVALUATE double
double dversion = Double.parseDouble(version.substring(0, pos));
System.out.println("dversion:" + dversion);
return dversion;
}
以下是在JOSM中的实现:
/**
* Returns the Java version as an int value.
* @return the Java version as an int value (8, 9, etc.)
* @since 12130
*/
public static int getJavaVersion() {
String version = System.getProperty("java.version");
if (version.startsWith("1.")) {
version = version.substring(2);
}
// Allow these formats:
// 1.8.0_72-ea
// 9-ea
// 9
// 9.0.1
int dotPos = version.indexOf('.');
int dashPos = version.indexOf('-');
return Integer.parseInt(version.substring(0,
dotPos > -1 ? dotPos : dashPos > -1 ? dashPos : 1));
}
System.out.println("Is Java version at least 1.8: " + SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_1_8));
double version = 1.6
和Double.parseDouble("1.6")
仍然应该产生相同的位模式,对吗?由于我们不对数字进行算术运算(只是简单比较),所以即使是==
也能正常工作。 - Aaron Digulla