在确定Java 8上的主要Java版本时,以及在使用系统属性java.specification.version
之前,删除1.
并解析第二个数字:
"1.8"
~> "8"
~> 8
NumberFormatException
,因为系统属性是"9"
确定主要Java版本的未来验证方法是什么?目标是获得一个int
,它可以是if
、-ed或switch
-ed,以决定采用哪种代码路径(例如,在库中激活某个特性)。
发布于 2017-11-13 10:00:22
Java9引入了Runtime.Version
类,希望在未来一段时间内能够支持这个类。把它和我以前的方法搭配起来:
public static int getMajorVersion() {
try {
// use Java 9+ version API via reflection, so it can be compiled for older versions
Method runtime_version = Runtime.class.getMethod("version");
Object version = runtime_version.invoke(null);
Method version_major = runtime_version.getReturnType().getMethod("major");
return (int) version_major.invoke(version);
// do not catch `ReflectiveOperationException` because it does not exist in Java <7
} catch (Exception ex) {
// before Java 9 system property 'java.specification.version'
// is of the form '1.major', so return the int after '1.'
String versionString = System.getProperty("java.specification.version");
return Integer.parseInt(versionString.substring(2));
}
}
(我在CC-0下发布了这段代码:您可以复制、修改、分发和执行这项工作,甚至是出于商业目的,所有这些都无需征得许可。)
它在我的机器上工作(哈哈),但我不确定这是否是最好的解决方案,因为我不知道新的API或系统属性是否有我不知道的角落情况。
还请参阅 斯蒂芬的回答 ,以了解为什么将版本缩减为一位数可能不是一个好主意。
发布于 2017-11-13 10:05:23
很明显,没有什么能保证未来的证明。我们不能肯定地预测未来(!)
但是,以下内容适用于以前版本的Java和符合9月233的版本
但也存在一个问题,即您使用的是哪个版本的编号。例如,"Java 5“和”Java1.5“的含义相同。您所使用的名称取决于您试图满足的命名方案。
关于“官方”Java版本名称的一个很好(但不是确定的)引用:
请注意,您的原始方案中断了早期Java版本,如"1.2.1“和"1.3.1”,其中最后的数字非常重要。而且您也不希望开始将Java1.0标记为“Java0”。最后,Java1.0和Java1.1非常不同,不应该混淆。(首先,Java1.0没有嵌套/内部类。)
我这样做只是为了成为一个“经理友好”的名字。为了“决策目的”,我不会把这个版本缩减为一个数字。您可能会发现,次要版本之间的差异是显著的。
发布于 2017-11-13 12:19:37
当然,这取决于行动的目标。如果您想以与Java营销兼容的方式向用户报告,您必须面对这样一个事实:营销本身从来没有使用一致的标签,并且可能会追溯地重新命名旧版本。
如果检查只是为了确保某些特性或bug修复的存在,那么只为每个版本分配一个升序就足够了。然后,您可以将0
分配给Java1.0,这与JavaReporting1.1(将1
分配给它)有很大的不同,并且可以使用以下方法获得多达9个的一致编号
public static int getMajorVersion() {
String version = System.getProperty("java.class.version");
int p = version.indexOf('.');
if(p>0) version = version.substring(0, p);
return Integer.parseInt(version)-44;
}
类文件版本的好处是它绑定到一个更正式的定义,因为它必须符合类文件的两个字段,所以它不能受方案更改或追溯重新定义的影响。此外,在这两个版本号中,没有像“beta”、“final”或“请不同地解释”这样的散文的空间。上面的代码保护的唯一一点是,可能遗漏了自Java1.1以来没有使用的.0
次要数字,因为每个版本的主要类文件版本都增加了。
当然,不能保证下一个版本的数量会再次增加,但是,这并不是兼容性检查的问题,因为它总是至少有上一个版本的数量,被解释为“与上一个版本兼容”。要开始使用更新的特性,无论如何您必须接触源代码。在这种情况下,您可以为这些未来版本的Runtime.version()
添加基于…的操作。
但是请注意,在用-target
或--release
编译时,您可以免费获得它,因为所需的最低版本无论如何都会写入类文件中,并且较早的JVM版本将拒绝执行您的代码。当您想要支持比最小版本更新的版本的特性时,无论如何您必须动态地访问它们,因此在本例中,您可以简单地反思性地尝试使用该特性,如果失败,可以转到回退代码,并且不需要进行额外的版本号检查。这正是您在尝试实现getMajorVersion()
执行反射Runtime.version().major()
时所做的事情,而不需要对该特性的存在进行基于先前版本的检查。
https://stackoverflow.com/questions/47261432
复制相似问题