[关闭]
@XQF 2017-02-14T00:11:58.000000Z 字数 1904 阅读 1121

初始化顺序--------头疼

java


1.概述

表示初始化顺序,。,。很是伤脑筋,,今天我就来决一生死,。,。表示这可能是我看了三遍编程思想和两遍java面试的总结。。。。再忘就再撸。。。。

2.创建对象时非静态变量的初始化

一个好端端的类,里面没有任何与静态有关的逻辑,那么初始化方式就是,先初始化成员变量,不管成员变量在哪个位置。然后再来执行其他方法

Java编程思想:在类的内部,变量定义的顺序决定了初始化的顺序,即使变量定义分布在方法定义之间。他们会在任何方法(包括构造器)被调用之前得到初始化

image_1b8s0tr8cubonmn1auc1uhc1v4o9.png-12.1kB

产生A类的对象,先初始化 a,再初始化b,再调用A的构造方法

  1. class A {
  2. private int a = 3;
  3. {
  4. System.out.println("a:" + a);
  5. }
  6. public A() {
  7. System.out.println("A constructor");
  8. }
  9. private int b = 4;
  10. {
  11. System.out.println("b:" + b);
  12. }
  13. }
  14. public class Ac {
  15. public static void main(String[] args) {
  16. new A();
  17. }
  18. }

代码块也看做是,。实例变量

  1. a:3
  2. b:4
  3. A constructor

3.创建对象时静态变量的初始化

好端端一个类的静态变量总是第一个被初始化与位置无关。
image_1b8s185ad14t21is01o0avlmsumm.png-19.1kB

这个段代码输出为

  1. 222
  2. 111

所以含有静态变量的类在创建对象的时候,是先初始化静态变量,再初始化非静态变量,再调用构造方法。

关于静态变量:静态变量只会被初始化一次,就是说初始化的代码只会被执行一次。什么时候被执行尼?两种情况,第一种是第一次创建该类的对象的时候,第二种情况是在该类一直没有创建对象而去访问该类的静态变量的时候。这两种情况下都会去加载类。

  1. class A {
  2. {
  3. System.out.println("111");
  4. }
  5. static {
  6. System.out.println("222");
  7. }
  8. }
  9. public class Ac {
  10. public static void main(String[] args) {
  11. new A();
  12. new A();
  13. }
  14. }

这段代码输出为:

  1. 222
  2. 111
  3. 111

4.对于有继承关系的类对象的初始化

  1. class A {
  2. static {
  3. System.out.println("static 1");
  4. }
  5. {
  6. System.out.println("11");
  7. }
  8. public A() {
  9. System.out.println("A constructor");
  10. }
  11. }
  12. class B extends A {
  13. static {
  14. System.out.println("static 2");
  15. }
  16. {
  17. System.out.println("22");
  18. }
  19. public B() {
  20. System.out.println("B construtor");
  21. }
  22. }
  23. public class Ac {
  24. public static void main(String[] args) {
  25. new B();
  26. System.out.println();
  27. new B();
  28. }
  29. }

这段代码输出为:

  1. static 1
  2. static 2
  3. 11
  4. A constructor
  5. 22
  6. B construtor
  7. 11
  8. A constructor
  9. 22
  10. B construtor

有口诀哟:

  1. 父类静态变量,子类静态变量
  2. 父类非静态变量,父类构造方法
  3. 子类非静态变量,子类构造方法

老实说其实背住也不失为一个好办法。

真是的解释应该是这样的

B是A类的子类,而静态变量是这一类的公共变量。所以我认为B类此时同时拥有两个静态块,加载B类的时候,先解决掉两个静态块。再来看为什么没有继承实例变量?为什么父类和子类的实例变量是分开的? 翻开Java编程思想p129页倒数第五行。。。构建过程是“向外”扩散的,所以基类在导出类构造器可以访问之前就已经完成了初始化。,就是说我们的子类对象是包含父类对象的,子类对象是建立在父类对象的基础上的,因此先进行父类对象的初始化,自然是,。老规矩。然而静态变量已经被初始化过了。

但是又有新问题,为什么11在初始化子类对象的时候没有再次被初始化?

5.关于我之前的混淆

  1. public class A{
  2. static{
  3. System.out.println("hehhe")
  4. }
  5. public static void main(String[]args){
  6. }
  7. }

为什么这样还是会有输出?明明两个条件都不满足呀?

实际上没毛病,在于这个类是public 的,public 的类会被默认加载,静态初始化在加载的时候就会被优先执行。然后通过静态方法main打开入口。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注