JDK 5 でビルドする「マスター」ソース ルートを 1 つ保持します。JDK 6 以降でビルドする必要がある 2 つ目の並列ソース ルートを追加します。(重複があってはなりません。つまり、両方に存在するクラスはありません。) インターフェイスを使用して、2 つの間のエントリ ポイントを定義し、わずかなリフレクションを行います。
例えば:
---%<--- main/RandomClass.java
// ...
if (...is JDK 6+...) {
try {
JDK6Interface i = (JDK6Interface)
Class.forName("JDK6Impl").newInstance();
i.browseDesktop(...);
} catch (Exception x) {
// fall back...
}
}
---%<--- main/JDK6Interface.java
public interface JDK6Interface {
void browseDesktop(URI uri);
}
---%<--- jdk6/JDK6Impl.java
public class JDK6Impl implements JDK6Interface {
public void browseDesktop(URI uri) {
java.awt.Desktop.getDesktop().browse(uri);
}
}
---%<---
異なる JDK などを使用して、IDE でこれらを個別のプロジェクトとして構成できます。要点は、メイン ルートを個別にコンパイルでき、どのルートで何を使用できるかが非常に明確であるということです。単一のルートを別々に使用すると、JDK 6 の使用状況が間違ったファイルに誤って「リーク」する可能性が非常に高くなります。
このように Class.forName を使用するのではなく、何らかのサービス登録システムを使用することもできます - java.util.ServiceLoader (main が JDK 6 を使用でき、オプションで JDK 7 のサポートが必要な場合!)、NetBeans Lookup、Spring など。等
同じ手法を使用して、新しい JDK ではなく、オプションのライブラリのサポートを作成できます。