私のプロジェクトでは、コンパイルと実行にJava 1.6が必要です。これで、Java 1.5(マーケティング側から)で動作する必要があります。メソッド本体を置き換えて(戻り値の型と引数は同じままにして)エラーなしでJava 1.5でコンパイルできるようにします。
詳細:すべてのOS固有のものをカプセル化するOS
というユーティリティクラスがあります。メソッドがあります
_public static void openFile(Java.io.File file) throws Java.io.IOException {
// open the file using Java.awt.Desktop
...
}
_
ダブルクリック(start
Windowsコマンドまたはopen
Mac OS Xコマンドに相当)を使用してファイルを開きます。 Java 1.5ではコンパイルできないため、コンパイル中に除外し、Windowsの場合は_run32dll
_、Mac OS Xの場合は_Runtime.exec
_を使用してopen
を呼び出す別のメソッドに置き換えます。
質問:どうすればいいですか?注釈はここで役立ちますか?
注:antを使用し、Java 1.5の目的のコードを持つOS
クラスを含む2つのJavaファイル_OS4J5.Java
_および_OS4J6.Java
_を作成できます。 1.6コンパイルする前にそれらの1つを_OS.Java
_にコピーします(またはい方法-Javaバージョンに応じて条件付きで_OS.Java
_の内容を置き換えます)。 、別の方法がある場合。
さらに詳しく:Cでは_ifdef, ifndef
_を使用でき、Pythonではコンパイルがなく、hasattr
または他の何かを使用して機能をチェックでき、Common LISPでは_#+feature
_を使用できます。 Javaに似たようなものはありますか?
この投稿 が見つかりましたが、役に立たないようです。
どんな助けも大歓迎です。 kh。
いいえ、Javaの条件付きコンパイルはサポートされていません。
通常の計画は、アプリのOS固有のビットをInterface
の背後に隠し、実行時にOSタイプを検出し、Class.forName(String)
を使用して実装をロードすることです。
あなたの場合、両方をコンパイルできない理由はありませんOS*
(およびアプリ全体のインファクト)Java 1.6 with -source 1.5 -target 1.5
その後、OS
クラス(現在はインターフェイスになる)を取得するためのファクトリメソッドで、Java.awt.Desktop
クラスが利用可能であり、正しいバージョンをロードします。
何かのようなもの:
public interface OS {
void openFile(Java.io.File file) throws Java.io.IOException;
}
public class OSFactory {
public static OS create(){
try{
Class.forName("Java.awt.Desktop");
return new OSJ6();
}catch(Exception e){
//fall back
return new OSJ5();
}
}
}
Garethが提案したようなインターフェースの背後に2つの実装クラスを隠すのがおそらく最善の方法です。
ただし、antビルドスクリプトのreplaceタスクを使用して、一種の条件付きコンパイルを導入できます。秘Theは、ソースをコンパイルする直前に、テキストの置換によってオープン/クローズされるコメントをコード内で使用することです:
/*{{ Block visible when compiling for Java 6: IFDEF6
public static void openFile(Java.io.File file) throws Java.io.IOException {
// open the file using Java.awt.Desktop
...
/*}} end of Java 6 code. */
/*{{ Block visible when compiling for Java 5: IFDEF5
// open the file using alternative methods
...
/*}} end of Java 5 code. */
antでは、Java 6でコンパイルする場合、「IFDEF6」を「* /」に置き換えて、
/*{{ Block visible when compiling for Java 6: */
public static void openFile(Java.io.File file) throws Java.io.IOException {
// open the file using Java.awt.Desktop
...
/*}} end of Java 6 code. */
/*{{ Block visible when compiling for Java 5, IFDEF5
public static void openFile(Java.io.File file) throws Java.io.IOException {
// open the file using alternative methods
...
/*}} end of Java 5 code. */
また、Java 5)をコンパイルする場合は、「IFDEF5」を置き換えます。// comments
、/*{{
ブロック内で/*}}
を使用するよう注意する必要があることに注意してください。
以下に紹介するAntスクリプトは、すてきできれいなトリックを提供します。
リンク: https://weblogs.Java.net/blog/schaefa/archive/2005/01/how_to_do_condi.html
例では、
//[ifdef]
public byte[] getBytes(String parameterName)
throws SQLException {
...
}
//[enddef]
antスクリプトを使用
<filterset begintoken="//[" endtoken="]">
<filter token="ifdef" value="${ifdef.token}"/>
<filter token="enddef" value="${enddef.token}"/>
</filterset>
詳細については上記のリンクにアクセスしてください。
リフレクションを使用して呼び出しを行い、Java 5でコードをコンパイルできます。
例えば.
Class clazz = Class.forName("Java.package.ClassNotFoundInJavav5");
Method method = clazz.getMethod("methodNotFoundInJava5", Class1.class);
method.invoke(args1);
例外をキャッチして、Java 5。
Java 9では、マルチリリースjarファイルを作成できます。基本的に、同じJavaファイルの複数のバージョンを作成することを意味します。
それらをコンパイルするとき、必要なjdkバージョンでJavaファイルの各バージョンをコンパイルします。次に、次のような構造にパックする必要があります。
+ com
+ mypackage
+ Main.class
+ Utils.class
+ META-INF
+ versions
+ 9
+ com
+ mypackage
+ Utils.class
上記の例では、コードの主要部分はJava 8でコンパイルされますが、Java 9の場合、追加の(しかし異なる)バージョンがありますUtils
クラス。
このコードをJava 8 JVMで実行すると、META-INFフォルダー内のクラスもチェックしません。ただし、Java 9では、クラスのより新しいバージョンを見つけて使用します。
私はそれほど素晴らしいJavaエキスパートではありませんが、Javaの条件付きコンパイルはサポートされており、簡単に実行できます。お読みください。
http://www.javapractices.com/topic/TopicAction.do?Id=64
要点を引用する:
条件付きコンパイルのプラクティスは、クラスのコンパイル済みバージョンからコードのチャンクをオプションで削除するために使用されます。コンパイラは、到達不能なコードの分岐を無視するという事実を使用します。条件付きコンパイルを実装するには、
- 静的な最終的なブール値をあるクラスの非プライベートメンバーとして定義する
- ブール値を評価するifブロックで条件付きでコンパイルされるコードを配置します
- ブール値をfalseに設定すると、コンパイラーはifブロックを無視します。それ以外の場合は、値をtrueのままにします
もちろん、これにより、メソッド内のコードの塊を「コンパイル」できます。クラスメンバ、メソッド、またはクラス全体を削除する(スタブのみを残す場合もあります)には、プリプロセッサが必要です。
アプリケーションで条件付きで有効なコードブロックが必要ない場合は、プリプロセッサが唯一の方法です。mavenプロジェクトとantプロジェクトの両方に使用できる Java-comment-preprocessor を参照してください。
p.s。
また、私は ソースの重複なしでJEP-238マルチバージョンJARを構築するためにMavenでプリプロセスを使用する方法の例
Java from Manifold framework )の新しい Preprocessor があります。これはjavac プラグインこれは、直接がJavaコンパイラーと統合されていることを意味します。管理するビルド手順、コード生成ターゲットなどはありません。
Java Primitive Specializations Generator は条件付きコンパイルをサポートします:
/* if Windows compilingFor */
start();
/* Elif Mac compilingFor */
open();
/* endif */
このツールにはMavenおよびGradleプラグインがあります。