1

我在多个地方读到最终方法是早期绑定的,但没有一个提供令人满意的理由。我怀疑即使在父类引用上调用的最终方法中,它怎么可能如此coz,编译器无法说明是调用父类的非最终方法还是子类的最终方法。
请指教。

class Parent {
    void meth() {
       System.out.println("parent");
}
}

class Child extends Parent {

@Override
final void meth() {
    // TODO Auto-generated method stub
    System.out.println("child");
}

public static void main(String[] args) {
    Parent parent = new Parent();
    Parent child = new Child();
    child.meth();
    parent.meth();
}
}  

在上面的代码中,调用子方法(父引用)的方法 meth() 是最终方法,但是 JVM 应该需要在运行时使用方法查找表,就像调用的子方法或父方法一样。

4

2 回答 2

3

自然,只有当引用的静态类型是方法具有 final 说明符的类时,才会发生早期绑定。

于 2012-09-15T00:48:13.210 回答
1

java中的绑定分两个阶段进行。在编译时,编译器已知的引用类型用于将方法绑定到可能是类型层次结构的最高方法。例如,如果在 Number 类型变量上调用 toString(),那么编译器知道它必须调用 Number.toString() 或子类覆盖而不是 Object.toString()。

其次,在运行时调用方法时,会查看对象的运行时类型,并找到并调用类型层次结构中最具体的方法。即在上面的 Number.toString 的情况下,如果对象是 Integer,它将找到 Integer.toString 并调用它。

如果方法在引用/变量的类型中是最终的,那么可以跳过第二步,因为我们知道不能有子类覆盖。这就是 Dima Rudnick 所说的静态类型。再次以我的示例为例,如果 Number.toString 是最终的,并且变量是 Number 类型,那么我们不需要查看运行时类型来知道我们正在调用什么方法。

注意:出于此目的,我假设 Object、Number 和 Integer 都具有特定的 toString 方法,而不是依赖于继承的方法。

于 2012-09-15T01:05:45.770 回答