类加载
类加载过程
加载
1、类的加载:将类的Class文件加载到内存中,并为其生成Java.class对象(此过程由类加载器完成)
链接
2、类的链接:将Java类的二进制数据合并到jvm运行状态中(jre)
2.1、验证:确保类符合JVM规范,保证安全性
2.2、准备:为类变量分配内存和初始化值
2.3、解析:JVM常量池中的符号引用(常量名)直接替换成直接引用(地址)
初始化
3、类的初始化:JVM对类进行初始化
执行类构造器方法(这个方法是由编译期自动收集类中所有类变量的赋值动作和静态代码块中的语句合并产生的(类构造器是构造类信息的,不是构造该类对象的构造器))
当初始化一个类的时候,如果发现其父类还没有进行初始化,则需要先触发其父类的初始化。
JVM会保证一个类的()方法在多线程环境中被正确加锁和同步。
类加载器
类加载分类
引导类加载器 BootStrap Class Loader
自定义类加载器 User Defined Class Loader 派生于ClassLoader的
引导类加载器(启动类加载器 Bootstrap ClassLoader)
使用C/C++ 实现,嵌套在JVM内部
用来加载Java的核心类库
没有父类加载器
加载扩展类和应用类加载器,并指定为它们的父类加载器
只加载包名为java javax sun等开头的类
自定义类加载器
用户自定义的类加载器
目的
隔离加载类(多个框架避免类冲突)
修改加载类方式
扩展加载源
防止源码泄露
步骤
1.继承ClassLoader ->重写findClass
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] classFromCustomPath = getClassFromCustomPath(name);//读取class的字节码流
try {
if (classFromCustomPath==null){
throw new FileNotFoundException();
}else{
return defineClass(name, classFromCustomPath, 0, classFromCustomPath.length);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
throw new ClassNotFoundException();
}
2.没有过于复杂的需求可以直接继承URLClassLoader 类
扩展类加载器(Extension ClassLoader)
java 编写 sun.misc.Launcher ExtClassLoader 实现
派生于ClassLoader类
父类加载器为启动类加载器
从java.ext.dirs系统属性所指定的目录中加载类库,或从JDK的安装目录的jre/lib/ext子目录下加载类库。如果用户创建的JAR放在此目录下,也会自动由扩展类加载器加载。
应用程序类加载器(系统类加载器 AppClassLoader)
java 编写sun.misc.Launcher$AppClassLoader 实现
派生于ClassLoader类
父类加载器为扩展类加载器
它负责加载环境变量classpath或系统属性 java.class.path 指定路径下的类库
该类加载器是程序中默认的类加载器,一般来说,Java应用的类都由该类加载器来加载
通过ClassLoader.getSystemClassLoader()可以获取该类加载器
获取类加载器的方式
1.clazz.getClassLoader()
2.Thread.currentThread().getContextClassLoader()
3.ClassLoader.getSystemClassLoader()
4.DriverManager.getCallerClassLoader();
双亲委派机制
如果一个类加载器收到类加载的请求,它并不会自己先加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类则进一步向上委托依次递归到顶层启动类加载器。如果父类能完成加载就执行加载成功返回,不能再交给子加载器加载
系统类加载器 -》 扩展类加载器 -》引导类加载器
优势:
1.避免重复加载
2.防止恶意修改
沙箱安全机制
对源代码的保护
沙箱机制就是将 Java 代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本地系统资源访问,通过这样的措施来
保证对代码的有效隔离,
防止对本地系统造成破坏。沙箱主要限制系统资源访问,那系统资源包括什么?——
CPU、内存、文件系统、网络。不同级别的沙箱对这些资源访问的限制也可以不一样。
- 在jvm中两个class对象为同一个类的条件
类的完整类名是同一个,类加载器是同一个