类初始化过程

面试问题是写出下面程序的输出,答案为null。java

public class Base {
	private String baseName = "base";
	
	public Base() {
		
		callName();
	}
	
	public void callName() {
		
		System.out.println(baseName);
	}
	
	static class Sub extends Base {
		
		private String baseName = "sub";
		
		public void callName() {
			System.out.println(baseName);
		}
		
		public static void main(String[] args) {
			
			Base b = new Sub();
		}
	}
}

这段代码中类的初始化顺序是这样的,父类静态块 ->子类静态块->父类构造器(属性在构造器中初始化) -> 子类构造器 。面试

摘抄一段靠谱评论:jvm

看我大师归来:
1. Base b = new Sub();
2. Base b = 直接忽略,从 new Sub();开始
3. 类加载器加载 Base,Sub 类到jvm;
4. 为Base,Sub 类中的两个属性baseName 分配存储空间,可是不初始化;
注意:属性的初始化是放在构造器中,按照代码顺序执行的。
5. new Sub会调用Sub的无参构造器,而在这个构造器中会隐式调用父类Base的无参构造器;
6. 父类Base的构造器中代码本质是
public Base()
{
baseName = "base";
callName();
}
即父类的属性baseName 的值为base。但为什么输出null,骚年别急。
7. 由于父类构造器方法是在子类中调用的,即大环境是子类,此时this指向Sub。此时,调用的方法callName()固然是指子类的方法。而这个方法打印的属性baseName固然也是子类的。那如今子类的属性baseName的值是多少呢?答案是null.由于此时子类Sub的构造器内代码本质是:
super();
baseName="sub";
此时baseName="sub"还没执行。this

所以,最后的值固然是null.spa

相关文章
相关标签/搜索