刚才复习了下面向对象类的加载以及对象的初始化,看下面一段代码
- public class Dog extends NewAnimal {
-
- static {
- printInfo("Dog静态代码块执行");
- }
-
- static Cat mc1 = new Cat();
- static Cat mc2 = new Cat();
-
- public static void main(String[] args) {
- Dog.printInfo("总算进入了main函数了,准备工作太多了,好累啊-----------------------");
- new Dog();
- }
- {
- Dog.printInfo("Dog构造块代码执行");
- }
- public Dog() {
- Dog.printInfo("Dog构造方法执行,创建了一个Dog对象");
- }
-
- public static void printInfo(Object o) {
- System.out.println(o);
- }
- }
- class NewAnimal extends LivingThings {
- {
- Dog.printInfo("NewAnimal构造块执行");
- }
- static {
- Dog.printInfo("NewAnimal静态代码块执行");
- }
-
- public NewAnimal() {
- Dog.printInfo("NewAnimal构造方法执行");
- }
- static Cat mc1 = new Cat();
- static Cat mc2 = new Cat();
- static {
- Dog.printInfo("NewAnimal静态代码块执行-----第二次");
- }
- }
- class LivingThings {
- static Cat mc1 = new Cat();
-
- {
- Dog.printInfo("LivingThings构造代码块执行");
- }
- static {
- Dog.printInfo("LivingThings静态代码块执行");
- }
- public LivingThings() {
- Dog.printInfo("LivingThings构造方法执行");
- }
- static Cat mc2 = new Cat();
- static {
- Dog.printInfo("LivingThings静态代码块执行---第二次");
- }
- }
- class Cat {
- static int count1 = 1;
- static int count2 = 1;
-
- {
- Dog.printInfo("Cat构造块执行"+ count2++);
- }
- static {
- Dog.printInfo("Cat静态代码块执行");
- }
- public Cat() {
- Dog.printInfo("Cat构造方法执行" + count1++);
- }
- }
复制代码 代码总结,首先运行程序后jvm将编译好的.class文件加载进内存,同时执行static修饰的数据(包括字段,静态代码块)
1.首先加载静态数据之前先看看有没有父类,如果有,就去加载他的父类中的静态数据,就这样一直找下去直到找到Object,然后才从最终父类加载到最终子类
2.加载时,如果有静态字段和静态代码块他们没有执行先后顺序,是按照代码的前后文顺序由上至下执行(与构造代码块和构造方法不同,构造代码块优先于构造方法执行)
3.加载完所有类之后,第三步就是执行main()方法创建对象了,看看上面的这段代码吧
首先加载运行的类Dog,加载时发现他还有父类,暂停加载该类,找他父类加载去,父类还有父类,一直找到他的老祖宗Object中去,加载完Object之后就加载LivingThings,之后执行
static Cat mc1 = new Cat();加载Cat类初始化两个变量后执行静态代码块,然后创建Cat对象,先调用构造代码块接着执行构造方法,下面才加载LivingThings,NewAnimal,Dog全部加载完毕后进入main()方法,创建对象,创建对象也是一层一层的往上找,找到最终父类后由上往下一级一级的调用构造方法(如果有构造块限于构造方法执行)。应该就是这样吧,大家有什么意见多提提吧
|