24.java-类加载器

类加载器

类加载器的作用和加载时机

  • 作用 : 负责将.class文件(存储的物理文件)加载在到内存中

  • 加载时机 : 用到即加载

    • 创建类的实例(对象)
    Student stu = new Student();
    
    • 调用类的静态方法
    Arrays.toString(arr);
    
    • 访问类或者接口的静态变量,或者为该类静态变量赋值
    interface Inter {
        int NUM = 10;
    }
    
    System.out.println(Inter.NUM);
    
    ------------------------------------------------------------------------------
    
    class A {
    	public static int num;
    }
    
    A.num = 20;
    System.out.println(A.num);
    
    • 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
    Class clazz = Class.forName("com.itheima.domain.Student");
    clazz.newInstance();
    
    • 初始化继承体系
    class Fu {}
    
    class Zi extends Fu {}
    
    Zi z = new Zi();
    
    1). Zi 字节码文件
    2). Fu 字节码文件
    
    • 直接使用 java.exe 命令来运行某个主类
    java HelloWorld.java
    

类加载器的过程

24.java-类加载器_第1张图片

加载:通过包名+类名,获取这个类,准备用流进行传输,将类加载到内存中,加载完毕创建一个class对象
验证:检验文件中的信息是否符合虚拟机规范,有没有安全隐患
准备:为类的类变量(被static修饰的变量)分配内存,设置默认初始化值()初始化静态变量
解析:将类的二进制数据流中符号引用替换为直接引用 (本类中如果用到了其他类,此时就需要找到对应的类)
初始化:静态变量赋值以及初始化其他资源

小结
  • 当一个类被使用的时候,才会加载到内存
  • 类加载的过程: 加载、验证、准备、解析、初始化

类加载器的分类

类的字节码对象.getClassLoader();  获取该类的, 类加载器对象.
  • Bootstrap class loader:虚拟机的内置类加载器,通常表示为null
    • C++ 实现, 获取到的只能是 null
  • Platform class loader:平台类加载器,负责加载JDK中一些特殊的模块 负责加载 lib\modules 内部的类
    • JDK9 之前是 :(Extension Class Loader) 扩展类加载器 : 负责加载 jre\lib\ext 目录下的类
  • Application class loader:负责加载自己写的类
  • 自定义类加载器 : 上级为 Application
    • 目前不做讲解 , 自己设计框架的时候才会用得到

双亲委派机制

如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器,如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式

24.java-类加载器_第2张图片

好处 :
  • 双亲委派模型保证了 Java 程序的稳定运行,可以避免类的重复加载
    • 当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次
  • 保证了 Java 的核心 API 不被篡改
假设我们自己编写了一个 Object 类
	1. java.lang.Object类	(真的)
	2. java.lang.Object类	(假的)
	
	双亲委派模型可以保证加载的是 JRE 里的那个 Object 类, 而不是我们自己写的
	
	AppClassLoader ---> PlatformClassLoader ---> BootstrapClassLoader
	
	BootstrapClassLoader : 发现已经加载过了Object类了, 就不会加载我们自己写的了

常用方法

方法名 作用
public static ClassLoader getSystemClassLoader() 获取系统类加载器
public InputStream getResourceAsStream(String name) 加载某一个资源文件
 public static void main(String[] args) throws Exception {
	InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("config.properties");
        Properties prop = new Properties();
        prop.load(is);
        is.close();
        //通过配置文件获取全类名
        String className = prop.getProperty("className");
        Class<?> aClass = Class.forName(className);
        System.out.println(aClass);*/
        Class<?> aClass = Class.forName("com.Student");
        //反射空参构造方法(解剖)
        Constructor<?> constructor = aClass.getConstructor();
        //使用空参构造方法对象,构造对象
        Object o = constructor.newInstance();

        //反射带参构造方法(解剖)
        Constructor<?> constructor1 = aClass.getConstructor(String.class);
        Object o2 = constructor1.newInstance("张三");

        //[暴力反射]带参构造方法(解剖)
        Constructor<?> constructor2 = aClass.getDeclaredConstructor(String.class);
        //开启权限
        constructor2.setAccessible(true);
        Object o3 = constructor2.newInstance("王飞杨");
    }
 }


tructor(String.class);
        //开启权限
        constructor2.setAccessible(true);
        Object o3 = constructor2.newInstance("王飞杨");
    }
 }

你可能感兴趣的:(java)