一、JVM和Java体系结构( 九 )

findClass(String name) throws ClassNotFoundException {try {byte[] result = getClassFromCustomPath(name);if(result == null){throw new FileNotFoundException();}else{return defineClass(name,result,0,result.length);}} catch (FileNotFoundException e) {e.printStackTrace();}throw new ClassNotFoundException(name);}private byte[] getClassFromCustomPath(String name){//从自定义路径中加载指定类:细节略//如果指定路径的字节码文件进行了加密,则需要在此方法中进行解密操作 。return null;}public static void main(String[] args) {CustomClassLoader customClassLoader = new CustomClassLoader();try {Class clazz = Class.forName("One",true,customClassLoader);Object obj = clazz.newInstance();System.out.println(obj.getClass().getClassLoader());} catch (Exception e) {e.printStackTrace();}}}
在编写自定义类加载器时,如果没有太过于复杂的需求,可以直接继承类,这样就可以避免自己去编写()方法及其获取字节码流的方式,使自定义类加载器编写更加简洁 。
4、关于
类,它是一个抽象类,其后所有的类加载器都继承自(不包括启动类加载器)
sun.misc.它是一个java虚拟机的入口应用 。
4.1、获取的途径
方式一:获取当前类的
clazz.()
方式二:获取当前线程上下文的Class工pader
.().r ()
方式三:获取系统的
.()
方式四:获取调用者的
. ()
package com.lxg.java1;/*** @author shkstart* @create 2020 上午 10:59*/public class ClassLoaderTest2 {public static void main(String[] args) {try {//1.ClassLoader classLoader = Class.forName("java.lang.String").getClassLoader();System.out.println(classLoader);//2.ClassLoader classLoader1 = Thread.currentThread().getContextClassLoader();System.out.println(classLoader1);//3.ClassLoader classLoader2 = ClassLoader.getSystemClassLoader().getParent();System.out.println(classLoader2);} catch (ClassNotFoundException e) {e.printStackTrace();}}}
5、双亲委派机制
Java虚拟机对class文件采用的是按需加载的方式,也就是说当需要使用该类时才会将它的class文件加载到内存生成class对象 。而且加载某个类的class文件时,Java虚拟机采用的是双亲委派模式,即把请求交由父类处理,它是一种任务委派模式 。
5.1、工作原理
1)如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行
2)如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归请求最终将到达顶层的启动类加载器
3)如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式 。
5.2、案例1
package com.lxg.java1;/*** @author shkstart* @create 2020 上午 11:39*/public class StringTest {public static void main(String[] args) {String str = new String();System.out.println("hello,atguigu.com");StringTest test = new StringTest();System.out.println(test.getClass().getClassLoader());}}
5.3、案例2
优势
避免类的重复助加载
保护程序安全,防止核心API被随意篡改
java.lang.:name:java.lang
5.4、沙箱安全机制
自定义类,但是在加载自定义类的时候会率先使用引导类加载器加载,而引导类加载器在加载的过程中会先加载jdk自带的文件(rt.jar包中java\lang\.clss),报错信息说没有main方法就是因为加载的是rt.jar包中的类 。这样可以保证对java核心源代码的保护,这就是沙箱安全机制 。
6、其他
在JVM中表示两个class对象是否为同一个类存在两个必要条件:
换句话说,在JVM中,即使这两个类对象(class对象)来源同一个class文件,被同一个虚拟机所加载,但只要加载它们的实例对象不同,那么这两个类对象也是不相等的 。