面试题答案
一键面试- 字节码层面:
- 在编译期,Java编译器会为每个类生成字节码文件。对于包含多态相关方法的类,字节码中会包含这些方法的相关信息。例如,方法的访问标志、名称、描述符等。在子类重写父类方法时,字节码中会保证重写方法与父类被重写方法具有相同的名称、参数列表和返回类型(或其子类型)。这确保了在字节码层面,多态的基本规则得以遵循。
- 运行时数据区:
- 方法区:类加载器将字节码加载到方法区,类的元数据信息(包括方法信息)被存储在此。当涉及多态时,不同类(父类和子类)的方法元数据都在方法区,为动态绑定提供基础。
- 堆:对象实例在堆中创建。每个对象实例在堆中都有一个指向其类元数据(在方法区)的指针。当通过父类引用指向子类对象时,堆中的对象实际是子类实例,通过指针可找到子类的方法元数据。
- 方法调用与动态绑定:
- 当通过父类引用调用重写方法时,在编译期,编译器仅检查该方法在父类中是否存在,进行静态类型检查。
- 在运行期,JVM根据对象的实际类型(即堆中对象所指向的类元数据)来确定要调用的实际方法。这就是动态绑定。例如,假设有父类
Animal
和子类Dog
,Dog
重写了Animal
的makeSound
方法。当Animal animal = new Dog(); animal.makeSound();
执行时,JVM会在运行时根据animal
实际指向的Dog
对象,找到Dog
类中的makeSound
方法并执行,而不是Animal
类中的方法,从而实现多态。