一个对象的初始化过程

对象初始化的时候究竟是怎么个什么过程,static修饰的变量和方法都怎么回事?使用的时候有什么区别?

 

今天本小白带着疑问也进行了一番测试,。

 

先上代码(自己测试的时候直接copy就行):


class SuperClass {
    static Print staticMember = new Print("父类static成员变量 1");

    {
        System.out.println("父类初始化块  1");
    }

    static {
        System.out.println("父类static代码块  1");
    }

    Print commonMember = new Print("父类成员变量  1");
    static Print staticMember1 = new Print("父类static成员变量  2");

    static {
        System.out.println("父类static代码块  2");
    }

    Print commonMember2 = new Print("父类成员变量  2");

    {
        System.out.println("父类初始化块  2");
    }

    SuperClass() {
        System.out.println("父类构造函数()");
    }

    static void method() {
        System.out.println("我是父类的一个静态方法  ");
    }

    void print() {
        System.out.println("我是父类的一个方法");
    }
}

class ChildClass extends SuperClass {
    static Print childStaticMember = new Print("子类static成员变量");
    Print childCommonMember = new Print("子类成员变量");

    static {
        System.out.println("子类static代码块");
    }

    {
        System.out.println("子类初始化块");
    }

    ChildClass() {
        System.out.println("子类构造函数()");
    }

    static void method2() {
        System.out.println("我是子类的一个静态方法");
    }

    void print2() {
        System.out.println("我是子类的一个方法");
    }
}

class Print {
    Print(String process) {
        System.out.println(process);
    }
}

public class Test {
    public static void main(String[] args) {
        SuperClass superClass = new SuperClass();
        System.out.println("。。一个卑微分隔符。。。。");

        new ChildClass();
        System.out.println("。。又一个卑微分隔符。。。。");

        ChildClass childClass = new ChildClass();
        System.out.println("。。双一个卑微分隔符。。。。");

        superClass.print();
        SuperClass.method();
        superClass.method();
        System.out.println("。。最后一个卑微分隔符。。。。");

        childClass.print2();
        ChildClass.method2();
        childClass.method2();

    }
}

这是跑的结果:

父类static成员变量 1
父类static代码块  1
父类static成员变量  2
父类static代码块  2
父类初始化块  1
父类成员变量  1
父类成员变量  2
父类初始化块  2
父类构造函数()
。。一个卑微分隔符。。。。
子类static成员变量
子类static代码块
父类初始化块  1
父类成员变量  1
父类成员变量  2
父类初始化块  2
父类构造函数()
子类成员变量
子类初始化块
子类构造函数()
。。又一个卑微分隔符。。。。
父类初始化块  1
父类成员变量  1
父类成员变量  2
父类初始化块  2
父类构造函数()
子类成员变量
子类初始化块
子类构造函数()
。。双一个卑微分隔符。。。。
我是父类的一个方法
我是父类的一个静态方法  
我是父类的一个静态方法  
。。最后一个卑微分隔符。。。。
我是子类的一个方法
我是子类的一个静态方法
我是子类的一个静态方法

分析(自己可以打断点,然后一步步调试):

一、先看第一段:

new了一个父对象。

看下结果

  1. static修饰的成员变量和static修饰的代码块在初始化的时候优先级一样,执行的顺序完全看在代码中的先后顺序。
  2. 成员变量和初始化块在初始化的时候优先级一样,执行的顺序完全看在代码中的先后顺序。
  3. 构造函数最后执行。经常我们使用带参数的构造函数的时候,使用的变量就是我们的成员变量。

二、再看第二段:

刚刚已经new了一个父对象,现在再new一个子对象。

  1. 先执行了子类的static修饰的对象。
  2. 又把父类的初始化块、成员变量和构造函数执行了一遍。
  3. 执行了子类的成员变量、初始化块和构造函数执行了一遍。

三、看完了一和二,那么问题来了,如果我们把这两个顺序颠倒一下,会是什么情况。

代码变成这样,把前两个new的对象交换一下,变成这样:

跑的结果是这样

跟第一次的不一样了啊。

原因就是,对于有父类的对象的第一次创建过程是这样的:

  1. 父类静态成员变量和静态代码块。
  2. 子类静态成员变量和静态代码块。
  3. 父类初始化代码块和父类成员变量。
  4. 父类构造函数。
  5. 子类初始化代码块和子类成员变量。
  6. 子类构造函数。

我们知道static修饰的变量,只会在类第一次使用的时候被加载,那么第二次再创建父类(子类也可以)的时候,就不会再加载一遍了,所以上面的结果只有父类初始化块、父类成员变量和父类构造函数被用了。以后的第三、第四、~第N次都会这样。

四、再看接下来的部分。

结果是:

也就是说被static修饰的静态方法,是可以在对象内使用,也可以用类名.使用。

我的理解是static一旦被加载,那么就属于这个类和全体对象共有,也就是一个公共的东西。谁都可以用。

再看这个:

我用对象加了个点不显示method2(),但是一旦我输入了一部分就会给出来提示。

我想这可能是用来提醒我,对于static修饰的方法,建议使用类名而不要使用对象。

 

以上纯属个人理解,如有错误,请指明,非常感谢。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值