6

我知道重载使用静态绑定,而覆盖使用动态绑定。但如果它们混合在一起呢?根据本教程,为了解决方法调用,静态绑定使用类型信息,而动态绑定使用实际的对象信息。

那么,下面的例子中是否发生了静态绑定来确定sort()调用哪个方法呢?

public class TestStaticAndDynamicBinding {
    
    @SuppressWarnings("rawtypes")
    public static void main(String[] args) {
        Parent p = new Child();
        Collection c = new HashSet();

        p.sort(c);
    }
}

.

public class Parent {
    
    public void sort(Collection c) {
        System.out.println("Parent#sort(Collection c) is invoked");
    }
    
    public void sort(HashSet c) {
        System.out.println("Parent#sort(HashSet c) is invoked");
    }
}

.

public class Child extends Parent {
    
    public void sort(Collection c) {
        System.out.println("Child#sort(Collection c) is invoked");
    }
    
    public void sort(HashSet c) {
        System.out.println("Child#sort(HashSet c) is invoked");
    }
}

ps:输出为: Child#sort(Collection c) is invoked

4

2 回答 2

4

在编译期间,静态绑定确定将使用哪个签名的方法(集合与哈希集)。在执行期间,VM 确定将在哪个对象上调用该方法

于 2015-06-27T07:22:11.387 回答
4

正如您所怀疑的,这里有两个绑定阶段。

首先是静态阶段,即会选择调用sort(Collection c)。这是在编译时完成的,并且由于c是类型的引用,Collection因此无论运行时类型(即 a )如何,都将使用此方法HashSet

然后,在运行时,由于p实际上包含一个Child实例,它的方法将被调用,你会得到"Child#sort(Collection c) is invoked".

于 2015-06-27T07:24:08.913 回答