我们可以用构造器来进行初始化,保证对象内的变量在new 的之前已经被初始化完成了。这样我们new 玩之后就可以直接调用了。
public Class Counter{
int i;
Counter(){
i=7; }
}
初始化顺序:在类的内部,变量定义的顺序决定了初始化的顺序,他们会在任何方法(包括扩构造器)被调用之前得到初始化。
class Window{
Window(int marker){
System.out.println("Window的无参构造方法"+marker);
}
}
class House{
Window window1=new Window(1);
House(){
window3 =new Window(33);
System.out.println("House构造方法");
}
Window window2=new Window(2);
Window window3=new Window(3);
}
public class Test03 {
public static void main(String[] args) {
House house = new House();
}
}
Output:
Window的无参构造方法1
Window的无参构造方法2
Window的无参构造方法3
Window的无参构造方法33
House构造方法
通过上述代码我们发现,我们把Window对象分散到代码各处,他们都会按定义的顺序去执行初始化,然后是构造器的初始化化。这也就验证了我们所说的变量的初始化会在任何方法(包括构造器)调用之前执行。注意,如果我们采用类的形式直接去调用静态方法,此时,普通的成员变量将不会被初始化,因为没有为对象在堆中开辟空间。
静态数据的初始化:无论我们创建多少个对象,都会在这个类加载到jvm的时候先去初始化静态对象(静态变量和静态代码块),而且仅仅执行一次(静态方法可以在静态方法中调用)。
class Bowl{
Bowl(int marker){
System.out.println(marker);
}
void f(int i){
System.out.println("f()"+i);
}
}
class Table{
static Bowl b1=new Bowl(1);//静态变量
Bowl b2=new Bowl(2);
Table() {
Bowl b3=new Bowl(3);
System.out.println("table的无参构造方法");
}
static {//静态代码块
init();//调用静态方法
}
void test(int i){
System.out.println("test()"+i);
}
static void init(){//静态方法
System.out.println("init()被静态代码块调用");
}
}
public class StaticTest {
public static void main(String[] args) throws ClassNotFoundException {
Table table = new Table();
}
}
Output:
1
init()被静态代码块调用
2
3
table的无参构造方法
通过上述代码,我们可以看出,优先被初始化的是静态变量和静态代码块,而且无论是静态变量还是静态代码块,在初始化时并无优先级。其次是普通变量(基本变量和引用变量)和普通代码块,且无论普通代码块和普通变量在初始化时也无优先级。最后是构造器的初始化。<br /> 最后我们可以总结出一个类被加载的过程:
当我们首次创建类的时候,或者类的静态方法(构造方法也是静态方法)和静态域被首次访问时,定位类class文件
当载入类文件到jvm时,有关静态域和静态方法的所有初始化动作都会被执行。且只执行一次。
在堆上为对象分配足够的存储空间(通过new 来创建类的时候),同时自动的将对象中的基本数据类型和引用数据类设置默认类型(引用类型为null).
执行说的普通域(普通变量和普通代码块)的初始化化动作(普通变量包括基本变量和引用变量)。
执行对象中的构造器。