0

私はより深いレバーでの動的/静的バインディングを理解しようとしています。多くの読書と検索の後、何かについて本当に混乱したと言えます。

Java はオーバーライドされたメソッドに動的バインディングを使用します。その理由は、コンパイラがメソッドがどのクラスに属しているかを認識していないからです。例えば ​​:

public class Animal{
       void eat(){
}

class Dog extends Animal{
       @Override
       void eat(){}
}

public static void main(String[] args[]){
     Dog d = new Dog();
     d.eat();
}

私の質問は、コードが Dog クラスの eat() メソッドを参照していることをコンパイラが認識しないのはなぜですか? オブジェクトは実行時に作成されますが、コードが Dog のメソッドを参照していることをコンパイラが理解できないのはなぜですか?それはコンパイラの設計の問題ですか、それとも何か不足していますか?

4

3 に答える 3

3

動的バインディングは絶対に必要です。たとえば、次のようなものがあるとします。

Animal a;
String kind = askTheUser();
if (kind.equals("Dog") {
    a = new Dog();
}
else {
    a = new Cat();
}
a.eat();

ここでは明らかに、コンパイラはコンパイル時にそれaが Dog であることを認識できません。それは猫かもしれません。したがって、動的バインディングを使用する必要があります。

これで、あなたの例では、コンパイラが認識して最適化できると言えます。しかし、それは Java が設計された方法ではありません。JIT コンパイラーのおかげで、ほとんどの最適化は実行時に行われます。JIT コンパイラーは、(おそらく) 実行時にこの最適化を行うことができます。また、静的コンパイラーでは実行できない多くのことを行うことができます。したがって、Java は静的コンパイラとバイトコードをより単純化し、最適化の取り組みを JIT コンパイラに集中させることにしました。

したがって、コンパイラがこれをコンパイルするときは、その行だけを気にしd.eat()ます。dDog 型eat()であり、Dog クラス階層に存在するオーバーライド可能なメソッドであり、このメソッドを動的に呼び出すために使用されるバイトコードが生成されます。

于 2016-11-04T11:23:18.097 に答える