Java的静态/动态绑定
作者:网络转载 发布时间:[ 2016/11/29 10:47:37 ] 推荐标签:测试开发技术 Java
再看看反编译的结果:
javap -c Test
警告: 二进制文件Test包含CoreJava.day_2.Test
Compiled from "Test.java"
public class CoreJava.day_2.Test {
public CoreJava.day_2.Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2 // class java/lang/String
3: dup
4: invokespecial #3 // Method java/lang/String."<init>":()V
7: astore_1
8: new #4 // class CoreJava/day_2/Test$SecLee
11: dup
12: invokespecial #5 // Method CoreJava/day_2/Test$SecLee."<init>":()V
15: astore_2
16: aload_2
17: aload_1
18: invokevirtual #6 // Method CoreJava/day_2/Test$Lee.say:(Ljava/lang/String;)V
21: return
}
正如上面的结果,18: invokevirtual #6 // Method CoreJava/day_2/Test Lee.say:(Ljava/lang/String;)V这里是TestLee.say而非Test$SecLee.say,因为编译期无法确定调用子类还是父类的实现,所以只能丢给运行时的动态绑定来处理。
既然重写测试了,那我们再试试重载:
下面的例子更复杂!Lee类中存在say方法的两种重载,更复杂的是SecLee集成Lee并且重写了这两个方法。其实这种情况是上面两种情况的复合情况。
下面的代码首先会发生静态绑定,确定调用参数为String对象的say方法,然后在运行时进行动态绑定确定执行子类还是父类的say实现。
public class Test {
public static void main(String[] args) {
String str = new String();
Lee lee = new SecLee();
lee.say(str);
}
static class Lee {
public void say(Object obj) {
System.out.println("这是Object");
}
public void say(String str) {
System.out.println("这是String");
}
}
static class SecLee extends Lee {
@Override
public void say(Object obj) {
System.out.println("这是第二李的Object");
}
@Override
public void say(String str) {
System.out.println("这是第二李的String");
}
}
}
结果:
$ java Test
这是第二李的String
结果在意料之中,不多说了。
那么问题来了,非动态绑定不可么?
其实某些方法的绑定也可以由静态绑定实现,比如说:
public static void main(String[] args) {
String str = new String();
final Lee lee = new SecLee();
lee.say(str);
}
可以看出,这里lee持有SecLee的对象并且lee变量为final,立即执行了say方法,编译器理论上通过足够的分析代码,是可以知道应该调用SecLee的say方法。
结论:
由于动态绑定需要在运行时确定执行哪个版本的方法实现或者变量,比起静态绑定起来要耗时,所以正如书上所说的,有些程序员认为,除非有足够的理由使用多态性,应该把所有的方法都声明为final,private或者static进行修饰。我觉得这个有点偏激了,具体使用仁者见仁,智者见智吧。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
Java性能测试有哪些不为众人所知的原则?Java设计模式??装饰者模式谈谈Java中遍历Map的几种方法Java Web入门必知你需要理解的Java反射机制知识总结编写更好的Java单元测试的7个技巧编程常用的几种时间戳转换(java .net 数据库)适合Java开发者学习的Python入门教程Java webdriver如何获取浏览器新窗口中的元素?Java重写与重载(区别与用途)Java变量的分类与初始化JavaScript有这几种测试分类Java有哪四个核心技术?给 Java开发者的10个大数据工具和框架Java中几个常用设计模式汇总java生态圈常用技术框架、开源中间件,系统架构及经典案例等
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11热门文章
常见的移动App Bug??崩溃的测试用例设计如何用Jmeter做压力测试QC使用说明APP压力测试入门教程移动app测试中的主要问题jenkins+testng+ant+webdriver持续集成测试使用JMeter进行HTTP负载测试Selenium 2.0 WebDriver 使用指南