ここで、相互に排他的な 2 つの問題を指定しているのが見えます (または、どちらかを選択した可能性が高く、どちらを選択したのかわかりません)。
ソース コードの 2 つのバージョン (ライブラリが存在する場合とそうでない場合) を出荷するか、単一のバージョンを出荷し、ライブラリが存在する場合はライブラリで動作することを期待するかを選択する必要があります。 .
単一のバージョンでライブラリの存在を検出し、利用可能な場合はそれを使用する場合は、分散コードにアクセスするためのすべてのコードが必要です。削除することはできません。あなたの問題を #define の使用と同一視しているので、これはあなたの目標ではないと思いました.2 つのバージョンを出荷したいのです (#define が機能する唯一の方法です)。
したがって、2 つのバージョンで libraryInterface を定義できます。これは、ライブラリをラップし、すべての呼び出しをライブラリまたはインターフェイスに転送するオブジェクトのいずれかです。どちらの場合も、このオブジェクトは両方のモードでコンパイル時に存在する必要があります。
public LibraryInterface getLibrary()
{
if(LIBRARY_EXISTS) // final boolean
{
// Instantiate your wrapper class or reflectively create an instance
return library;
}
return null;
}
ライブラリを使用したい場合 (C で #ifdef を使用した場合)、次のようになります。
if(LIBRARY_EXISTS)
library.doFunc()
ライブラリは、どちらの場合にも存在するインターフェイスです。これは常に LIBRARY_EXISTS によって保護されているため、コンパイルされます (クラス ローダーに読み込まれることさえありませんが、これは実装に依存します)。
ライブラリがサード パーティによって提供される事前にパッケージ化されたライブラリである場合、Library をその呼び出しをライブラリに転送するラッパー クラスにする必要がある場合があります。LIBRARY_EXISTS が false の場合、ライブラリ ラッパーはインスタンス化されないため、実行時にロードすることさえできません (JVM が常に final 定数によって保護されているため、JVM が十分にスマートな場合はコンパイルすることさえできません)。ただし、覚えておいてください。どちらの場合も、コンパイル時にラッパーを使用できる必要があります。