类变量和实例变量及其初始化

0.基本概念java

  类变量是指java类中的static数据成员,实例变量则是指java类中的非static数据成员。因为类变量不须要建立一个对象便可访问,而实例变量则必须与一个具体的对象对应,所以类变量和实例变量的初始化时机是不一样的。本文主要关注如下3个问题:函数

  (1)何时初始化类变量?何时初始化实例变量?spa

  (2)何时会同时初始化类变量和实例变量?code

  (3)在(1)、(2)情形下各个类变量和实例变量的初始化顺序?对象

1.类变量初始化blog

  1.1 类变量初始化方式继承

  static变量初始化的方式有两种:定义时初始化和static代码块中初始化。以下代码所示:ci

1 class A(){  
2    public static int i = 1;//static变量初始化方式一:在定义时初始化
3    static{//static变量初始化方式二:在static代码块初始化static变量
4      System.out.println("statci 代码块");
5      }    
6  }

  1.2 类变量初始化时机编译

  根据有无被final关键字修饰,类变量的初始化时机不一样。被final关键字修饰的类变量在编译时就已经被初始化被放置在常量池中了,而没有被final修饰的类变量则在该类首次使用时被初始化。特别须要注意的是,类变量只在该类首次使用时被初始化,这意味着类变量只会被初始化一次。class

  在下列情形下,若是一个java类中没有被final修饰的类变量还没有初始化,那么这些没有被final修饰的类变量将会被初始化:

  (1)访问该类中没有被final修饰的类变量时;

  (2)设置该类中没有被final修饰的类变量时;

  (3)调用该类的static方法。

  1.2 类变量初始化顺序

  类变量初始化会遵循如下三个原则:

  (1)在上述3个情形下,首先会初始化该类中全部没有被final修饰的类变量,而后再执行对应的操做;

  (2)按照代码中的顺序依次执行static变量定义语句和static代码块;

  (3)若是该类有父类且父类的类变量没有初始化,则先初始化父类的类变量;

  (4)若是父类还有父类的话,根据(3)的规则,以此类推。

  根据上述原则,能够肯定类变量初始化顺序以下:

//没有继承的情形
static变量初始化和static代码块

//有继承的情形
1.父类的static变量初始化和static代码块
2.子类的static变量初始化和static代码块

/*备注:
类变量初始化只有一次,若是某个java类的类变量已经被初始化过了,则上述过程当中的类变量初始化将再也不执行
*/

 

2.实例变量初始化

  2.1 实例变量初始化方式

  与类变量初始化方式相似,实例变量初始化方式也有两种:定义时初始化和代码块初始化。示例以下:

1  class A(){  
2    public static int i = 1;//实例变量初始化方式一:在定义时初始化
3 
4    {//实例变量初始化方式二:在代码块初始化实例变量
5      System.out.println("代码块");
6      }    
7  }

  2.2 实例变量初始化时机和顺序

  实例变量初始化是在建立该类的对象时进行的,初始化时遵循的原则是:

  (1)按照代码中的顺序依次执行实例变量定义语句和实例变量代码块;

  (2)若是建立该类的对象时该类的类变量还没有初始化,则先初始化类变量,再初始化实例变量;

  (3)若是该类有父类的话,则先建立一个父类对象;而且,若是父类类变量没被初始化时,先初始化父类的类变量,再初始化父类的实例变量,再调用父类的默认构造器;

  (4)若是父类还有父类的话,根据(3)的规则以此类推,一直到根基类。

  根据上述原则易知,实例变量初始化以前可能会先初始化类变量(这是特别须要留意的一点)。初始化顺序以下:

//没有继承的情形(且该类的类变量未被初始化)
1.static变量初始化和static代码块
2.实例变量初始化和实例变量初始化代码块
3.构造函数

//有继承的情形(且该类和父类的类变量未被初始化)
1.父类的static变量初始化和static代码块
2.子类的static变量初始化和static代码块
3.父类的实例变量初始化和实例变量初始化代码块
4.父类的构造函数
5.子类的实例变量初始化和实例变量初始化代码块
6.子类构造函数

/*备注:
类变量初始化只有一次,若是某个java类的类变量已经被初始化过了,则上述过程当中的类变量初始化将再也不执行
*/

3.小结

  你们看完若是还不太明白类变量和实例变量的初始化时机和顺序,能够亲自去写一个demo试试,实践才能出真知嘛!

  在这里,只强调两点:

  (1)类变量只会初始化一次;

  (2)类变量和实例变量的初始化时机是不一样的,类变量初始化在首次使用该类的时候进行,实例变量的初始化在建立该类的每一个对象时都会进行。

相关文章
相关标签/搜索