如果情书了类加载器的概念,实际上也就清楚了一点:用户可以定义属于自己的类加载器,那么可以直接继承ClassLoader类完成.
public abstract class ClassLoader extends Object
ClassLoader本身就是一个抽象类,但是这个类每一抽象方法,是为了让用户去继承,如果已经得到程序类的文件信息,那么可以使用ClassLoader类的以下方法进行加载,
加载类:
public Class<?> loadClass(String name) throws ClassNotFoundException
package cn.zwb.classloader;
public class MyClassLoader extends ClassLoader{
public Class<?> getMyClass(String className) throws ClassNotFoundException{
return super.loadClass(className);
}
}
此时实际上只是定义了一个类加载器的结构,骨子里还是通过CLASSPATH加载类,
范例:使用类加载器
package cn.zwb.classloader;
public class ClassLoaderDemo {
public static void main(String[] args) throws ClassNotFoundException {
MyClassLoader mcl=new MyClassLoader();
Class<?> cls= mcl.getMyClass("cn.zwb.classloader.Salgrade");
System.out.println(cls);
}
}
package cn.zwb.classloader;
public class Salgrade {
public Salgrade() {
System.out.println("********实例化Salgrade类对象***********");
}
}
以上的类加载器是否提供没有任何的关系,最有用处的类加载器一定是可以通过远程加载.
如果说此时在D:盘上保存有一个"Salgrade.class"文件(这只是文件,没有包的存在).既然是文件,那么一定要使用io流读取数据.在ClassLoader类里面提供有一个可以将字节数组变为类文件转换
方法:
protected final Class<?> defineClass(String name, byte[] b, int off, int len, ProtectionDomain protectionDomain) throws ClassFormatError
读取不在CLASSPATH中的类
package cn.zwb.classloader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class MyClassLoader extends ClassLoader{
public Class<?> getMyClass(String className) throws ClassFormatError, Exception{
byte[] d=this.getFileDate(className);
return super.defineClass(className, this.getFileDate(className), 0, d.length);
}
private byte[] getFileDate(String className) throws Exception{
byte ret[]=null;
File file=new File("D:"
+File.separator+className.substring(className.lastIndexOf(".")+1)+".class");
InputStream input=new FileInputStream(file );
ByteArrayOutputStream bos=new ByteArrayOutputStream();
byte data[] =new byte[1024];
int len=0;
while((len=input.read(data))!=-1){
bos.write(data,0,len);
}
ret=bos.toByteArray();
bos.close();
input.close();
return ret;
}
}
测试
public class ClassLoaderDemo {
public static void main(String[] args) throws ClassFormatError, Exception {
MyClassLoader mcl=new MyClassLoader();
Class<?> cls= mcl.getMyClass("cn.zwb.classloader.Salgrade");
System.out.println(cls.newInstance());
}
}
结果
********实例化Salgrade类对象***********
cn.zwb.classloader.Salgrade@5c647e05
总结:
1.使用类加载器之后彻底打破了CLASSPATH的限定格局;
2.类加载器毕竟属于扩充功能.