【Java 对象初始化详细过程】

Java对象的初始化涉及类的加载、静态资源的处理以及构造函数的调用。类在遇到new、静态字段访问或静态方法调用时会被初始化,先父类后子类。静态代码块只执行一次,构造函数用于实例化对象时初始化成员变量。文章通过示例展示了类和对象初始化的详细步骤。
摘要由CSDN通过智能技术生成

Java 对象初始化详细过程

一、进行类初始化

java类是什么时候初始化的

  1. 遇到new、get static 和 put static 或 invoke static 这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。对应场景是:使用 new 实例化对象、读取或设置一个类的静态字段(被 final 修饰、已在编译期把结果放入常量池的静态字段除外)、以及调用一个类的静态方法。
  2. 对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
  3. 当初始化类的父类还没有进行过初始化,则需要先触发其父类的初始化。(而一个接口在初始化时,并不要求其父接口全部都完成了初始化)
  4. 虚拟机启动时,用户需要指定一个要执行的主类(包含 main() 方法的那个类),虚拟机会先初始化这个主类。

发生如上情况,Java类加载器就会去找类的路径,定位已经编译好的 *.class 文件。

二、获得类的资源

然后 jvm 就会载入 *.class,生成一个 class 对象。这个时候如果有静态的方法或者变量,静态初始化动作就会被执行。这个时候要注意了,静态初始化在程序运行过程中只会在 Class 对象首次加载的时候运行一次。这些资源都会放在 jvm 的方法区。
方法区又叫静态区,跟堆一样,被所有的线程共享。
方法区中包含的都是在整个程序中永远唯一的元素,包含所有的 class 和 static 变量。

Java中静态变量(类变量)、普通代码块、静态代码块和构造函数辨析

①静态代码块在类被加载的时候就运行了,而且只运行一次,拥有最高优先级(先父类再子类),静态代码块和静态变量的执行顺序只跟代码中出现的顺序有关。
②子类构造方法的第一行存在一个隐式的——super();

  1. 如果父类中没有定义空参数构造函数,那么子类的构造函数必须用super明确要调用父类的哪个构造函数并且super语句必须要定义在子类构造函数的第一行。因为父类的初始化动作要先完成。
  2. 当一个类中没有定义构造函数时,系统会给该类中加一个默认的空参数的构造函数,方便该类初始化。只是该空构造函数是隐藏不见的。
  3. 当在该类中自定义了构造函数,默认构造函数就没有了。如果仍要构造函数,需要在类中手动添加。
  4. 如果子类构造函数中如果使用this调用了本类构造函数时,那么super就没有了,因为super和this不能同时出现在同一构造函数中,但是可以保证的是,此this调用的构造函数肯定会访问父类的构造函数。

③代码块在编译后实际上是被放到了构造方法中,且是放在了构造方法的第一句
④如果类已经被加载,则静态代码块和静态变量就不用重复执行

class TestTwo{
  public TestTwo(){
    System.out.println("父类构造方法");
  }
  {
    System.out.println("父类代码块");
  }
  static {
    System.out.println("父类静态代码块");
  }
  public static void find(){
    System.out.println("静态方法");
  }
}

public class TestOne extends TestTwo{
  public TestOne(){
    System.out.println("子类构造方法");
  }
  {
    System.out.println("子类代码块");
  }
  static {
    System.out.println("子类静态代码块");
  }
  public static void main(String[] args) {
    new TestOne();
  }
}

输出结果:

父类静态代码块
子类静态代码块
父类代码块
父类构造方法
子类代码块
子类构造方法

三、初始化对象 Dog dog = new Dog()

  • 1.第一次创建 Dog 对象先执行上面的一二步
  • 2.在堆上为 Dog 对象分配足够的存储空间,所有属性和方法都被设置成默认值(数字为 0,字符为 null,布尔为 false,而所有引用被设置成 null;注意方法内部定义的基本类型是不会默认赋值)
  • 3.执行构造函数检查是否有父类,如果有父类会先调用父类的构造函数。
  • 4.执行构造函数。
  • 5.把这个对象指向这个空间

总结:
如果Dog类没有进行过类初始化,首先进行类初始化,Java类加载器去找Dog类的路径,定位已经编译好的 Dog.class 文件,然后 jvm 就会载入 Dog.class,生成一个Dog的class对象。在此过程中,Dog类有静态的方法或者变量的话,进行静态初始化(静态初始化在程序运行过程中只会在 Class 对象首次加载的时候运行一次)。最后,分配内存空间(实例化对象),执行构造方法(初始化对象),把对象的地址赋值给引用dog

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值