1.类的成员变量会自动进行初始化:
基本类型:0
引用类型:null
2.局部变量必须进行初始化!否则报错!
3.对于类的成员变量初始化操作,比如
int a=9;
实际上进行的操作是:
int a=0;
a=9;
所以在赋值前先进行了初始化操作.
这样可以确保任何成员变量都先执行了初始化工作
4.在类的内部,即使变量定义散布于方法定义间,他们仍然会在任何方法(包括构造器)被调用之前得到初始化,变量定义的先后顺序决定了初始化的顺序.eg:
class Window{
public int x;
Window(int marker){
System.out.println("Window:"+marker);
}
}
class House{
<span style="white-space:pre"> </span>Window w1=new Window(1);
House(){
System.out.println("House()");
}
Window w2=new Window(2);
void f(){
System.out.println("f()");
Window w5=new Window(5);
}
Window w3=new Window(3);
}
public class Money{
public static void main(String[] args){
House h=new House();
h.f();
}
}
Output:
Window:1
Window:2
Window:3
House()
f()
Window:5
在主函数中,House h=new House();
因此需要初始化House,当程序访问House这一class的时候,则会先将成员变量中的变量按照定义顺率进行初始化,然后再执行构造函数
所以初始化顺序为
1.Window w1=new Window(1)
2.Window w2=new Window(2)
3.Window w3=new Window(3)
接下来是才可以访问构造函数
4.System.out.println("House");
然后访问h.f()方法,方法中的变量不会自动执行初始化
5.System.out.println("f()");
6.Window w5=new Window(5);
由于在初始化HOUSE这一个类的时候就会将其成员变量进行初始化,所以以下代码可以正常执行
class House{
Window w1=new Window(1);
House(){
System.out.println("House()");
System.out.println(w2.x); //pay attention to the location of w2
}
Window w2=new Window(2);
void f(){
System.out.println("f()");
Window w5=new Window(5);
}
Window w3=new Window(3);
}
虽然w2.x所在的位置在Window w2=new Window(2)之后,但是由于提前进行了初始化操作,所以是不会报错的.
那么如果我们只是定义了对象而没有new一个引用呢?
比如:Window w1;
那么还会初始化w1吗?
答案是会初始化
但是初始化的对象是null。这种初始化是编译器进行的操作,并不会调用构造函数!
最后还有一个关于staitc和非static的区别
eg:
class Window {
House h = new House();
Window(int marker) {
System.out.println("Window:" + marker);
}
}
class House {
Window w2 = new Window(2);
House() {
System.out.println("House()");
}
}
public class Money {
public static void main(String[] args) {
House h = new House();
}
}
由于House类中有Window类,所以当我们访问House类的时候会对Window类中的成员变量进行初始化
而又因为Window类中有House类的成员变量,所以又会初始化House类中的成员变量,所以造成了循环,编译器报错
如何解决这个问题呢?
1.断开二者的循环
2.将其中一个成员变量设置为static类型,这样就只进行初始化一次了!