Java のチュートリアルを勉強しているときに、Reflection と Late Binding に戸惑いました。一部のチュートリアルでは、両者は同じであり、Reflection と Late Binding に違いはないと書いています。しかし、他のチュートリアルでは違いがあると言われています。
私は混乱しているので、誰かがリフレクションとレイトバインディングがJavaで何であるかを説明してもらえますか?可能であれば、両方の実際の例をいくつか教えてください.
ありがとう..
Java のチュートリアルを勉強しているときに、Reflection と Late Binding に戸惑いました。一部のチュートリアルでは、両者は同じであり、Reflection と Late Binding に違いはないと書いています。しかし、他のチュートリアルでは違いがあると言われています。
私は混乱しているので、誰かがリフレクションとレイトバインディングがJavaで何であるかを説明してもらえますか?可能であれば、両方の実際の例をいくつか教えてください.
ありがとう..
Javaは遅延バインディングを使用してポリモーフィズムをサポートします。つまり、多くのメソッドのどれを使用するかの決定は、実行時まで延期されます。
インターフェイスの抽象メソッド(または抽象クラスfwiw)を実装するNクラスの場合を考えてみましょう。
public interface IMyInterface {
public void doSomething();
}
public class MyClassA implements IMyInterface {
public void doSomething(){ ... }
}
public class MyClassB implements IMyInterface {
public void doSomething(){ ... }
}
public class Caller {
public void doCall(IMyInterface i){
// which implementation of doSomething is called?
// it depends on the type of i: this is late binding
i.doSomething();
}
}
代わりに、他のコードを検査できるコードを記述するためにリフレクションが使用されます。クラスで使用できるメソッドまたは属性を確認したり、名前でメソッドを呼び出したり(またはクラスをロードしたり)、実行時に非常に興味深いことをたくさん実行します。
リフレクションの非常に優れた説明がここにあります:リフレクションとは何ですか、なぜそれが役立つのですか?
遅延バインディング (動的ディスパッチとも呼ばれます) はリフレクションを必要としません。コンパイル時にどのメンバーに動的にバインドするかを知る必要があります (つまり、メンバーの署名はコンパイル時に認識されます)。オーバーライドされたメンバーは実行時に発生します。
リフレクションを行うとき、使用しているメンバーさえわかりません(署名はもちろん、コンパイル時に名前さえもわかりません)。すべてが実行時に行われるため、はるかに遅くなります。
実際の例:
プロジェクトを jdesktop 0.8 でビルドし、jdesktop 0.9 で出荷する場合、コードは引き続き 0.9 の機能を使用します。これは、レイト バインディングを利用するためです。つまり、コードが呼び出すコードは、クラス ローダーによってロードされるバージョンです。コンパイルされたバージョンに関係なく。(これは、呼び出されたコードのコンパイル時バージョンをアプリケーションに埋め込むリンカーとは対照的です。)
リフレクションについては、Java 1.5 および 1.6 をターゲットにしようとしているが、1.6 のタブ コンポーネントが利用可能であればそれを使用したい場合、JTabbedPane クラスでリフレクションを使用してsetTabComponentAt
メソッドを見つけ、それらの存在を確認します。この場合、これらの機能をまったく持たない Java 1.5 に対してビルドしているため、それらを直接呼び出すことはできません。そうしないと、コンパイルが失敗します。ただし、エンドユーザーのシステムで 1.6 に対して実行していることに気付いた場合 (ここでは遅延バインディングが機能します)、リフレクションを使用して 1.5 には存在しなかったメソッドを呼び出すことができます。
それらは関連しています。リフレクションの多くの用途は、レイト バインディングに依存していますが、それらは言語とその実装の根本的に異なる側面です。
「Late Binding」によって対処される重要な問題の 1 つはポリモーフィズムです。つまり、クラス階層に沿った適切なオーバーライド メソッドの呼び出しは、コンパイル時ではなく実行時に決定されます。リフレクションは、実行時にオブジェクトに関する情報を収集して操作する機能です。たとえば、実行時に「クラス」属性を使用してオブジェクトのすべての属性またはメソッド名を取得し、それらのメソッドを呼び出したり、その属性を操作したりできます。
次のコードでは、リフレクションによって新しいオブジェクトを動的に作成できます ( object obj = new MyClass( "MyInstance" ) のような単純なものを使用する代わりに、クラスを使用してコンストラクターを取得およびアクセスする方法を参照してください)。同様の方法で、他のコンストラクタ フォーム、メソッド、および属性にアクセスできます。Java でのリフレクションの詳細については、http: //java.sun.com/developer/technicalArticles/ALT/Reflection/を参照してください。
... in some method of some class ...
Class c = getClass();
Constructor ctor = c.getConstructor( String.class );
Object obj = ctor.newInstance( "MyInstance" );