Java面试问题之十三
类加载器是Java虚拟机中重要的部分,请自定义一个类加载器来实现.class文件的加载功能。
答:要创建一个用户自己的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的findClass(String name)方法即可,该方法根据参数指定了类的名称,返回对应Class对象的引用。下面编写一个MyClassLoader来实现.class文件的加载功能。
import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;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(ClassLoader parent,String name){ super(parent); this.name=name; } public String toString(){ return name; } //设定类类文件所在的路径 public void setPath(String path){ this.path=path; } public String getPath(){ return this.path; } //findClass需要被覆盖,定义自己的逻辑供系统调用 protected Class findClass(String name) throws ClassNotFoundException{ byte[] data= loadClassData(name); return defineClass(name,data,0,data.length); //返回对应的Class引用 } private byte[] loadClassData(String name) throws ClassNotFoundException{ FileInputStream fis=null; byte[] data=null; ByteArrayOutputStream baos=null; try{ name=name.replaceAll("\\.","\\\"); fis=new FileInputStream(new File(path+name+fileType)); baos=new ByteArrayOutputStream(); int ch=0; while((ch=fis.read())!=-1){ baos.write(ch); //将.class文件写入内存中 } data=baos.toByteArray(); }catch(IOException e){ throw new ClassNotFoundException("Class is not found:"+name,e); }finally{ //注意:在最后一定要关闭输入输出流对象 try{ fis.close(); baos.close(); }catch(IOException e) { e.printStackTrace(); } } return data; } public static void test(ClassLoader loader) throws Exception { Class objClass = loader.loadClass("Sample"); Object obj=objClass.newInstance(); //创建一个Sample类实例 } public static void main(String[] args){ try{ MyClassLoader loader1=new MyClassLoader("loader1"); loader1.setPath("D:\\Java\\Program\\Exercises"); MyClassLoader loader2=new MyClassLoader(loader1,"loader2"); loader2.setPath("D:\\Java\\Program\\Exercises"); MyClassLoader loader3=new MyClassLoader(null,"loader3"); loader3.setPath("D:\\Java\Program\\Others"); test(loader2); test(loader3); }catch(Exception e){ e.printStackTrace(); } }}