我们可以用构造器来进行初始化,保证对象内的变量在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的无参构造方法1Window的无参构造方法2Window的无参构造方法3Window的无参构造方法33House构造方法
通过上述代码我们发现,我们把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:1init()被静态代码块调用23table的无参构造方法
通过上述代码,我们可以看出,优先被初始化的是静态变量和静态代码块,而且无论是静态变量还是静态代码块,在初始化时并无优先级。其次是普通变量(基本变量和引用变量)和普通代码块,且无论普通代码块和普通变量在初始化时也无优先级。最后是构造器的初始化。<br /> 最后我们可以总结出一个类被加载的过程:
当我们首次创建类的时候,或者类的静态方法(构造方法也是静态方法)和静态域被首次访问时,定位类class文件当载入类文件到jvm时,有关静态域和静态方法的所有初始化动作都会被执行。且只执行一次。在堆上为对象分配足够的存储空间(通过new 来创建类的时候),同时自动的将对象中的基本数据类型和引用数据类设置默认类型(引用类型为null).执行说的普通域(普通变量和普通代码块)的初始化化动作(普通变量包括基本变量和引用变量)。执行对象中的构造器。
