对Java的ClassLoader的几点认识

本文详细解析了Java中的ClassLoader机制,包括其作为普通抽象类的角色、URLClassLoader的具体实现方式、类加载过程中的双亲委派模型,以及类加载器在解决类隔离问题上的作用。
1 ClassLoader只是一个普通抽象类,它的工作是从类名得到Class。ClassLoader与其他类的唯一不同之处是它是为JVM服务的,属于“公务员”,例如Thread就带有getContextClassLoader()和setContextClassLoader()方法;


2 ClassLoader的实现类URLClassLoader完成工作的方法是根据传入的class目录或jar文件的URL读取二进制文件,并转化为Class;


3 ClassLoader有个成员变量parent,使用ClassLoader获取Class时,默认会先用它的parent尝试获取该Class,没有的话自己再尝试。当然,你可以自己实现ClassLoader来改变这一行为。例如:


复制代码
import java.net.URL;
import java.net.URLClassLoader;


/**
 * 先自己尝试获取Class,不行再找parent
 */
public class OverridingClassLoader extends URLClassLoader
{
  
  private final ClassLoader parent;


  public OverridingClassLoader(URL[] urls, ClassLoader parent)
  {
    super(urls, null);
    this.parent = parent;
  }


  @Override
  public Class<?> loadClass(String name) throws ClassNotFoundException
  {
    try
    {
      return super.loadClass(name);
    } catch (Exception e)
    {
      return parent.loadClass(name);
    }
  }


}
复制代码
4 JVM不会关心进程里有多少个ClassLoader实例,也不关心它们从各种途径读出来多少个Class,所以类名相同的Class可以同时存在多个。这会造成一些混乱,比如,假设两个类Person和Student有继承关系,并被一个ClassLoader读进了JVM,然后某个ClassLoader从另一个jar文件又读进来一个Person,这时第一个Student和第二个Person将没有任何关系,instanceof或isAssignableFrom均会返回false;


5 第三方库或框架比如Spring、Hadoop往往会尝试调用Thread.currentThread().getContextClassLoader()来获取ClassLoader为己用,所以你若是想要它们使用你的自定义ClassLoader,记得提前调用Thread.currentThread().setContextClassLoader()把你的ClassLoader设进去。Tomcat就是这么做的,每个webapp的Thread.currentThread().getContextClassLoader()都会返回与该webapp绑定的一个WebappClassLoader实例,所以使用不同jar包的webapp们不会互相影响。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值