zoukankan      html  css  js  c++  java
  • java多态/重载方法——一个疑难代码引发的讨论

      直接上代码,看这个代码发现自己的基础有多差了。参考 http://www.cnblogs.com/lyp3314/archive/2013/01/26/2877205.htmlhttp://hxraid.iteye.com/blog/428891 以及 《深入Java虚拟机》

      这个问题是java获取动态绑定最终的方法?涉及的知识有继承、多态、重载、方法调用的整合。

    public class Poly {
    
        public static void main(String[] args) {
            A a1 = new A();
            A a2 = new B();
            B b = new B();
            C c = new C();
            D d = new D();
            System.out.println(a1.show(b));
            System.out.println(a1.show(c));
            System.out.println(a1.show(d));
            System.out.println(a2.show(b));
            System.out.println(a2.show(c));
            System.out.println(a2.show(d));
            System.out.println(b.show(b));
            System.out.println(b.show(c));
            System.out.println(b.show(d));
    
        }
    }
    
    class A {
        public String show(D obj) {
            return ("A and D");
        }
    
        public String show(A obj) {
            return ("A and A");
        }
    }
    
    class B extends A {
        public String show(B obj) {
            return ("B and B");
        }
    
        public String show(A obj) {
            return ("B and A");
        }
    }
    
    class C extends B {
    }
    
    class D extends B {
    }

      直接上结论:  

    A and A
    A and A
    A and D
    B and A
    B and A
    A and D
    B and B
    B and B
    A and D

      摘抄结论:

      (1) 所有私有方法、静态方法、构造器及初始化方法<clinit>都是采用静态绑定机制。在编译器阶段就已经指明了调用方法在常量池中的符号引用,JVM运行的时候只需要进行一次常量池解析即可。 

          (2) 类对象方法的调用必须在运行过程中采用动态绑定机制。

               首先,根据对象的声明类型(对象引用的类型)找到“合适”的方法。具体步骤如下:

               ① 如果能在声明类型中匹配到方法签名完全一样(参数类型一致)的方法,那么这个方法是最合适的。

               ② 在第①条不能满足的情况下,寻找可以“凑合”的方法。标准就是通过将参数类型进行自动转型之后再进行匹配。如果匹配到多个自动转型后的方法签名f(A)和f(B),则用下面的标准来确定合适的方法:传递给f(A)方法的参数都可以传递给f(B),则f(A)最合适。反之f(B)最合适 。 

               ③ 如果仍然在声明类型中找不到“合适”的方法,则编译阶段就无法通过。 

               然后,根据在堆中创建对象的实际类型找到对应的方法表,查找方式同声明类型。

      挨个解读:

    •  System.out.println(a1.show(b));   //a1声明为A类型,A中不存在完全匹配的方法,对b向上转型为A,确定调用A.show(A)方法,a1实际类型为A类型,运行方法为A.show(A)方法。
    • System.out.println(a1.show(c)); //a1声明为A类型,A中不存在完全匹配的方法,对c向上转型为A,确定调用A.show(A)方法,a1实际类型为A类型,运行方法为A.show(A)方法。
    • System.out.println(a1.show(d));   //a1声明为A类型,A中存在完全匹配的方法,调用A.show(D)方法,a1实际类型为A类型,运行方法为A.show(D)方法。
    • System.out.println(a2.show(b));   //a2声明为A类型,A中不存在完全匹配的方法,对b向上转型为A,确定调用A.show(A)方法,a2实际类型为B类型,B类型覆盖了A.show(A),运行B.show(A)方法。
    • System.out.println(a2.show(c));   //a2声明为A类型,A中不存在完全匹配的方法,对c向上转型为A,确定调用A.show(A)方法,a2实际类型为B类型,B类型覆盖了A.show(A),运行B.show(A)方法。
    • System.out.println(a2.show(d));  //a1声明为A类型,A中存在完全匹配的方法,调用A.show(D)方法,a2实际类型为B类型,运行方法为B.show(D)方法。
    • System.out.println(b.show(b));    //b声明为B类型,B中存在完全一致的方法,调用B.show(B)方法,b实际类型为B类型,运行方法为B.show(B)。这是跟a2.show(b)最大的不同。
    • System.out.println(b.show(c));    //b声明为B类型,B中不存在完全一致的方法,对c向上转型为B,调用B.show(B)方法,b实际类型为B类型,运行方法为B.show(B)。
    • System.out.println(b.show(d));    //b声明为B类型,B中存在完全一致的方法,调用B.show(D)方法,b实际类型为B类型,运行方法为B.show(D)。
      总体上是jvm关于方法调用的机制不熟悉导致问题不懂,java基础还是得恶补。
  • 相关阅读:
    第4章 Android移植环境搭建
    第3章 Android移植平台工具介绍
    第2章
    第1章 Android系统的编译和移植实例:
    nfs
    TFTP服务器搭建
    根系统制作
    nfs挂载
    uboot的编译
    交叉工具链的搭建方法
  • 原文地址:https://www.cnblogs.com/jason0529/p/5280529.html
Copyright © 2011-2022 走看看