类加载机制(父子类)
如有错误,敬请指正自己学的不够粗浅,翻阅资料并结合IDE的Debug-Console写下的这篇博文。在进一步的详尽解释有待实力提高后再回来补充完善。
- 在本例中JVM对类进行加载的时候,会先分配堆空间,对所有非静态的引用赋值为null,之后才对栈空间赋值
- 为更好理解,更推荐读者可以将代码拷贝到自己的IDE中Debug查看其加载顺序
- 同时也可以看代码中的注释,进行理解。
- 在此说明:由于子类构造中super()必须放在首行,又不想引入静态块输出,故而控制台前五句输出,
并非Father中无参构造方法的执行效果!
- 以下是控制台输出内容和详细代码
这里是Console的输出内容
由Father father = new Child();出发
首先加载子类Child无参,并对成员变量分配堆空间>>>
(若没有子类无参||若子类无参中有没有super(),JVM默认提供)
之后执行子类无参的super(),到Father类后,分配其成员变量的堆空间>>>
紧接着对其成员变量栈空间>>>>>>赋值
```由于Child(){}中super()必须在首行,这里假装构造开始```
constractorChild start...
constractorFather start...
调用父类普通成员方法call()
父类独有成员方法,输出结束
当子类重写与父类同名的成员方法后,该实例,则会去子类执行:
这里是子类重写父类的同名方法......
由于poo仅在Child(){}无参中分配过堆空间,却没有栈空间赋值
故而输出poo=null
由于ooo在Father类中已经被分配栈空间
故而输出ooo=ooo
constractorFather finished...
子类成员变量栈空间>>>>>>赋值结束
child成员变量oo=oo
constractorChild finished...
--------
父类普通方式执行......
这里是子类重写父类的同名方法......
由于poo仅在Child(){}无参中分配过堆空间,却没有栈空间赋值
故而输出poo=child
由于ooo在Father类中已经被分配栈空间
故而输出ooo=ooo
这里是Test.java
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Father father = new Child();
System.out.println("--------");
System.out.println();
System.out.println("父类普通方式执行......");
father.callName();
}
这里是Father.java
public class Father {
private String foo = "father";
public String ooo = "ooo";
public String getOoo() {
return this.ooo;
}
public Father() {
System.out.println("由Father father = new Child();出发");
System.out.println("首先加载子类Child无参,并对成员变量分配堆空间>>>");
System.out.println("(若没有子类无参||若子类无参中有没有super(),JVM默认提供)");
System.out.println("之后执行子类无参的super(),到Father类后,分配其成员变量的堆空间>>>");
System.out.println("紧接着对其成员变量栈空间>>>>>>赋值");
System.out.println();
System.out.println("由于Child(){}中super()必须在首行,这里假装构造开始");
System.out.println();
System.out.println("constractorChild start...");
System.out.println();
System.out.println("constractorFather start...");
System.out.println("调用父类普通成员方法call()");
call();
System.out.println("当子类重写与父类同名的成员方法后,该实例,则会去子类执行:");
callName();
System.out.println("constractorFather finished...");
}
public void call(){
System.out.println("\t父类独有成员方法,输出结束");
System.out.println();
}
public void callName() {
System.out.println("222");
System.out.println(foo);
}
}
这里是Child.java
class Child extends Father {
private String poo = "child";
private String oo = "oo";
public Child() {
super();
System.out.println("子类成员变量栈空间>>>>>>赋值结束");
System.out.println("child成员变量oo="+oo);
System.out.println("constractorChild finished...");
}
public void callName() {
System.out.println("这里是子类重写父类的同名方法......");
System.out.println("由于poo仅在Child(){}无参中分配过堆空间,却没有栈空间赋值");
System.out.println("故而输出poo="+poo);
System.out.println();
System.out.println("由于ooo在Father类中已经被分配栈空间");
System.out.println("故而输出ooo="+super.getOoo());
}
}