java classLoader 理解三

来源:互联网 发布:找房源的软件 编辑:程序博客网 时间:2024/05/22 13:21

第二篇博文主要讲解了ClassLoader的一些原理性的东西,本篇主要分析一些实战性的东西.                                                                                                                                                       一般 获取ClassLoader会有如下三种方式:

        1.this.getClass().getClassLoader();           2.ClassLoader.getSystemClassLoader(); 3.Thread.currentThread().getContextClassLoader();

第一种方法主要通过Class文件获取,最常见,

第二种方法通过ClassLoader类的静态方法getSystemClassLoader()获取,该方法返回就是AppClassLoader(个人觉得),

第三种方法通过当前线程获取,如果启动该线程的类在classPath下,获取到的自然就是AppClassLoader,如果启动线程的类在java.ext.dir目录下,获取到的就是extClassLoader,除了获取ClassLoader,第三种方式也可set  ClassLoader,看代码,

class MyClassLoader extends URLClassLoader {        MyClassLoader(URL[] urls, ClassLoader parent) {            super(urls, parent);}public static void main(String args[]) throws Exception{File file=new File("D:\\wp\\JFinalWp\\ClassLoader\\bin");URL url=file.toURL();URL urls[]=new URL[]{url};MyClassLoader classLoader=new MyClassLoader(urls,ClassLoader.getSystemClassLoader());Thread.currentThread().setContextClassLoader(classLoader);Class newClass=classLoader.findClass("com.my.classloader.MyClassLoaderTest");System.out.println(Thread.currentThread().getContextClassLoader());}}

自定义了一个ClassLoader,指定加载目录,指定父加载器, 指定加载目录url2肯定不是当前项目(既MyClassLoader这个类所属项目)的目录,因为当前项目ClassPath下面的文件肯定会被appClassLoader这个父加载器先加载.


接下来说说自定义ClassLoader,上代码先,

代码1:

class MyClassLoader extends URLClassLoader {                MyClassLoader(URL[] urls, ClassLoader parent) {    super(urls, parent);}public static void main(String args[]) throws Exception{File file=new File("D:\\wp\\JFinalWp\\ClassLoader\\bin");URL url=file.toURL();URL urls[]=new URL[]{url};MyClassLoader classLoader=new MyClassLoader(urls,ClassLoader.getSystemClassLoader());Class newClass=classLoader.findClass("com.my.classloader.MyClassLoaderTest");Object object=newClass.newInstance();Method method=newClass.getMethod("setName",String.class);method.invoke(object, "jake");Method method2=newClass.getMethod("sayName");method2.invoke(object);classLoader.close();}}
代码2:

class MyClassLoader2 extends ClassLoader {        MyClassLoader2(ClassLoader parent) {        super(parent);}                public Class<?> findClass(String name)  {  //ps: 该方法实现还是有问题的                FileInputStream input=null;        ByteOutputStream out=null;        String oName=name;        try {name=name.replace(".", File.separator).concat(".class");        File file=new File("D:\\wp\\JFinalWp\\ClassLoader\\bin\\"+name);                input=new FileInputStream(file);        out=new ByteOutputStream();        byte by[]=new byte[1024];int len=0;while((len=input.read(by))!=-1){out.write(by, 0, len);}byte bt[]=out.getBytes();return defineClass(oName,bt, 0, bt.length);} catch (Exception e) {e.printStackTrace();}finally{if(input!=null){try {input.close();} catch (IOException e) {e.printStackTrace();}}if(out!=null){out.close();}}        return null;        }        public static void main(String args[]) throws Exception{MyClassLoader2 classLoader=new MyClassLoader2(ClassLoader.getSystemClassLoader());Class newClass=classLoader.findClass("com.my.classloader.MyClassLoaderTest");Object object=newClass.newInstance();Method method=newClass.getMethod("setName",String.class);method.invoke(object, "jake");Method method2=newClass.getMethod("sayName");method2.invoke(object);}}


代码一是通过继承URLClassLoader这个ClassLoader,我们常见的appClassLoader,extClassLoader就是继承这个类加载器,URLClassLoader内部实现了findClass(String name)这个方法,载入自己需要的class文件,  载入后转化为我们的Class对象则可以调用顶层ClassLoader内部loadClass(String name)方法

代码二是通过继承ClassLoader这个顶层类加载器实现,findClass(String name) 这个方法需要自己实现,比较麻烦,上面代码二的方法还是有点问题的,


一般通过代码一的方式实现就行了,URLClassLoader内部实现还是完善的.

0 0
原创粉丝点击