我想知道是否有一个Java API可以告诉你一个特定的语言特性(例如,“钻石”运算符)在当前平台上可用。
(In换句话说,我尝试做的类似于JavaScript中的“浏览器嗅探”。
这在元编程(编写生成Java源代码的Java程序)中非常方便。
到目前为止,我发现的最佳解决方案是解析System.getProperty("java.specification.version")
并检查它是否≥引入此特性的版本,但我不能100%确定此属性在所有JVM中都可用(甚至不能确定它是否符合所有JVM中的相同语法)。这种方法的另一个小麻烦是,您必须采取额外的步骤来查找哪个Java版本引入了您感兴趣的语言特性。没什么大不了的,因为这些信息很容易谷歌,但理想情况下,如果有一个API可以随时提供信息,那就太好了,例如:
code.append("Map<Integer, String> map = ");
if (javax.meta.JavaVersion.getCurrentVersion().supportsDiamond()) {
code.append("new Map<>();");
} else {
code.append("new Map<Integer, String>();");
}
显然没有名为javax.meta
的包,但我想知道是否已经有了解决这个问题的解决方案,它比解析"java.specification.version"
属性更简洁。
- 更新 *:我刚刚意识到
Package#getSpecificationVersion()
也提供了与System.getProperty("java.specification.version")
相同的值,但可能更可靠,因为系统属性是可变的。换句话说,获得Java规范版本的最佳方法可能是在任何“内置”包上调用Package#getSpecificationVersion()
。例如:String.class.getPackage().getSpecificationVersion()
3条答案
按热度按时间t40tm48m1#
这将为您提供系统正在运行的Java版本。
如果你运行的是Java 9及更高版本,你可以用途:
Java文档
Java版本命名标准在Java 9中也发生了变化。
Java版本:
1.7, 1.8, 9, 10, 11
我没有一个解决方案,让你检查特定的功能。
llmtgqce2#
特征可以是:JDK 10
1.方法:
Optional.orElseThrow()
1.系统属性:例如,禁用JRE上次使用跟踪
它也可能是功能的删除:在Java 10中
1.删除对使用旧LookAndFeel的支持
1.删除
Runtime.getLocalizedInputStream
和getLocalizedOutputStream
方法1.等等。
因此,如果存在新功能或已删除新功能,则很难通过编程方式执行
check
或discover
除非您知道您要查找的功能,否则需要Oracle自己提供文档、功能名称和描述。如果我们要为此创建API,我们必须首先从Oracle文档中获取列表,然后对每个功能进行必要的检查,以发现当前版本或是否支持。
下面是一个example程序来检查编译器的特定功能。
参见JDK 10 features
rjee0c153#
我刚刚发现了另一个部分解决方案:javax.lang.model.SourceVersion。它仍然没有完全解决问题,但似乎是朝着正确方向迈出的一步。
所以我不再用我以前的方法,
你可以写:
(因为
SourceVersion
的enum
常量是按升序声明的)这个类还提供了静态方法
isKeyword
、isName
、isIdentifier
,这些方法可能会很有用,但是要获得其中的一些信息已经相当容易了(例如Character.isJavaIdentifierPart(cp)
)。在后台,
SourceVersion
还依赖于阅读"java.specification.version"
系统属性:这是一些臭代码就在那里!例如,如果有人调用
System.setProperty("java.specification.version", "6.9");
,那么SourceVersion.latestSupported()
将返回RELEASE_5
;)我感到惊讶的是,即使Sun/Oracle也没有提供一种“内在的”方法来直接从VM获取Java版本(就像
sun.misc
包公开的各种内在操作一样)