美文网首页
类加载和初始化

类加载和初始化

作者: 小贱嘎嘎 | 来源:发表于2017-08-31 12:47 被阅读0次

    对象的创建过程

    当首次创建某个类的对象时(构造器可看作静态方法),或者类的静态方法/静态域被访问时,Java解释器会定位并加载类的.class文件,所有静态初始化动作都会执行,这个静态初始化动作只执行一次。
    --------------------分割线---------------------
    总结一下对象的创建过程,假设有一个名为Dog的类:
    1,即使没有显式的使用static关键字,构造器实际上也是静态方法。因此当创建类型为Dog的对象,或者Dog类的静态方法/静态域首次被访问时,Java解释器查找类路径,定位Dog.class文件。
    2,载入Dog.class(将会创建一个Class对象),有关静态初始化的动作全部执行。因此,静态初始化只在Class对象首次加载时候进行一次。
    3,当用new Dog()创建对象时,将在堆上分配足够的存储空间。
    4,此块存储空间被清空,所以所有的基本数据类型被设置为默认值,引用类型被置为null。
    5,执行所有出现于字段定义处的初始化动作
    6,执行构造器

    普通初始化例子

    根据下面代码写出输出结果

    package com.patrick.bishi;
    
    public class TestVar {
        public static int k = 0;
        public static TestVar t1 = new TestVar("t1");
        public static TestVar t2 = new TestVar("t2");
        public static int i = print("i");
        public static int n = 99;
        public int j = print("j");
        {
            print("构造");
        }
        static {
            print("静态");
        }
    
        public TestVar(String str) {
            System.out.println((++k) + ":" + str + "    i=" + i + " n=" + n);
            ++i;
            ++n;
        }
    
        public static int print(String str) {
            System.out.println((++k) + ":" + str + "    i=" + i + " n=" + n);
            ++n;
            return ++i;
        }
    
        public static void main(String[] args) {
            TestVar t = new TestVar("init");
        }
    }
    

    分析:
    1,执行main函数时进行类的加载,此时静态数据被置为默认值k=0,t1=null,t2=null,i=0,n=0。
    2,执行静态初始化语句与静态初始化块

    • k=0,

    • 为了初始化t1开始执行非静态初始化语句与非静态初始化块

    • print("j")语句输出: 1:j i=0 n = 0;
      此时k = 1,n=1,i =1, j = 1;

    • print("构造")语句输出:2:构造 i = 1 n = 1
      此时k = 2,n = 2,i = 2,j = 1;

    • 执行构造器输出 3:t1 i = 2 n = 2
      此时k=3,n=3,i=3,j=1

    • 初始化t2开始执行非静态初始化语句与非静态初始化块

    • print("j")语句输出: 4:j i=3 n = 3;
      此时k = 4,n=4,i =4, j = 4;

    • print("构造")语句输出:5:构造 i = 4 n = 4
      此时k = 5,n = 5,i = 5,j = 4;

    • 执行构造器输出 6:t2 i = 5 n = 5
      此时k=6,n=6,i=6,j=4

    • 给i赋值print("i")输出 7:i i = 6 n =6
      此时k=7,n=7,i=7

    • 给n赋值此时n=99

    • 执行静态块print("静态")输出8:静态 i = 7 n = 99
      此时k=8 n =100 i = 8

    • 执行main方法中的初始化执行非静态初始化语句与非静态初始化块

    • print("j")语句输出: 9:j i=8 n = 100;
      此时k = 9,n=101,i =9, j = 9;

    • print("构造")语句输出:10:构造 i = 9 n = 101
      此时k = 10,n = 102,i = 10,j = 9;

    • 执行构造器输出 11:init i = 10 n = 102
      此时k=11,n=103,i=11,j=9
      ****整体输出:****

      1:j   i=0 n=0
      2:构造  i=1 n=1
      3:t1  i=2 n=2
      4:j   i=3 n=3
      5:构造  i=4 n=4
      6:t2  i=5 n=5
      7:i   i=6 n=6
      8:静态  i=7 n=99
      9:j   i=8 n=100
      10:构造 i=9 n=101
      11:init   i=10    n=102
      

    父类子类初始化顺序

    父类:

    public class Person {
    
        {
            System.out.println("父类非静态块");
        }
    
        static {
            System.out.println("父类静态块");
        }
    
        public Person() {
            System.out.println("父类构造器");
        }
    }
    

    子类:

    public class Male extends Person{
    
        {
            System.out.println("子类非静态块");
        }
    
        static {
            System.out.println("子类静态块");
        }
    
        public Male() {
            System.out.println("子类构造器");
        }
    
    }
    

    测试类:

    public class Main {
    
        public static void main(String [] args){
            Person person = new Male();
        }
    
    }
    

    输出结果:

    父类静态块
    子类静态块
    父类非静态块
    父类构造器
    子类非静态块
    子类构造器

    相关文章

      网友评论

          本文标题:类加载和初始化

          本文链接:https://www.haomeiwen.com/subject/cujelxtx.html