定義がどのように存在するかに関係なく、静的関数呼び出しは静的呼び出しバイトコードに変換されるため...ターゲット関数とクラスがまだ存在しない場合でも、静的関数の呼び出し元を強制的に正常にコンパイルする方法はありますか?
まだ存在しない関数への呼び出しをコンパイルできるようにしたい。コンパイラーに、実行時にそれらを適切に定義してクラスパスに入れることを信頼するように指示する必要があるので、とりあえずコンパイルしてください。
これを行う方法はありますか?
定義がどのように存在するかに関係なく、静的関数呼び出しは静的呼び出しバイトコードに変換されるため...ターゲット関数とクラスがまだ存在しない場合でも、静的関数の呼び出し元を強制的に正常にコンパイルする方法はありますか?
まだ存在しない関数への呼び出しをコンパイルできるようにしたい。コンパイラーに、実行時にそれらを適切に定義してクラスパスに入れることを信頼するように指示する必要があるので、とりあえずコンパイルしてください。
これを行う方法はありますか?
反射的にはい、ただし通常の呼び出しではありません。
呼び出しには、メソッド名とパラメーターの型を含む文字列プールのエントリが必要であるため、コンパイラはメソッドのシグネチャを決定できる必要があります。
invokestatic <メソッド仕様>
<method-spec> はメソッド仕様です。これは、クラス名、メソッド名、および記述子の 3 つの部分で構成される単一のトークンです。例えば
java/lang/System/exit(I)V
「java.lang.System」というクラスの「exit」というメソッドで、記述子「(I)V」を持っています (つまり、整数の引数を取り、結果を返しません)。
検討
AClass.aStaticMethod(42)
について何も知らなくてもAClass
、
AClass.aStaticMethod(int)
AClass.aStaticMethod(int...)
AClass.aStaticMethod(long)
AClass.aStaticMethod(long...)
float
とについても同様double
AClass.aStaticMethod(Integer)
AClass.aStaticMethod(Number)
AClass.aStaticMethod(Comparable<? extends Integer>)
AClass.aStaticMethod(Object)
AClass.aStaticMethod(Serializable)
そしておそらく私が見逃した他のいくつか。
...ターゲット関数とクラスがまだ存在しない場合でも、静的関数の呼び出し元を強制的に正常にコンパイルする方法はありますか?
いいえ。メソッド呼び出しをコンパイルするとき、コンパイラは呼び出されたメソッドの名前、引数の型、結果の型、例外などをチェックする必要があります。静的メソッドについて質問しているため、この情報は 1 か所でしか定義できません...静的メソッドを宣言するクラスです。静的な型安全性が必要な場合、これに対する回避策はありません。
実行時に私を信頼するようにコンパイラに指示する必要があります...
それほど単純ではありません。
メソッドのシグネチャがどうあるべきかをコンパイラに伝えていません。呼び出しから署名を正確に推測することはできないため、コンパイラに通知する必要があります。
Java プラットフォームは堅牢であるように設計されており、「ただ信じてください」ということは壊滅的な実行時障害につながる可能性があります。
コンパイル時の型の安全性を犠牲にして、静的に型付けされたコードの利便性/シンプルさ/読みやすさを避けたい場合は、リフレクションがオプションです。しかし、他に有効なオプションが思い浮かびません。
いいえ。ただし、メソッドとそれらに対するコードを持つインターフェイスを宣言し、Abstract Factoryパターンを使用して実行時に実装を提供することはできます。
依存性注入はこのアプローチを使用します。