类的加载次序与继承

Posted 花间岛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类的加载次序与继承相关的知识,希望对你有一定的参考价值。

原创转载请注明出处:http://www.cnblogs.com/chaeyeon/p/6146169.html


如果:A extends B
1.若要加载类A,应先加载父类B。而只要加载一个类,静态字段就会分配内存,静态代码块就会执行。则先为父类B(Object)的静态变量分配内存以及执行父类的静态语句块(执行先后顺序按由书写执行决定)。

2.然后再加载子类A,及为类A的静态变量分配内存以及执行类A的静态语句块。(并且1、2步骤只会在类第一次加载的时候执行,即最多执行一次)

结论一:子类的加载,必须先加载其父类,类的加载伴随着,静态变量的内存分配,静态语句的执行。
可以通过:Class.forname(A)加载类A。在父类的静态代码中输出父类中的静态变量,并在子类的静态代码块中输出子类的静态字段来验证1,2结论。

3.若需实例化类A,则在子类的构造方法执行之前,先调用其父类B的构造函数。并且在调用其父类B的构造函数前、在父类中会发生:
        1.父类B中的非静态变量分配内存以及执行父类中的非静态语句块.再调用父类B中的构造函数初始化初始化父类中的字段(因为父类中的字段要被子类继承,而字段的初始化,要通过自己的构造函数完成)。

2.然后再给类A中的非静态变量分配内存以及执行类A非静态语句块.最后调用A中的构造函数初始化。( 并且第次实例化子类对象的时候过程3都会发生)

结论二:实例化对象的时候需要调用构造方法,由于子类继承父类的成员变量,所以实例化子类的时候,在子类的构造方法中一定要先调用了父类的构造方法(super()在子类的构造方法的第一行)来给子类中继承自父类的字段初始化,然后再执行子类中的构造函数来初始化子类特有的字段,这个步骤,会在每次实例化子类对象的时候重复执行。注意:一个类构造方法每次被调用之前,一定会先执行一次该类中的实例语句块。

5.对于静态方法和非静态方法都是被动调用,即系统不会自动调用执行,所以用户没有调用时都不执行,方法都存放在方法区中(静态区)等待用户的调用。只有用户调用时才给方法中的局部变量分配内存。

注意:加载不意味着执行!!!

总结:
子类的加载必先加载父类。类的加载伴随着静态变量的分配与静态语句块的执行(这个过程只会类第一次被加载时执行 )
子类的实例化,伴随着父类的实例化(先实例化父类,然后实例化子类),此时伴随着成员变量和实例语句块的执行(这个过程在每次实例化子类的时候都会发生)

继承:
1.子类会继承父类中所有的字段和方法(包括私有的字段和方法),但构造方法不能被继承。

2.子类即使继承了父类的私有字段,也不能直接访问,只能间接访问,或不能访问(但是可以通过父类提供的公开的方法中来做到间接地访问父类中私有的成员字段或方法,既然能被访问,说明子类为父类的私有字段分配了空间,继承了父类的私有字段,不然数据往那里存)
图片
通过.net的调试器,可以清楚的验证这一结论,既然子类中可以访问父类的成员方法的成员变量那么可以理解为在子类对象中包含一个父类对象。

3.构造方法虽然不能被继承,但是子类中的任何一个构造方法执行前都会执行父类的构造方法。目的同继承为了减少代码的重复因为可以通过在子类中调用父类的构造来初始化子类,而不用在子类中在写一遍对父类中成员变量赋值的代码(如果子类中不显示地调用默认调用父类的无参构造,可以在父类中的无参构造中输出一名话,然后在实现化一个子类来验证)

4.子类可以通过方法的重写,或字段的重名来覆盖都父类中的方法或都字段。但是只要该字段或方法在父类中不是私有的,在子类中仍然可以通过”super.“字段名或方法名去访问。

5.this表示的就是当前对象,谁调用就指代谁,this就是对象的引象,保证对象的地址,每一个对象都有this存在堆中,可以理解为Object o=new Object();new返回的就是堆中对象中的this(this保存对象的引用,它的含义等价引用)静态代码段中没有this

6、super(或者base)都是指代当前子类对象中的父类型的特征。super指代子类从父类中继承过来的字段或方法,用于区分子类中重写父类的方法或者子类覆盖父类的中的字段,就可以通过”super.“方法名或字段名来显示的在子类中调用父类中的方法或字段,即使这些方法或字段被子类重写或覆盖。super不是引用,不保存内存地址,它只是存在于this中来指代子类从父类继承过来的数据(即父类中的数据),和子类中特有的数据。this能存在的地方super就存在,super是this的组成部分。
验证:
图片
 
从这张图看所谓的继承应该很明了

 

以上是关于类的加载次序与继承的主要内容,如果未能解决你的问题,请参考以下文章

正文Java类加载器( CLassLoader ) 死磕 4: 神秘的双亲委托机制

[实验6]类的继承与多态

带有继承和静态的类的初始化以及加载过程(重要)

子类继承父类,子类执行的时候,父子类的执行顺序?

静态代码块类的继承和接口

java 中类的加载顺序