自定义类加载器 MyTest18
public class MyTest18 extends ClassLoader{
private String classLoaderName;
private String path;
private String feleExtension = ".class";
public MyTest18(String classLoaderName) {
super(); //将系统类加载器当做该类加载的父加载器
this.classLoaderName = classLoaderName;
}
public MyTest18(ClassLoader parent, String classLoaderName) {
super(parent);// 显示指定该类加载器父加载器
this.classLoaderName = classLoaderName;
}
public void setPath(String path) {
this.path = path;
}
@Override
protected Class<?> findClass(String className) throws ClassNotFoundException {
System.out.println("className: " + className);
System.out.println("classLoaderName: " + this.classLoaderName);
byte[] data = this.loadClassData(className);
return this.defineClass(className, data, 0, data.length);
}
private byte[] loadClassData(String className){
byte[] data = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
System.out.println("loadClassData.222.........");
try {
className = className.replace(".", "\\");
String fileName = this.path + className + this.feleExtension;
System.out.println("fileName: " + fileName);
is = new FileInputStream(new File(fileName));
baos = new ByteArrayOutputStream();
int ch = 0;
while (-1 != (ch = is.read())) {
baos.write(ch);
}
data = baos.toByteArray();
} catch (Exception e) {
}finally {
try {
is.close();
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return data;
}
public static void main(String[] args) throws Exception {
MyTest17 myTest = new MyTest17("loader17");
//myTest.setPath("E:\\gitSpace\\jdk8\\out\\production\\classes\\");
myTest.setPath("c:\\");
Class<?> clazz = myTest.loadClass("jvm.classloader.MyTest2");
System.out.println("class: " + clazz);
System.out.println("class.hashCode: " + clazz.hashCode());
Object object = clazz.newInstance();
System.out.println(object);
System.out.println("--------------------------------");
MyTest17 myTest2 = new MyTest17("loader177");
//myTest.setPath("E:\\gitSpace\\jdk8\\out\\production\\classes\\");
myTest2.setPath("c:\\");
Class<?> clazz2 = myTest2.loadClass("jvm.classloader.MyTest2");
System.out.println("class2: " + clazz2);
System.out.println("class2.hashCode: " + clazz2.hashCode());
Object object2 = clazz2.newInstance();
System.out.println(object2);
}
本例中,2个类加载器,都委托系统(或应用)加载器去加载,因此重写的findClass不会执行,没输出,在类路径上能找到,只会执行一次加载, hashCode是一致的
class: class jvm.classloader.MyTest2
class.hashCode: 366712642
jvm.classloader.MyTest2@6d06d69c
class2: class jvm.classloader.MyTest2
class2.hashCode: 366712642
jvm.classloader.MyTest2@7852e922
若将类路径下的MyTest2.class删除后则输出如下
每个类加载器都有自己的命名空间,命名空间由该加载器及所有父加载器所加载的类组成
className: jvm.classloader.MyTest2
classLoaderName: loader17
loadClassData..........
fileName: c:\jvm\classloader\MyTest2.class
class: class jvm.classloader.MyTest2
class.hashCode: 135721597
jvm.classloader.MyTest2@87aac27
className: jvm.classloader.MyTest2
classLoaderName: loader177
loadClassData..........
fileName: c:\jvm\classloader\MyTest2.class
class2: class jvm.classloader.MyTest2
class2.hashCode: 1406718218
jvm.classloader.MyTest2@e9e54c2
public static void main(String[] args) throws Exception {
MyTest18 myTest = new MyTest18("loader18");
//myTest.setPath("E:\\gitSpace\\jdk8\\out\\production\\classes\\");
myTest.setPath("c:\\");
Class<?> clazz = myTest.loadClass("jvm.classloader.MyTest2");
System.out.println("class: " + clazz);
System.out.println("class.hashCode: " + clazz.hashCode());
Object object = clazz.newInstance();
System.out.println(object);
System.out.println("--------------------------------");
MyTest18 myTest2 = new MyTest18(myTest, "loader18");
//myTest.setPath("E:\\gitSpace\\jdk8\\out\\production\\classes\\");
myTest2.setPath("c:\\");
Class<?> clazz2 = myTest2.loadClass("jvm.classloader.MyTest2");
System.out.println("class2: " + clazz2);
System.out.println("class2.hashCode: " + clazz2.hashCode());
Object object2 = clazz2.newInstance();
System.out.println(object2);
System.out.println("--------------------------------");
MyTest18 myTest3 = new MyTest18(myTest2, "loader19");
//myTest.setPath("E:\\gitSpace\\jdk8\\out\\production\\classes\\");
myTest3.setPath("c:\\");
Class<?> clazz3 = myTest3.loadClass("jvm.classloader.MyTest2");
System.out.println("class3: " + clazz3);
System.out.println("class3.hashCode: " + clazz3.hashCode());
Object object3 = clazz3.newInstance();
System.out.println(object3);
}
此示例没删除MyTest2.class则输出如下
第2个加载器加载的是父类的,第3个加载时,在1中已经加载过,所以3者是加载的同个类
className: jvm.classloader.MyTest2
classLoaderName: loader18
loadClassData.222.........
fileName: c:\jvm\classloader\MyTest2.class
class: class jvm.classloader.MyTest2
class.hashCode: 135721597
jvm.classloader.MyTest2@87aac27
class2: class jvm.classloader.MyTest2
class2.hashCode: 135721597
jvm.classloader.MyTest2@3e3abc88
class3: class jvm.classloader.MyTest2
class3.hashCode: 135721597
jvm.classloader.MyTest2@6ce253f1
网友评论