Static方法,与子类父类的执行顺序

今天遇到了一些问题, 刚开始很混乱。后来一个一个的查,一个一个问题的去解决,现在豁然开朗了。记录一下:

起因是因为看一个帖子看到这样一段代码:


-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

public class Test {
     Person person = new Person( "Test" );
     static {
         System.out.println( "test static" );
     }
     
     public Test() {
         System.out.println( "test constructor" );
     }
     
     public static void main(String[] args) {
         new MyClass();
     }
}
 
class Person{
     static {
         System.out.println( "person static" );
     }
     public Person(String str) {
         System.out.println( "person " +str);
     }
}
 
 
class MyClass extends Test {
     Person person = new Person( "MyClass" );
     static {
         System.out.println( "myclass static" );
     }
     
     public MyClass() {
         System.out.println( "myclass constructor" );
     }
}

输出结果为:

test static
myclass static
person static
person Test
test constructor
person MyClass

myclass constructor


------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

一开始看到结果的时候想不通为什么是这样子的,跟我想的一点都不一样啊。 费了半天劲儿都看不出来这样的结果,觉得自己真的是太欠缺了,懂的太少了。后来静下心研究了一下,慢慢来,不要急躁,会学到很多东西。

首先,我将自己的疑问列出来:

1.静态方法的初始化

2. new 一个子类的时候,父类构造是如何被调用的;

3.main方法与成员变量及方法的执行顺序。


首先解决第一个问题,静态方法的初始化,静态方法是被static修饰的方法,一般静态方法会在类被加载的时候就进行初始化, 而且只初始化这一次。所以你看到的输出结果,static是在最前面的。

第二个问题,new一个子类的时候,有static变量跟方法会先初始化。然后会先去加载父类的成员变量,方法, 与构造函数,如果父类中存在static方法或者变量,则先初始化static变量与方法,但是记住,static方法与变量只能被初始化一次,如果前面初始化过就不会再初始化第二次了。接下来就是初始化成员变量,然后调用构造函数。

第三个问题,程序开始运行时,系统会找到main方法所在的class,然后把main方法加载到内存中,从mian 函数的第一条开始执行,知道main的最后一条语句结束。但是class中存在static变量或者方法,也会进行初始化。所以这里输出的第一条是test static。  至于main所在的类中其他的成员变量喝构造函数只会在new 这个类时进行初始化,方法要在调用的时候才加载。


好了,现在我们来捋一捋。接下来在new MyClass()的时候,先执行static方法,输出myclass static。因为MyClass继承自Test,所以会先出初始化Test,而Test类在系统执行main之前就被加载了,也就是说Test类中的static方法已经被初始化过了,在这里就不会再进行二次初始化。接下来就初始化成员变量person,person是通过new Person()被初始化的,new Person() 会按照同样的顺序对Person类中的静态方法,成员变量,构造函数进行初始化。 所以,首先输出静态方法中的person static,然后调用构造函数,输出person Test。 person初始化完成之后就执行Test类的构造函数,输出test constructor。 然后在返回子类进行初始化,初始化成员变量 person (static已经被初始化过,不会再次进行初始化),同样到person类中执行构造函数(static已经被初始化过,不会再次进行初始化),输出person MyClass,然后执行myClass的构造函数,输出myclass constructor



现在,清晰很多了吧。  所以  静态方法与main的执行关系是,静态方法与属性> main 方法,  子类初始化会先加载父类的变量跟方法,注意这里只是加载并不会创建一个父类对象。



  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值