浅谈类初始化与对象实例化

类的初始化和对象的实例化

类的初始化是指类和接口加载到方法区后,因某些原因的触发,执行静态变量初始化语句和静态初始化块中语句的过程,初始化语句的执行顺序是由上往下的。

类的初始化语句由编译器 收集并放到一个特殊的方法中,称为类初始化方法,在Class文件中对应的是<clinit>,这种只方法只能由JVM调用。

触发类初始化方法的条件可以包括:
1.创建本类对象或子类对象。包括使用new操作符创建对象、通过反射(Class类的newInstance方法、Constructor类的newInstance方法)。
2.访问静态成员。包括对静态变量的赋值和读取,但不包括对常量的访问,调用静态方法。
3.Class.forName方法。
4.子类初始化。
5.Java应用程序的入口,即应用程序启动时执行的主类。

特殊情况:
通过子类调用父类的静态变量只会触发父类的初始化。
直接调用class对象而不用于访问类的结构是不会触发类的初始化,因为该对象是类在装载时在堆内存创建的。
接口不能定义static块,同时子接口的初始化不会触发父接口的初始化。
实现类在不调用接口成员的情况下不会初始化接口。

初始化类的过程必须保持同步,如果有多个线程初始化一个类,仅仅允许一个线程执行初始化,其他的线程都需要等待。

对象的实例化是指使用new创建对象和调用构造方法初始化对象的过程,发生在类初始化之后。构造方法在Class文件中被编译成<init>,每个构造器都会先执行实例变量的初始化语句,意思是实例变量声明的语句中的赋值。
public class C {
String name = "default";
public C(String name) {
this.name = name;
}

}

构造方法的字节码将如下:
public jptest.C(java.lang.String);
    descriptor: (Ljava/lang/String;)V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: invokespecial #3                  // Method java/lang/Object."<init>":()V
         4: aload_0
         5: ldc           #4                  // String default
         7: putfield      #5                  // Field name:Ljava/lang/String;
        10: aload_0
        11: ldc           #6                  // String init
        13: putfield      #5                  // Field name:Ljava/lang/String;
        16: aload_0
        17: aload_1
        18: putfield      #5                  // Field name:Ljava/lang/String;
        21: return


由此可以得知实例化一个对象,代码执行的顺序是:静态初始化块->父类构造方法->实例初始化块->实例变量初始化语句->构造方法的代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值