特定の言語機能(例えば「ダイヤ」オペレータ)が現在のプラットフォームで利用可能であるかどうかを言うことができるのJava APIがある場合、私は思っていました。
(つまり、私がやろうとしていることは、JavaScriptで「スニッフィングブラウザ」に類似しています。)
これは、メタプログラミング(Javaソースコードを生成するJavaプログラムを書くことで本当に便利になります。
私がこれまでに見つけた最高のソリューションを解析することでSystem.getProperty("java.specification.version")
、それは≥本機能を導入したバージョンだかどうかを確認するが、私は、このプロパティは、すべてのJVMで利用可能であること(または、それは同じ構文に準拠かどうかさえわから100%ではありませんよすべてのJVMで)。このアプローチのもう一つのマイナーな不快感は、あなたが興味を持っている言語機能を導入されたJavaのバージョンを調べるの余分なステップを取らなければならないということである。大した、その情報はかなり簡単Googleにあり、理想的にそれが出来容易に例えば、情報を提供できる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()
機能は次のようになります。JDK 10
- 方法 :
Optional.orElseThrow()
- API:変更不可能なコレクションを作成するためのAPI
- システムプロパティ:フォアの例、無効にJREへの最終使用状況の追跡
- GC増強(フルパラレル)
- Javadocのサポート:(複数のスタイルシートの場合)
また、機能の除去が考えられます。また、Java 10に
- 古いのLook&Feelを使用するためのサポートの除去
- 除去
Runtime.getLocalizedInputStream
およびgetLocalizedOutputStream
方法 - 等々..
するのは難しいですのでcheck
かdiscover
またはそれの新機能が存在が削除されている場合programmatcally ない限り、あなたが探しているものを知っている、それはドキュメンテーション、機能名や説明としてOracle自体によって提供されるようにする必要があります。
我々が作成し、そのためのAPIしようとしている場合、我々は、Oracleのドキュメントから最初のリストを取得し、その後、現在のバージョンまたはそれがサポートされている場合を発見するために、各機能に必要なチェックを行う必要があります。
以下は、ある例 programmaticaly特定の機能のためのコンパイラをチェックします。
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.Arrays;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject.Kind;
public class CompileSourceInMemory {
public static void main(String args[]) throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
StringWriter writer = new StringWriter();
PrintWriter out = new PrintWriter(writer);
out.println("public class HelloWorld {");
out.println(" public static void main(String args[]) {");
out.println(" System.out.println(\"This is in another java file\");");
out.println(" }");
out.println("}");
out.close();
JavaFileObject file = new JavaSourceFromString("HelloWorld", writer.toString());
Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file);
CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, compilationUnits);
boolean success = task.call();
for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
System.out.println(diagnostic.getCode());
System.out.println(diagnostic.getKind());
System.out.println(diagnostic.getPosition());
System.out.println(diagnostic.getStartPosition());
System.out.println(diagnostic.getEndPosition());
System.out.println(diagnostic.getSource());
System.out.println(diagnostic.getMessage(null));
}
System.out.println("Success: " + success);
if (success) {
try {
Class.forName("HelloWorld").getDeclaredMethod("main", new Class[] { String[].class })
.invoke(null, new Object[] { null });
} catch (ClassNotFoundException e) {
System.err.println("Class not found: " + e);
} catch (NoSuchMethodException e) {
System.err.println("No such method: " + e);
} catch (IllegalAccessException e) {
System.err.println("Illegal access: " + e);
} catch (InvocationTargetException e) {
System.err.println("Invocation target: " + e);
}
}
}
}
class JavaSourceFromString extends SimpleJavaFileObject {
final String code;
JavaSourceFromString(String name, String code) {
super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension),Kind.SOURCE);
this.code = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
JDK 10を参照してください機能を