重载与桥接函数

来源:互联网 发布:sql 统计项目函数 编辑:程序博客网 时间:2024/05/24 05:22

        我们首先来看一看下面的代码: 

class Father {
    
public Object test() {
        
return new Object();
    }

}


class Son extends Father {
    
public String test() {
        
return "asd";
    }

}

        父类和子类都有一个test方法,并且参数都为空,根据以往的经验“函数名相同并且参数相同的函数,即视为同一个函数”,因此,我们的第一感觉是子类重载了父类的test方法。但是大家要注意,两个test方法的返回值是不一样的。根据经验,“考察两个方法是否相同时,不考虑返回值”,因此在我们的印象里,返回值不同是不会影响到两个test函数的重载关系的。

        但是作为java的虚拟机,在分辨两个函数是否相同的时候,是要考虑返回值的。因此,上述2个方法在java虚拟机眼中,是不同的2个方法,是不能构成重载关系的。这一点与我们的常识是有差别的。那么,如何处理虚拟机与程序员意识之间的差别呢?Java的编译器通过自动插入桥接函数的方法帮我们解决了这个问题。在子函数中,编译器如果发现了上面的这种情况(函数同名,同参数,但返回值不同),就会认为程序员的意愿是要重载该函数,于是编译器在子函数中自动插入一个桥接函数,即实现了对test函数的重载,又合理的调用了程序员自定义的test函数。就上述例子而言,编译器插入的桥接函数代码如下:       

public Object test() {
    
return (Object)test();    //此处的test表示上面的程序员自定义的test

}

        注意,上述代码是编译器以字节码的形式直接插入到*.class文件中的,而不是以源码的形式插入到*.java文件中。换句话说,如果你手动的将上述代码写入源码中,编译器会报错的。因为“编译器不考虑返回值,但虚拟机考虑返回值”。

原创粉丝点击