对象的创建过程
static数据:
无论创建多少个对象,静态数据都只占用一份存储空间。static关键字不能应用与局部变量,因此它只能作用于域。如果一个域是静态的基本类型域,且没有对它进行初始化,那么它就会获得基本类型的标准值;如果它是一个对象引用,那么它的默认初始化值是null。
例子:
class Bowl{ Bowl(int marker){ System.out.println("Bowl (" + marker + " )"); } void f1(int marker){ System.out.println("f1( " + marker + " )"); } } class Table{ static Bowl bowl1 = new Bowl(1); Table(){ System.out.println("Table()"); bowl2.f1(1); } void f2(int marker){ System.out.println("f2( " + marker + " )"); } static Bowl bowl2 = new Bowl(2); } class Cupboard{ Bowl bowl3 = new Bowl(3); static Bowl bowl4 = new Bowl(4); Cupboard(){ System.out.println("Cupboard()"); bowl4.f1(2); } void f3(int marker){ System.out.println("f3( " + marker + " )"); } static Bowl bowl5 = new Bowl(5); } public class StaticInitialization { public static void main(String[] args) { System.out.println("Createing new Cupboard() in main"); new Cupboard(); System.out.println("Creating new Cupboard() in main"); new Cupboard(); table.f2(1); cupboard.f3(1); } static Table table = new Table(); static Cupboard cupboard = new Cupboard(); } /*output: Bowl (1 ) Bowl (2 ) Table() f1( 1 ) Bowl (4 ) Bowl (5 ) Bowl (3 ) Cupboard() f1( 2 ) Createing new Cupboard() in main Bowl (3 ) Cupboard() f1( 2 ) Creating new Cupboard() in main Bowl (3 ) Cupboard() f1( 2 ) f2( 1 ) f3( 1 ) */
分析:
主类是StaticInitialization,要执行main()(静态方法),必须加载StaticInitialization类,然后它的静态域table和cupboard被初始化,这使得它们对应的类也被加载,由于这些类包含了静态的Bowl对象,因此Bowl也被加载。
静态域的初始化在非静态成员变量初始化之前。
小结对象的创建过程,假设有一个名为Dog的类:
1.即使没有显式地使用static,构造器实际上也是静态方法。因此,当首次创建类型为Dog的对象时,或者Dog类的静态方法、静态域首次被访问时,java解释器必须查找类路径,以定位Dog.class文件。
2.然后加载Dog.class,有关静态初始化的所有动作都会执行。因此,静态初始化只在Class对象首次加载的时候进行一次。
3.当new Dog()创建对象时,首先将在堆上为Dog对象分配足够的存储空间。
4.这块存储空间会被清零,这就自动将Dog对象中的所有基本类型数据设置成默认值(对数字来说就是0,对布尔类和字符型也是如此),而引用则被设置成null。
5.执行所有出现于字段定义处(成员变量)的初始化动作。
6.执行构造器。