jvm自带的三个classloader
1.Bootstrap classloader,是jvm的一部分,由C写成,调用的是核心库。
sun java下,可以用以下语句查看调用类路径
URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
写道
%JAVA_HOME%/jre/lib/resources.jar
%JAVA_HOME%/jre/lib/rt.jar
%JAVA_HOME%/jre/lib/sunrsasign.jar
%JAVA_HOME%/jre/lib/jsse.jar
%JAVA_HOME%/jre/lib/jce.jar
%JAVA_HOME%/jre/lib/charsets.jar
%JAVA_HOME%/jre/lib/jfr.jar
%JAVA_HOME%/jre/classes
%JAVA_HOME%/jre/lib/rt.jar
%JAVA_HOME%/jre/lib/sunrsasign.jar
%JAVA_HOME%/jre/lib/jsse.jar
%JAVA_HOME%/jre/lib/jce.jar
%JAVA_HOME%/jre/lib/charsets.jar
%JAVA_HOME%/jre/lib/jfr.jar
%JAVA_HOME%/jre/classes
2.ExtClassLoader,调用系统扩展类
写道
%JAVA_HOME%/jre/lib/ext/access-bridge.jar
%JAVA_HOME%/jre/lib/ext/cldrdata.jar
%JAVA_HOME%/jre/lib/ext/dnsns.jar
%JAVA_HOME%/jre/lib/ext/jaccess.jar
%JAVA_HOME%/jre/lib/ext/jfxrt.jar
%JAVA_HOME%/jre/lib/ext/localedata.jar
%JAVA_HOME%/jre/lib/ext/nashorn.jar
%JAVA_HOME%/jre/lib/ext/sunec.jar
%JAVA_HOME%/jre/lib/ext/sunjce_provider.jar
%JAVA_HOME%/jre/lib/ext/sunmscapi.jar
%JAVA_HOME%/jre/lib/ext/sunpkcs11.jar
%JAVA_HOME%/jre/lib/ext/zipfs.jar
%JAVA_HOME%/jre/lib/ext/cldrdata.jar
%JAVA_HOME%/jre/lib/ext/dnsns.jar
%JAVA_HOME%/jre/lib/ext/jaccess.jar
%JAVA_HOME%/jre/lib/ext/jfxrt.jar
%JAVA_HOME%/jre/lib/ext/localedata.jar
%JAVA_HOME%/jre/lib/ext/nashorn.jar
%JAVA_HOME%/jre/lib/ext/sunec.jar
%JAVA_HOME%/jre/lib/ext/sunjce_provider.jar
%JAVA_HOME%/jre/lib/ext/sunmscapi.jar
%JAVA_HOME%/jre/lib/ext/sunpkcs11.jar
%JAVA_HOME%/jre/lib/ext/zipfs.jar
3.AppClassLoader,调用classpath里的类
这三个类遵循双亲委派模型,也就是先每装载一个类时,先从父装载器装载,找不到才一级级往下找,这也就是classpath里的类无法覆盖jdk里自带类的原因。
像tomcat等应用,涉及到webapp隔离,所以在装载每个webapp里的类时,没有遵循双亲委派模型,而是优先自己所调用的类,另外这里有个关键点,就是隐式装载,也就是用关键字new创建对象时,装载这个类所使用的装载器是使用new关键字所在类的装载器。
以下代码可以模拟这个过程。
自定义类装载器
package jp.co.wqf; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; public class MyClassLoader extends ClassLoader { private String name; private String path = "D:/"; private final String fileType = ".class"; public MyClassLoader(String name){ super(); this.name = name; } public MyClassLoader(String name, ClassLoader cl){ super(cl); this.name = name; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } @Override protected Class<?> findClass(String name) throws ClassNotFoundException { byte[] data = loaderClassData(name); return this.defineClass(name, data, 0, data.length); } private byte[] loaderClassData(String className){ InputStream is = null; byte[] data = null; ByteArrayOutputStream baos = new ByteArrayOutputStream(); String fileName = className.replace(".", "/"); try { is = new FileInputStream(new File(path + fileName + fileType)); int c = 0; while(-1 != (c = is.read())){ baos.write(c); } data = baos.toByteArray(); } catch (Exception e) { e.printStackTrace(); } finally{ try { is.close(); baos.close(); } catch (IOException e) { e.printStackTrace(); } } return data; } }
测试
package jp.co.wqf; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub MyClassLoader classLoader = new MyClassLoader("classload1"); classLoader.setPath("/eclipse/workspace/Test/bin/"); try { Class<?> clsA = classLoader.loadClass("jp.co.wqf.A"); Object objA = clsA.newInstance(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
以下类不要放在上面代码的classpath里
package jp.co.wqf; public class A { private B b; public A(){ this.b = new B(); } }
package jp.co.wqf; public class B { private C c; public B(){ this.c = new C(); } }
package jp.co.wqf; public class C { public C(){ System.out.println("create class c!"); } }
相关推荐
NULL 博文链接:https://lz12366.iteye.com/blog/735289
Sun 官方关于 ClassLoader原理的文章,值得一看
Java 虚拟机中ClassLoader 相关简介 双亲委托机制 Android 中ClassLoader 简介
ClassLoader运行机制 自己写的ClassLoader运行机制 自己写的ClassLoader运行机制 自己写的ClassLoader运行机制 自己写的ClassLoader运行机制 自己写的
自定义classloader的使用
ClassLoader原理,ClassLoader原理 ClassLoader原理
Java ClassLoader定制实例
java classloader classpath 张孝祥
关于J2EE服务器的ClassLoader的原理,该文档清晰了揭示了jvm装载类的顺序,同时用户可以自定义修改classLoader的配置 通过该文档,可以加深对Java虚拟机的理解
理解Java ClassLoader机制
用于验证理解Android中Classloader加载类机制的程序demo,从中可以对比DexClassLoader和PathClassLoader的区别联系。
破解java加密的ClassLoader.java,在classloader植入破解代码
Classloader
ClassLoader类加载机制和原理详解
classloader 源码,自定义classloader
自定义ClassLoader,控制台输入调试。 运行期间 重新载入指定目录的class文件。可实现对于类的功能函数更新。 用到java 反射,@interface 等技术
Java中ClassLoader的解析,从ClassLoader的角度分析了JVM,装载类,创建类的对象的整个过程,更清晰的了解JVM的运行机制。
JVM内存模型,类加载模式工作机制详细,内存屏障,类从被加载到虚拟机内存中开始,直到卸载出内存为止,它的整个生命周期包括了:加载、验证、准备、解析、初始化、使用和卸载这7个阶段。其中,验证、准备和解析这三...