关闭

对Java的ClassLoader的几点认识

发表于:2015-10-29 09:58

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:unrealwalker    来源:51Testing软件测试网采编

  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们不会互相影响。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号