Java单继承构造方法疑问:父类构造器为何调用子类getName且返回null?
Java构造方法与子类重写的常见问题解析
示例代码
package javaapplication32; class Animal { String name = "Animal"; Animal() { System.out.println("Animal's name is: " + getName()); } String getName() { return name; } } class Dog extends Animal { String name = "Dog"; Dog() { System.out.println("Dog's name is: " + getName()); } String getName() { return name; } } public class JavaApplication32 { public static void main(String[] args) { Dog dog = new Dog(); } }
运行结果对比
实际输出
Animal's name is: null
Dog's name is: Dog
预期输出
Animal's name is: Animal
Dog's name is: Dog
问题解答
1. 为何Animal构造器中的getName()方法会调用Dog类的getName()方法?
Java的方法重写机制会根据对象的实际类型匹配方法。创建Dog实例时,JVM首先分配Dog类型的内存空间,对象的实际类型已经是Dog,只是还未执行子类构造逻辑。此时执行父类Animal的构造器,调用getName()时,JVM会优先执行子类Dog中重写的getName()方法,而非父类的原方法。
2. 该方法调用为何没有返回"Dog",而是返回null?
Java对象初始化遵循固定顺序:
- 分配内存,所有实例变量先做默认初始化(引用类型设为
null) - 执行父类构造器
- 执行子类实例变量的显式赋值操作
- 执行子类构造器
当Animal构造器调用Dog的getName()时,子类Dog的name变量还处于默认初始化的null状态——因为此时还没到执行String name = "Dog"这个显式赋值的步骤。直到父类构造执行完毕,才会给Dog的name赋值为"Dog",所以后续Dog构造器调用getName()时就能返回正确值。
内容的提问来源于stack exchange,提问作者isofiso
相关产品推荐
相关产品推荐

