自定义类加载器的实现,类加载过程

为了安全

每个JAVA程序至少拥有三个类加载器

·引导类加载器 bootstrap

·扩展类加载器 ext

·系统类加载器(应用类加载器)app

引导类加载器负责加载系统类(rt.jar),是虚拟机不可分割的一部分,C实现的,没有对应的classloader对象

例如String.class.getClassLoader()返回null

扩展类加载器用于从jre/lib/ext目录加载标准的扩展,将jar放入该目录,即使没有任何备案域类路径,扩展类加载器也可以找到其中的各个类

系统类加载器用于加载应用类,有CLASSPATH环境变量或-classpath命令选项设置的类路径中的目录里或JAR文件里查找这些类

oracle的java语言实现中,扩展类加载器和系统类加载器都是java实现的,都是urlclassloader类的实例

类加载器的层次结构,向上依赖加载的顺序,app会要求ext加载,ext要求bootstrap加载

JAVA的类加载是父类委托机制,先找父类加载,不行再找子类加载

这是为了害怕用户自己定义class文件然后自己写一个类加载器来加载原本应该是JVM自己加载的类,会使JVM混乱和影响用户安全。

URL url = new URL("*.jar");

URLClassLoader ucl = new URLClassLoader(new URL[]{url});

Class<?> cl = ucl.loadClass("xxx.class");

因为URLClassLoader构造器中没有指定父类加载器,因此ucl的父亲就是系统类加载器

设置线程的加载器

Thread t .....

t.setContextClassLoader(loader);

在指定类加载器的时候会用到

代码如下:

package classloader;

import java.io.BufferedInputStream;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;

public class MyClassLoader extends ClassLoader {

  private String name;//类加载器的名字    private String path = "/home/chiwei/mydisk/eclipse_workspace/java/src/";//类加载的路径    private final String fileType = ".class";    public MyClassLoader(String name) {    super();    this.name = name;  }    public String getPath() {    return path;  }

  public void setPath(String path) {    this.path = path;  }

  private byte[] loadClassData(String name) {    InputStream in = null;    byte[] data = null;    ByteArrayOutputStream baos = null;    try {      name = name.replace(".", "\\");      in = new BufferedInputStream(new FileInputStream(new File(path+name+fileType)));      baos = new ByteArrayOutputStream();      int ch = 0;      while((ch=in.read())!=-1) {        baos.write(ch);      }      data = baos.toByteArray();    }catch(Exception e) {      e.printStackTrace();    }finally {      try {        baos.close();        in.close();      } catch (IOException e) {        e.printStackTrace();      }    }    return data;  }    protected Class<?> findClass(String name) {    byte[] data = this.loadClassData(name);    return this.defineClass(name, data, 0,data.length);  }

  public static void main(String[] args) throws Exception{    // TODO Auto-generated method stub    MyClassLoader loader1 = new MyClassLoader("loader1");    loader1.setPath("");    test(loader1);  }    public static void test(ClassLoader loader) throws Exception{    Class<?> clazz = loader.loadClass("classloader.MyString");    Object object = clazz.newInstance();    MyString ms = (MyString)object;    System.out.println(ms.toString());    System.out.println(object==null);    System.out.println(object.hashCode());  }

 

}

package classloader;

public class MyString {

  public java.lang.String toString() {    return "这是我自定义的String类的toString方法";  }  

}

这是我自定义的String类的toString方法false

926509297

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值