java类加载器
来源:互联网 发布:苹果手机健身软件 编辑:程序博客网 时间:2024/06/11 13:58
类加载器
java虚拟机代码存储在.class结尾的类文件当中,但是运行程序的机器并不能识别class文件,这就需要一种机制将class文件解释为机器能够识别的代码,这就是类加载器
类加载器的分类
类加载器分为以下三类:
- BootStrap ClassLoader(引导类加载器或者叫启动类加载器)
- ExtClassLoader(扩展类加载器)
- AppClassLoader(系统类加载器或者叫应用类加载器)
BootStrap ClassLoader是虚拟机的一部分,它是由C语言实现的,通常从rt.jar文件中加载(也即java.开头的类文件)。BootStrap ClassLoader没有对应的ClassLoder对象,比如以下方法:
String.class.getClassLoader()
该方法执行后会返回null。
ExtClassLoader从jre/lib/ext目录加载“标准的扩展”,如果将jar文件放入该目录,即时没有任何类路径,ExtClassLoder也可以找到其中的各个类。AppClassLoader用于加载应用类,它对CLASSPATH环境变量或者-classpath指定的目录或者jar文件进行加载。
每个线程都有一个对类加载器的引用,称为上下文类加载器。主线程的上下文类加载器是AppClassLoader,当新线程创建时,它的上下文类加载器被设置为创建它的线程的上下文类加载器。比如以下方法:
public static void main(String[] args) throws InterruptedException { System.out.println(Thread.currentThread().getContextClassLoader()); new Thread(new Runnable() { public void run() { System.out.println(Thread.currentThread().getContextClassLoader()); } }).start(); }
该方法执行后会输出:
sun.misc.Launcher$AppClassLoader@14dad5dcsun.misc.Launcher$AppClassLoader@14dad5dc
类的加载
类的加载有三种方式:
- 启动应用时由jvm进行加载;
- 使用Class.forName进行动态加载;
使用ClassLoader的loadClass方法进行动态加载。
第一种方式如前所述,不进行赘述。Class.forName方法和ClassLoader的loadClass方法有一些区别,主要如下:Class.forName有两个,一个是Class.forName(String name), 一个是Class.forName(String name, boolean initialize, ClassLoader loader), 执行Class.forName(className)等同于Class.forName(className, true, currentLoader), 会对类进行初始化;
- ClassLoader的loadClass方法单纯进行类加载,不进行初始化操作,只有在调用newInstance方法时才会进行初始化操作。
我们定义一个具有static块的类对上述逻辑进行测试,
public class StaticTest { static { System.out.println("static test"); }}
使用以上测试类执行以下代码:
public static void main(String[] args) throws InterruptedException, ClassNotFoundException, IllegalAccessException, InstantiationException { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); Class a = classLoader.loadClass("com.cmcc.hy.StaticTest"); //此处不会触发static语句块执行 a.newInstance();//此处会触发static语句块执行 Class b = Class.forName("com.cmcc.hy.StaticTest");//此处不会触发static语句块执行 b.newInstance();//此处不会触发static语句块执行 Class.forName("com.cmcc.hy.StaticTest", true, classLoader);//此处不会触发static语句块执行 }
执行之后,会输出一次“static test”,ClassLoader的loadClass的方法不会进行初始化, newInstance方法执行时如果Class已经初始化,则不进行初始化操作,否则进行初始化,那么a.newInstance会进行初始化操作,从而触发static语句块执行,Class.forName原本会进行初始化,但是根据类的加载原则,所有的Class只会加载一次,所以b本质上和a是相同的引用,那么b.newInstance也不会进行初始化操作,最后一句也和此相同,不会进行初始化操作。
- Java类加载器
- java类加载器
- java类加载器
- Java类加载器
- java类加载器
- Java类加载器
- Java 类加载器
- java类加载器
- java类加载器
- Java 类加载器
- -java 类加载器
- Java-类加载器
- Java类加载器
- Java 类加载器
- Java 类加载器
- java类加载器
- java类加载器
- Java-----类加载器
- 快速幂 矩阵快速幂
- C++构造函数与析构函数中的“异常”
- python 不同方式读取文件速度不同
- 一步一步解析H.264码流的NALU(SPS,PSS,IDR)获取宽高和帧率
- android 属性动画之 ObjectAnimator
- java类加载器
- HttpServletRequest 中 获取文件(File)信息;
- 排序算法总结
- 欢迎使用CSDN-markdown编辑器
- mysql数据库连接util
- socket 实例
- 72条基本商务礼仪
- iOS使用自签名证书实现HTTPS请求
- 数据同步的几个原则