虚拟机类加载过程基础可以参考:JVM类加载机制基础
我们知道jvm的类加载是利用双亲委派机制,
图片来自http://blog.youkuaiyun.com/cutesource/article/details/5904501
JVM的类加载是通过ClassLoader及其子类来完成的,类的层次关系和加载顺序可以由下图来描述:
• 根类加载器(Bootstrap)
• 扩展类加载器( Extension)
• 系统类加载器( App)
用户自定义类加载器需要继承ClassLoader类,ClassLoader的相关方法
jdk的ClassLoader类的loaderClass方法实现了双亲委派源码如下,lz加了部分注释
在写自己的类加载器之前,先看一下Java API中给出了一个网络类加载器:
下面我们参照这个例子,写一个自己的类加载器,因为网络不好模拟,我们就定义一个加载本地文件类的加载器。
首先创建一个Java工程,工程目录如下图所示
然后我们来写自己的类加载器MyClassLoader
定义一个被加载的类
下面进行测试
package com.slowly.hy;
public class Test01 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
MyClassLoader classLoader01 = new MyClassLoader("e:/project/MyClassLoaderLearning");//我的工程的路径
Class<?> c = classLoader01.loadClass("com.slowly.hy.test.Hello");
Object obj = c.newInstance();
}
}
输出结果:
sun.misc.Launcher$AppClassLoader@73d16e93
Hello
可以看出此时使用系统类加载器加载的,并没有用我们自己的类加载器,这是什么原因呢?那么怎么又能让自己的类加载器进行加载呢??其实上面的双亲委派图中已经提到了,系统类加载器(App ClassLoader)会加载classpath或java.class.path路径下的jar包和类,下面我们让测试程序打印一下java.class.path
package com.slowly.hy;
public class Test02 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
MyClassLoader classLoader01 = new MyClassLoader("e:/project/MyClassLoaderLearning");
Class<?> c = classLoader01.loadClass("com.slowly.hy.test.Hello");
System.out.println(c.getClassLoader());
Object obj = c.newInstance();
System.out.println(System.getProperty("java.class.path"));
}
}
可以看出java.class.path路径为上图所示
那么怎样才能让自己定义的类加载器加载呢?我们把Hello.class文件移出系统类加载器的默认加载路径,
原路径:
移动到
测试程序
package com.slowly.hy;
public class Test03 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
MyClassLoader classLoader01 = new MyClassLoader("e:/project/MyClassLoaderLearning");
Class<?> c = classLoader01.loadClass("Hello");
System.out.println(c.getClassLoader());
Object obj = c.newInstance();
System.out.println(System.getProperty("java.class.path"));
}
}
运行结果
可以看出是用自己定义的类加载器加载了
写这篇文章真是太费劲了,发了3次,前面都是格式不对,发表上来比较乱,所以有重写写了一次,真是不容易啊,望好评,多指教,希望这次能发表成功吧!