@XQF
2017-02-13T16:11:58.000000Z
字数 1904
阅读 1265
java
表示初始化顺序,。,。很是伤脑筋,,今天我就来决一生死,。,。表示这可能是我看了三遍编程思想和两遍java面试的总结。。。。再忘就再撸。。。。
一个好端端的类,里面没有任何与静态有关的逻辑,那么初始化方式就是,先初始化成员变量,不管成员变量在哪个位置。然后再来执行其他方法
Java编程思想:在类的内部,变量定义的顺序决定了初始化的顺序,即使变量定义分布在方法定义之间。他们会在任何方法(包括构造器)被调用之前得到初始化

产生A类的对象,先初始化 a,再初始化b,再调用A的构造方法
class A {private int a = 3;{System.out.println("a:" + a);}public A() {System.out.println("A constructor");}private int b = 4;{System.out.println("b:" + b);}}public class Ac {public static void main(String[] args) {new A();}}
代码块也看做是,。实例变量
a:3b:4A constructor
好端端一个类的静态变量总是第一个被初始化与位置无关。

这个段代码输出为
222111
所以含有静态变量的类在创建对象的时候,是先初始化静态变量,再初始化非静态变量,再调用构造方法。
关于静态变量:静态变量只会被初始化一次,就是说初始化的代码只会被执行一次。什么时候被执行尼?两种情况,第一种是第一次创建该类的对象的时候,第二种情况是在该类一直没有创建对象而去访问该类的静态变量的时候。这两种情况下都会去加载类。
class A {{System.out.println("111");}static {System.out.println("222");}}public class Ac {public static void main(String[] args) {new A();new A();}}
这段代码输出为:
222111111
class A {static {System.out.println("static 1");}{System.out.println("11");}public A() {System.out.println("A constructor");}}class B extends A {static {System.out.println("static 2");}{System.out.println("22");}public B() {System.out.println("B construtor");}}public class Ac {public static void main(String[] args) {new B();System.out.println();new B();}}
这段代码输出为:
static 1static 211A constructor22B construtor11A constructor22B construtor
有口诀哟:
父类静态变量,子类静态变量父类非静态变量,父类构造方法子类非静态变量,子类构造方法
老实说其实背住也不失为一个好办法。
真是的解释应该是这样的
B是A类的子类,而静态变量是这一类的公共变量。所以我认为B类此时同时拥有两个静态块,加载B类的时候,先解决掉两个静态块。再来看为什么没有继承实例变量?为什么父类和子类的实例变量是分开的? 翻开Java编程思想p129页倒数第五行。。。构建过程是“向外”扩散的,所以基类在导出类构造器可以访问之前就已经完成了初始化。,就是说我们的子类对象是包含父类对象的,子类对象是建立在父类对象的基础上的,因此先进行父类对象的初始化,自然是,。老规矩。然而静态变量已经被初始化过了。
但是又有新问题,为什么11在初始化子类对象的时候没有再次被初始化?
public class A{static{System.out.println("hehhe")}public static void main(String[]args){}}
为什么这样还是会有输出?明明两个条件都不满足呀?
实际上没毛病,在于这个类是public 的,public 的类会被默认加载,静态初始化在加载的时候就会被优先执行。然后通过静态方法main打开入口。
