多态是java执行方法的多态,只有方法存在多态,成员变量不存在多态,因为多态存在重写,重载因此导致同一个符号不能表示唯一的方法。
多态存在的三个条件:
1 继承
2 方法重写
3 父类引用指向子类对象
java程序的运行过程:
java文件(.java)在编译过程中被解析成字节码文件(.class)后被JVM执行。
编译成字节码文件:
Java中某个类的class文件包含以下内容:
1. 魔数(Magic Number):一个固定的4字节值,用于标识该文件是否为有效的Java字节码文件。
2. 版本号(Version):指示该class文件的版本信息。
3. 常量池(Constant Pool):一个表结构,用于存储字面量(如字符串、数字等)和符号引用(如类、方法、字段等)的常量。
4. 访问标志(Access Flags):用于表示该类的访问修饰符,如public、private、final等。
5. 类索引(This Class):指向该类在常量池中的索引。
6. 父类索引(Super Class):指向该类的父类在常量池中的索引。
7. 接口索引集合(Interfaces):指向该类实现的接口在常量池中的索引。
8. 字段表集合(Fields):描述该类的字段信息,包括字段名称、修饰符、类型等。
9. 方法表集合(Methods):描述该类的方法信息,包括方法名称、修饰符、参数类型、返回类型等。(虚方法表就存方法表中)
10. 属性表集合(Attributes):描述该类的附加属性信息,如源文件名、注解等。
方法调用底层原理-两种分派:
当java程序被编译成字节码文件时java的方法之间的调用和方法调用都是用符号来代表的,符号存放在常量池中,当字节码文件被JVM加载符号才会被方法所在的具体的空间地址替换。但是由于方法的重载,重写,导致符号对应的方法可能是一个虚方法,只有在具体运行中才能知道具体是什么方法(动态分派),因此在JVM加载时要得到符号所对应的版本是哪个(就是得到具体对应的是哪个对象)还有一部分方法是常量池中符号确定对应的方法(通过常量池符号静态声明的方法,静态分派)
字节码文件被JVM解析成机器码执行。
根据方法调用底层原理来分析下面的例子
具体例子:
最后打印的结果是三个 人类的狂欢!
对象调用方法的范围是根据静态类型来判断的 这个例子中静态类型都是Human