JavaSE_07_类加载与对象创建

文章详细阐述了Java中的类加载过程,包括静态和非静态内容的加载顺序,以及对象创建的步骤,强调了静态变量和非静态变量的区别。同时,解释了垃圾回收机制,如何判断对象不再需要并释放内存,以及finalize方法的作用。此外,文章还探讨了参数传递的不同方式,值传递和引用传递的原理和区别。

《类加载与对象创建》

目录

  • 过程分析(掌握)
  • JVM运行解析(掌握)
  • 垃圾回收机制(了解)
  • 参数传递(熟练)

一、过程分析

案例一

  • A类
package com.hpr.test;

public class A {
    static int x = 10;
    int y = 10;

    static {
        System.out.println("静态代码块执行:x=" + (++x));
    }

    {
        System.out.println("代码块执行:x=" + (++x) + ",y=" + (++y));
    }

    public A() {
        System.out.println("构造方法执行...");
    }

    public static void aa() {
        System.out.println("静态方法执行...");
    }

    public void cc() {
        System.out.println("非静态方法执行...");
    }
}
  • 测试类
package com.hpr.test;

public class Test {
    public static void main(String[] args) {
        A a1 = new A();
        System.out.println("a1:x=" + a1.x + ",y=" + a1.y);
        System.out.println("------------------------------");
        A a2 = new A();
        System.out.println("a2:x=" + a2.x + ",y=" + a2.y);
    }
}

执行结果

请添加图片描述

结果分析

  1. 静态代码块执行了一次;
  2. 代码块及构造方法每new一个对象执行一次;
  3. a1、a2对象共用静态变量x,单独使用非静态变量y;
  4. 方法调用即执行,不调用则不执行。

二、JVM运行解析

内存模型简笔图

请添加图片描述

类加载(静态变量、方法、代码块)

  1. JVM会先去方法区中找有没有类对应的.class存在,如果有,就直接使用;如果没有,就把对应类的.class加载到方法区;
  2. 将.class加载到方法区的时候,分为两部分,首先将非静态内容加载到方法区的非静态区域内;
  3. 再将静态内容加载到方法区的静态区域内,加载完成后,对所有的静态成员变量进行默认初始化;
  4. 所有静态成员变量默认初始化后,进行显示赋值,再执行静态代码块;(执行静态代码块和静态成员变量显示赋值无先后顺序,与代码顺序有关,谁在前面先执行谁)
  5. 如果有继承关系,加载子类的时候会先加载父类,再加载子类。

对象创建(非静态变量、方法、代码块)

  1. 对象创建首先会在堆内存中开辟一块空间,并分配一个地址;

  2. 将对象的所有非静态成员加载到开辟的空间下,并为所有非静态成员变量进行默认初始化;

  3. 调用构造函数进栈执行,在执行构造函数的时候,首先会执行构造函数中的隐式三步,再执行后续代码;

    隐式三步:

    1. 执行super语句,调用父类的构造函数;
    2. 对所有非静态成员变量进行显示赋值;
    3. 执行构造代码块;(非静态成员变量显示赋值和执行构造代码块无先后顺序,由代码顺序决定,谁在前先执行谁);
  4. 执行完隐式三步后,再执行构造函数中的代码,代码执行完后弹栈;

  5. 将堆内存中开辟的空间地址赋值给一个引用对象,对象创建完成。

常见概念

请添加图片描述

三、垃圾回收机制

内存释放

  • Java使用自动的处理重新分配内存的方法,即垃圾回收机制:当一个对象的引用不存在,则该对象被认为是不再需要的,它所占有的内存会被释放掉;
  • Java自动回收垃圾,不需要开发人员自己控制;
  • 当对象被释放时,将自动调用对象的finalize()方法;
  • 如果想强制垃圾回收,可以调用System.gc()方法(非必要不建议手动调用)。

案例二

  • TestGc类
package com.hpr.test;

public class TestGc {

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("回收对象:" + this);
    }

    public static void main(String[] args) {
        //引用t指向对象
        TestGc t = new TestGc();
        //引用t指向新对象
        t = new TestGc();
        System.out.println("当前对象:" + t);
        System.gc();
    }
}

执行结果

请添加图片描述

四、参数传递

案例三

package com.hpr.test;

public class Transmit {

    public static void valueTransmit(int xx) {
        xx++;
    }

    public static void quoteTransmit(int[] yy) {
        yy = new int[3];
    }

    public static void main(String[] args) {
        int x = 10;
        int[] y = new int[2];
        valueTransmit(x);
        quoteTransmit(y);
        System.out.println(x);          //10
        System.out.println(y.length);   //2
    }
}

值传递

请添加图片描述

引用传递

请添加图片描述

总结

重点

  1. 类加载与对象创建先后顺序及主要完成事项;
  2. 垃圾回收机制及finalize方法;
  3. 值传递与引用传递。

难点

  1. 类加载与对象创建主要完成事项;
  2. 值传递与引用传递。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值