• Java类加载机制


    类的生命周期

    加载-验证-准备-解析-初始化-使用-卸载

    1 加载阶段

    把.class二进制数据读到内存中,并放到方法区,然后在堆中创建一个Java.lang.Class对象,这个对象就是用来封装类在方法区的数据结构的。
    所以,类加载机制的最终产物是:在堆中创建了java.lang.Class对象,这个对象提供了访问方法区内部数据结构的接口。

    2 验证阶段

    这个主要就是验证包的签名等

    3 准备阶段

    为静态变量分配内存,并设置初始值。
    内存分配动作发生在方法区的,在准备阶段,给类成员进行初始化。

    类型 初始化值
    String null
    Object null
    int 0

    4 解析阶段

    将符号引用转成直接引用
    说白了,就是,将变量换成内存中真实地址,都将高级的东西解析为机器识别的底层东西。

    5 初始化(最重要的)

    5-1 初始化2种方式

    初始化有生命类变量和静态代码块2种方式,它们的优先级相同,谁在前面谁先来。

    static int age = 20;
        static{
            System.out.println("hello,world");
            System.out.println(age);
        }
    

    6 初始化的触发几种情况

    6-1 创建类对象的时候

    • new
    • 反射
    • 对象的反序列化

    6-2 调用类的某个静态方法

    package com.siyu;
    
    public class Claloader {
        static int age = 20;
        static{
            System.out.println("hello,world");
            System.out.println(age);
        }
    
        public static void getName(){
            String name = Thread.currentThread().getName();
            System.out.println(name);
        }
    }
    
    package com.siyu;
    
    public class Test {
        public static void main(String[] args) {
    //        调用类的某个静态方法,触发类的初始化
            Claloader.getName();
    //        hello,world
    //        20
    //        main
        }
    }
    

    6-3 调用某个类或接口中的类变量

    package com.siyu;
    
    public class Claloader {
        static int age = 20;
        static{
            System.out.println("hello,world");
            System.out.println(age);
        }
    
        public static void getName(){
            String name = Thread.currentThread().getName();
            System.out.println(name);
        }
    }
    
    
    package com.siyu;
    
    public class Test {
        public static void main(String[] args) {
    //        调用类的某个静态方法,触发类的初始化
            int age = Claloader.age;
    //        hello,world
    //        20
        }
    }
    
    
    

    6-4 调用子类静态变量,引父类初始化

    package com.siyu;
    
    public class Claloader {
        static int age = 20;
        static{
            System.out.println("hello,world");
            System.out.println(age);
        }
    
        public static void getName(){
            String name = Thread.currentThread().getName();
            System.out.println(name);
        }
    }
    
    class Sub extends Claloader{
        static String name = "nezha";
        static {
            System.out.println("这是子类的静态代码块");
        }
    }
    
    
    package com.siyu;
    
    public class Test {
        public static void main(String[] args) {
    
            int age = Sub.age;
    //        hello,world
    //        20
        }
    }
    
    
    

    6-5 直接用java.exe运行某个类

    7 注意的是

    • 子类引用父类静态变量,不会引发子类初始化
    • 通过数组定义引用类,不会引起类初始化
    • 使用final修饰的为常量,不会引起初始化
  • 相关阅读:
    javascript常用对象
    oracle储存过程,job,视图,触发器(记性不好,写个例子自己记)
    xml直接读取节点
    脑瓜子的文章导航 脑瓜子的学院系列文章汇总
    ASP.NET MVC 中实现View与Controller分离
    开发
    SQLite学习手册(转)
    缓存数据库redis、memcached。 MongoDB 资源集锦
    在GOOGLE浏览器中模拟移动浏览器 调试Web app
    Intelligencia.UrlRewriter在IIS 7.0下的完全配置攻略
  • 原文地址:https://www.cnblogs.com/hellosiyu/p/13127647.html
Copyright © 2020-2023  润新知