java多态/重载方法——一个疑难代码引发的讨论
直接上代码,看这个代码发现自己的基础有多差了。参考 http://www.cnblogs.com/lyp3314/archive/2013/01/26/2877205.html和http://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基础还是得恶补。
java多态/重载方法——一个疑难代码引发的讨论的更多相关文章
- 类与接口(五)java多态、方法重写、隐藏
一.Java多态性 面向对象的三大特性:封装.继承.多态. 多态的类型,分为以下两种: 编译时多态: 指的是 方法重载.编译时多态是在编译时确定调用处选择那个重载方法,所以也叫 静态多态,算不上真正的 ...
- Java 多态 虚方法
Java中多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载. 看代码: package com.company; public class Main { public stati ...
- JAVA用JNI方法调用C代码实现HelloWorld
一.首先是java运行环境的搭建,到官网下载java jdk安装即可(注意要修改环境变量).还可以顺便安装eclipse. 二.编写java代码,文件名HelloWorld.java public c ...
- java对象的方法属性和代码块的加载顺序
1.静态变量 2.静态代码块 3.局部代码块 4.构造函数 5.普通代码块 6.静态方法 7.普通方法 8.普通属性 for example: package com.JavaTest2; publi ...
- java中的方法——重载yu重写(转)
重载(Overloading) (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型. 重载Overloading是一个类中多态性的一种表现. ...
- Parallel.For 你可能忽视的一个非常实用的重载方法
说起Parallel.For大家都不会陌生,很简单,不就是一个提供并行功能的for循环吗? 或许大家平时使用到的差不多就是其中最简单的那个重载方法,而真实情况 下Parallel.For里面有14个重 ...
- 【转】 Java多态特性:重载和覆写的比较
Java重载: 在同一个类中 方法具有相同的名字,相同或不同的返回值,但参数不同的多个方法(参数个数或参数类型) public class MethoDemo{ public static void ...
- Java如何使用重载方法处理异常?
在Java编程中,如何使用重载方法处理异常? 此示例显示如何使用重载方法来处理异常.需要在每个方法中使用try catch块. package com.yiibai; public class Exc ...
- Java多态特性:重载和覆写的比較
Java重载: 在同一个类中 方法具有同样的名字,同样或不同的返回值,但參数不同的多个方法(參数个数或參数类型) public class MethoDemo{ public static void ...
随机推荐
- CoreText实现图文混排之点击事件-b
CoreText实现图文混排之点击事件 主要思路 我们知道,CoreText是基于UIView去绘制的,那么既然有UIView,就有 -(void)touchesBegan:(NSSet<UIT ...
- C#导入导出数据到Excel的通用类代码
Excel文件导入导出,需引用Microsoft Excel 11.0 Object Library ///////////////////////////////////////////////// ...
- 解决websphere在aix linux下日志乱码
管理控制台--->服务器--->应用程序服务器--->server1--->java和进程管理--->进程定义--->java虚拟机--->将通用jvm参数设 ...
- SDUT 2622 最短路径(Dijkstra)
点我看题目 题意 :中文不详述. 思路 :因为这个题加了一个要求就是路径数目得是x的倍数.所以在原来算法的一维dis数组增加到二维,用来存走的路径数%x.也可以用spfa做. #include < ...
- DJANGO模板的BLOCK自定义技巧
除了INCLUDE, EXTENDS基本的继承模板之外,如果想在本模板上,直接生成让同类页面继承的模板, 则可以需要自定义的地方实现自定义BLOCK, 先在本页面实现自己的BLOCK,然后,在继承的页 ...
- UIcollectionView的使用(首页的搭建3)
2.4 数据统计cell 2.4.1 创建cell,继承自UICollectionViewcell 2.4.2导入详情头文件并且创建详情view 2.4.2.1创建详情view,继承自uiview,定 ...
- SQLite入门与分析(八)---存储模型(1)
写在前面:SQLite作为嵌入式数据库,通常针对的应用的数据量相对于通常DBMS的数据量是较小的.所以它的存储模型设计得非常简单,总的来说,SQLite把一个数据文件分成若干大小相等的页面,然后以B树 ...
- ANDROID_MARS学习笔记_S01原始版_015_Socket
一.代码1.xml(1)main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayo ...
- WCF - Overview
WCF stands for Windows Communication Foundation. The elementary feature of WCF is interoperability. ...
- 转自 Good morning 的几句精辟的话
1.志愿者招募 根据流量平衡方程来构图非常方便,而且简单易懂,以后可能成为做网络流的神法之一 简单记一下流量平衡方程构图法的步骤: a.列出需求不等式 b.通过设置松弛变量,将不等式变成等式 c.两两 ...