JVM_1

  • 在Java代码中,类型的加载、连接、初始化在程序运行期间完成。
  • 提供了更大的灵活性,更多可能性。
退出JVM:
  • 执行System.exit()方法
  • 程序正常执行结束
  • 程序执行遇到Exception或者Error终止执行
  • 操作系统出现错误导致JVM进程终止
类加载、连接、初始化过程
  1. 加载:类的加载是指将类的.class文件中的二进制数据读入到内存中,并放在方法区内,然后在内存中创建一个java.lang.Class对象用来封装类在方法区中的数据结构(jvm规范没有规定class对象位于哪,但HotSpot虚拟机将其放在方法区中)
  2. 连接:
    1. 验证阶段:确保被加载的类的正确性,保证加载的字节码文件没有被篡改,符合jvm对字节码的格式要求
    2. 准备阶段:为类的==静态变量==分配内存,并将其初始化为默认值
    3. 解析阶段
  3. 初始化:为类的的静态变量赋予正确的初始值
class Test {
    public static int a = 1;
}
/**
 *对于静态变量a的值的初始化过程为
 * 1:连接的准备阶段: a = 0;
 * 2:在初始化阶段:a = 1;
 */
  1. 类的使用:创建类的对象等操作
  2. 卸载:在内存销毁,卸载后不能创建对象(很少接触)
类的使用方式 主动使用与被动使用
  • 主动使用 类只有在被首次主动使用时才会初始化
    1. 创建类的实例
    2. 访问某个类的或接口的静态变量,或对改静态变量赋值
    3. 调用类的静态方法
    4. 反射(比如Class.forName("Test"))
    5. 初始化一个类的子类
    6. java虚拟机启动时被标记为启动类
    7. jdk7对动态语言的支持:java.lang.invoke.MethodHandle实例解析结果REF_getStatic、REF_putStatic、REF_invokeStatic句柄对应的类没有被初始化,则初始化
  • 被动使用,以上情况以外的均为被动使用,被动使用不会导致类被初始化
public class Test1 {
    public static void main(String[] args) {
        System.out.println(Child.str);
    }
}

class Parent {
    public static String str = "hello world";

    static {
        System.out.println("parent static invoke");
    }
}

class Child extends Parent {
    static {
        System.out.println("child static invoke");
    }
}

输出结果:
parent static invoke
hello world

感悟:
第一次看到这个程序的时候,我以为会输出
parent static invoke
child static invoke
hello world

***误区***:
对于静态属性来说,只有直接定义了该属性的类才会被初始化,即上程序对于str的访问只会去初始化Parent这个类,不会初始化Child子类。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容