Java重载(OverLoad)的理解
来源:互联网 发布:什么是java框架 编辑:程序博客网 时间:2024/05/21 10:35
```public class Test{static abstract class Human{}static class Man extends Human{}static class Woman extends Human{}public void sayHello(Human guy){System.out.println("hello guy");}public void sayHello(Man guy){System.out.println("hello gentleman");}public void sayHello(Woman guy){System.out.println("hello lady");}public static void main(String[] args){Human man = new Man();Human woman = new Woman();Test sr = new Test();sr.sayHello(man);sr.sayHello(woman);}}```
`该类的运行结果为
hello guy
hello guy
由此可见虽然调用sayHello方法时入参实际是Human的子类实例,但是在JVM看来man、woman两个入参是
Human的实例。为了验证man、woman的类型可以采用javap这条编译指令:
Compiled from "Test.java"public class Test { public Test(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>"()V 4: return public void sayHello(Test$Human); Code: 0: getstatic #16 // Field java/lang/System.out:Ljavaio/PrintStream; 3: ldc #22 // String hello guy 5: invokevirtual #24 // Method java/io/PrintStream.printn:(Ljava/lang/String;)V 8: return public void sayHello(Test$Man); Code: 0: getstatic #16 // Field java/lang/System.out:Ljavaio/PrintStream; 3: ldc #33 // String hello gentleman 5: invokevirtual #24 // Method java/io/PrintStream.printn:(Ljava/lang/String;)V 8: return public void sayHello(Test$Woman); Code: 0: getstatic #16 // Field java/lang/System.out:Ljavaio/PrintStream; 3: ldc #37 // String hello lady 5: invokevirtual #24 // Method java/io/PrintStream.printn:(Ljava/lang/String;)V 8: return public static void main(java.lang.String[]); Code: 0: new #42 // class Test$Man 3: dup 4: invokespecial #44 // Method Test$Man."<init>":()V 7: astore_1 8: new #45 // class Test$Woman 11: dup 12: invokespecial #47 // Method Test$Woman."<init>":()V 15: astore_2 16: new #1 // class Test 19: dup 20: invokespecial #48 // Method "<init>":()V 23: astore_3 24: aload_3 25: aload_1 26: invokevirtual #49 // Method sayHello:(LTest$Human;)V 29: aload_3 30: aload_2 31: invokevirtual #49 // Method sayHello:(LTest$Human;)V 34: return}
jvm编译时生成的调用方法的符号引用,入参全部标识为Human类。
这是为什么呢?这就需要从JVM 进行讲解了,在代码中定义的Human类成为静态类型,而Man、Woman类则成为实际类型。静态类型在编译期是可知的,但是动态类型只有在运行时才可以确定。解释了这两个概念,结合代码阐述一下,main方法中两次调用sayHello(),在方法接受者已经确定是sr的前提下,调用哪个重载方法,就需要根据入参的类型、数量来进行辨别,但是jvm在重载时是根据静态类型而不是实际类型作为判断依据的。并且静态类型在编译期是可知的,所以选择了sayHello(Human guy)作为重载版本,并把这两个方法的调用写入到了invokevirtual指令的参数中。
下面需要强调动态绑定的发生的前提条件:
- 需要有继承
- 父类的引用指向子类对象
- 必须有重写
但是最关键的触发条件是调用重写的方法。
0 0
- Java重载(OverLoad)的理解
- Java方法的重载(overload)
- java 的方法重载overload
- 我理解的重载(overload)和覆盖(override)
- 方法的重载(Overload)
- java的重写(overwrite)与重载(overload)的区别
- java的重载(overload)和覆盖(override)简介
- JAVA方法的重载(overload)和覆盖(override)
- Java重载(overload)和重写(override)的区别
- java重载(overload)与重写(override)的区别
- Java中重载(overload)和重写(override)的区别
- Java中重载(overload)和重写(override)的区别
- Java的重载(Overload)与重写(Override)
- Java的重载(Overload)与重写(Override)
- Overload java重载的一些笔记
- Java的重载(overload)和覆盖(override)
- 方法重载(overload)的例子分析(摘自<深入理解Java虚拟机>)
- java函数重载 overload
- maven在不同环境下打包的应用
- Java 类加载机制详解
- [三进制倍增 || 可并堆] BZOJ 4003 [JLOI2015]城池攻占
- Java的对象是采用值传递还是引用传递?
- SqlServer数据库同步 两张表的数据 去除重复数据
- Java重载(OverLoad)的理解
- php file_put_contents() 读取数据不换行问题
- golang协程资源占有率
- win快捷键大全
- HDOJ(HDU) 2091 空心三角形
- 玩转Google开源C++单元测试框架Google Test系列(gtest)(总)
- 详解HttpURLConnection
- 高精
- [LCT 线段树 dfs序] BZOJ 3779 重组病毒