0

经过 2-3 小时后才知道,compile-time 和 run-time有什么区别。最后,我想出了这个。

在运行时分配的内存称为运行时/动态绑定,在编译时分配的内存称为编译时/静态绑定。

然后我尝试了这个例子

class myclass {

    void here() {
        System.out.println("Here from myclass !!");
    }

    void here(int i) {
        System.out.println("Here !!" + i);
    }
}

class thisclass extends myclass {

    void here() {
        System.out.println("Here from thisclass !!");
    }
}

public class poly {

    public static void main(String s[]) {
        myclass m= new myclass();
        myclass a= new thisclass();
        m.here();
        m.here(12);
        a.here();
        a.here(13);
    }
} 

所以,我还发现这myclass a= new thisclass();被认为是运行时绑定。由于,a是 的对象myclass,但突然编译器发现,类不匹配。因此,它将动态绑定thisclass对象的空间。

所以,直到这里,我得到了东西。但是,我发现,另一个常见的答案是重载引用编译时和覆盖引用运行时。我没有明白这一点。

thisclass a= new thisclass();
a.here();

这是否也称为运行时绑定。?? 请纠正我,如果在这里写错了。

4

3 回答 3

4

首先,内存分配不在这张图中。没有编译时内存分配。

该问题将编译时与静态绑定和运行时与动态绑定混为一谈。

静态绑定发生在编译时;动态绑定发生在运行时。

现在,当你写

myclass m= new thisclass();
m.here(18);

在编译时发生的是方法签名的解析:您正在调用here(int)并且该选择是最终的。这被称为“静态绑定”。在运行时发生的是方法分派:运行时选择一个here(int)适合于 所引用对象的运行时类型的实现m。有两种方法可供选择:myclass.m(int)thisclass.m(int),并且运行时在此特定示例中选择后者。这被称为“动态绑定”。

至于您的问题“对于动态绑定来说是压倒一切的强制性”... Java 语言规范规定了选择在运行时调用的正确方法的规则。对于一般情况,这些规则意味着称为“动态绑定”的过程。但是,如果您要问是否有任何特定过程总是在运行时发生,那么情况就不同了:优化的 JIT 编译器可以看到只有一种方法可供选择,并输出一个“单态调用站点”,它对单个选择进行硬编码。此外,它还可以将整个方法内联到调用者中,从而甚至删除调用本身。

于 2012-11-05T13:30:17.860 回答
0

这:

thisclass a= new thisclass();
a.here();

不是运行时绑定,因为编译器知道要调用什么 here() 方法(来自此类的那个)。但如果你说:

myclass a= new thisclass();
a.here();

那么将是一个运行时绑定。

PS:您的班级名称应以大写字母开头。

于 2012-11-05T13:17:32.937 回答
0

但是,我发现,另一个常见的答案是重载引用编译时和覆盖引用运行时。我没有明白这一点。

重载意味着在同一个类中有多个具有不同参数的方法。调用哪个方法在编译时是已知的,因为此时指定了参数。

覆盖意味着在子类中重新定义父类的方法。

于 2012-11-05T13:30:43.057 回答