当前位置: 主页 > JAVA语言

java 委派类加载-java动态类学习文章java程序

发布时间:2023-06-10 07:04   浏览次数:次   作者:佚名

java动态类加载学习

文章目录

静态代码块加载

整一个Person类java 委派类加载,里面放静态代码块和动态代码块等等,看不同操作下,他们的调用情况

实例化一个类对象

new Person();

在这里插入图片描述

调用静态方法

Person.staticAction();

java找不到或无法加载主类_java 委派类加载_java动态加载类

调用了静态代码块和静态方法

在这里插入图片描述

赋值

Person.id = 1;

这里只调用了静态代码块

在这里插入图片描述

所以静态代码块在类初始化的时候就调用了,而其他的在类实例化的时候才调用(比如构造代码块,无参构造函数)

java找不到或无法加载主类_java 委派类加载_java动态加载类

Class c = Person.class;

这里只加载不初始化,所以不调用静态代码块

使用Class.forName

Class.forName("cc3.Person");

这里进行了初始化,调用了静态代码块

在这里插入图片描述

双亲委派

java找不到或无法加载主类_java 委派类加载_java动态加载类

java有三种类加载器

1、启动类加载器(Bootstrap ClassLoader)

它是属于虚拟机自身的一部分,用C++实现的,主要负责加载\lib目录中或被-Xbootclasspath指定的路径中的并且文件名是被虚拟机识别的文件。加载String java.lang这些

2、扩展类加载器(Extension ClassLoader)

它是Java实现的,独立于虚拟机,主要负责加载\lib\ext目录中或被java.ext.dirs系统变量所指定的路径的类库。加载扩展包 ext

3、应用程序类加载器(Application ClassLoader)

它是Java实现的,独立于虚拟机。主要负责加载用户类路径(classPath)上的类库,如果我们没有实现自定义的类加载器那这玩意就是我们程序中的默认加载器。加载用户自定义类

java 委派类加载_java找不到或无法加载主类_java动态加载类

在这里插入图片描述

双亲委派的意思是如果一个类加载器需要加载类,那么首先它会把这个类请求委派给父类加载器去完成java 委派类加载,每一层都是如此。一直递归到顶层,当父加载器无法完成这个请求时,子类才会尝试去加载。这里的双亲其实就指的是父类,没有mother。父类也不是我们平日所说的那种继承关系,只是调用逻辑是这样。

理解:加载一个类时,先一直委派到顶层,从最顶层开始,去相应的文件夹中找相应的class文件,没有就往子类中找,其中第三层Application ClassLoader就加载我们用户自己写的类

类的继承关系

ctrl+aalt+u查看类的继承关系

在这里插入图片描述

ClassLoader-->SecureClassLoader-->URLClassLoader-->AppClassLoader
loadClass-->findClass(重写的方法)-->defineClass(从字节码加载类)

java找不到或无法加载主类_java 委派类加载_java动态加载类

加载类测试

注意,其中第二步加载类的时候不进行初始化

ClassLoader cl = ClassLoader.getSystemClassLoader();
Class<?> c = cl.loadClass("cc3.Person");//  不进行初始化
c.newInstance();

URLClassLoader任意类加载

先整一个Hello.java

import java.io.IOException;
public class Hello {
    static {
        System.out.println("hello sk1y");
        try {
            Runtime.getRuntime().exec("calc");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

然后javac编译,将Hello.class文件移走,然后将源码中的Hello.java删除

file协议

注意第二行加载类的时候不进行初始化

URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("file:///D:\\project\\java\\classes\\")});
Class<?> c = urlClassLoader.loadClass("Hello");
c.newInstance();