zoukankan      html  css  js  c++  java
  • Java方法执行过程

    弄清调用对象方法的执行过程十分重要,下面是调用过程的详细描述。

    1)编译器查看对象的声明类型和方法名,假设调用x.f(param),且隐式参数x声明为C类的对象。需要注意的是有可能存在多个名字为f但参数类型不一样的方法(overload)。例如,可能存在f(int)和f(String)的方法,编译器会一一列举所有C类中名为f的方法和其超类中访问属性为public且名为f的方法(超类的私有方法不可访问)。

    至此,编译器已经获得了所有可能被调用的候选方法名字。

    2)接下来,编译器将查看调用方法时提供的参数类型,如果在所有名为f的方法中存在一个于提供的参数类型完全匹配,就选择这个方法。这个过程被叫做重载解析(overloading resolution),例如,对于调用x.f("hello")来说,编译器就会挑选f(String)而不会是f(int)。由于允许类型转换(int可能转成Double,子类转成超类),所以这个过程可能会很复杂。如果编译器没有找到于参数类型匹配的方法,或者发现经过类型转换之后有多个方法与之匹配,就会报错。

    (方法的名字和参数列表被成为方法的签名,如果子类中定义了一个与超类签名相同的方法,那么子类中的这个方法就覆盖了超类中相同的签名。简而言之,子类调用方法,自己有就调用自己的,自己没有就调用超类的。并且允许子类将覆盖方法的返回类型定义为原返回类型的子类型)

    至此,编译器已经获得了需要调用的方法名字和参数类型。

    3)如果是private,static,final方法或者构造器,那么编译器就可以准确的知道调用某个方法,这种调用方式被成为静态绑定(static binding)。与此对应的是,调用的方法依赖于隐式参数的实际类型,并且在运行时实现动态绑定。

    (静态绑定:不能被继承的方法,如果被调用就可以确定是哪个方法。)

    (动态绑定:方法可能被重写 需要根据调用的对象类型调用具体的方法)

    4)当程序运行时,并且采用动态绑定调用方法时,虚拟机一定调用与x所引用对象的实际类型最合适的那个类的方法。假设x的实际类型为D,它是C类的子类,如果D类定义了方法f(Stringn)就直接调用它。否则将在D类中的超类中寻找(先找最亲的)以此类推。

    每次调用方法都需要搜索,时间开销相当大,为此,虚拟机预先为每个类创建了一个方法表(method table),其中列出了所有方法的签名和实际调用的方法,这样一来真正调用方法的时候虚拟机直接查这个表。在前面的例子中,虚拟机搜索D类的方法表,以便寻找与调用f(String)相匹配的方法,这个方法既有可能是D.f(String),也有可能是X.f(String),这里X是D的超类。这里需要注意的是,如果调用super.f(String),编译器将对隐式参数超类的方法表进行搜索。

    不和别人一样,不复制只真正理解
  • 相关阅读:
    JavaEE——SpringMVC(11)--拦截器
    JavaEE——SpringMVC(10)--文件上传 CommonsMultipartResovler
    codeforces 460A Vasya and Socks 解题报告
    hdu 1541 Stars 解题报告
    hdu 1166 敌兵布阵 解题报告
    poj 2771 Guardian of Decency 解题报告
    hdu 1514 Free Candies 解题报告
    poj 3020 Antenna Placement 解题报告
    BestCoder5 1001 Poor Hanamichi(hdu 4956) 解题报告
    poj 1325 Machine Schedule 解题报告
  • 原文地址:https://www.cnblogs.com/Vinlen/p/12737828.html
Copyright © 2011-2022 走看看