测试代码:

 class Hello
{
  public String str = "Hello World";
  public void fun()
  {
    System.out.println(str);
7   }
} public class Test{
  public static void main(String[] args)
  {
    Hello hello = new Hello();
    hello.fun();     System.out.println("----------------------");     //Hello类的类加载器
    ClassLoader classLoaderOfHello = Hello.class.getClassLoader();     System.out.println("Hello is Loaded by : "+classLoaderOfHello); 24     System.out.println("----------------------");     //Hello类的类加载器的Class对象
    Class AppClazz = classLoaderOfHello.getClass();     //分析Hello类的类加载器的Class对象的类继承关系
    while(AppClazz != null)
31     {
    System.out.println(AppClazz); 34     AppClazz = AppClazz.getSuperclass();
35     }     System.out.println("----------------------");     //取得扩展器加载器的类对象Class
    Class ExtClazz = classLoaderOfHello.getParent().getClass();     while(ExtClazz != null)
    {
    System.out.println(ExtClazz);     ExtClazz = ExtClazz.getSuperclass();
    }
  }
}

结论:

1.  用户自定义的类是由 应用(系统)类加载器AppClassLoader加载

2.  在”父亲委托机制”中,扩展类加载器ExtClassLoader是AppClassLoader的父亲,并不是继承关系,而是ExtClassLoader加载了AppClassLoader

3.  AppClassLoader 和 ExtClassLoader 都扩展于 URLClassLoader加载器.

4.  也同时说明AppClassLoader而非继承ExtClassLoader.

继承关系:

java.lang.Object

--- java.lang.ClassLoader
              --- java.security.SecureClassLoader
                      ---  java.net.URLClassLoader
                            --- sun.misc.Launcher$ExtClassLoader

java.lang.Object

--- java.lang.ClassLoader
              --- java.security.SecureClassLoader
                      ---  java.net.URLClassLoader
                            --- sun.misc.Launcher$AppClassLoader

其实很简单嘛,直接看AppClassLoader的源代码就可以了嘛,哈哈,终于找到了好东东,上

JDK7: http://download.java.net/openjdk/jdk7/

JDK6: http://download.java.net/openjdk/jdk6/

下载其源代码就可以了

现在直接来看其源代码:

/**
* The class loader used for loading from java.class.path.
* runs in a restricted security context.
*/
static class AppClassLoader extends URLClassLoader {

static {
ClassLoader.registerAsParallelCapable();
}

public static ClassLoader getAppClassLoader(final ClassLoader extcl)
throws IOException
{
final String s = System.getProperty("java.class.path");
final File[] path = (s == null) ? new File[0] : getClassPath(s);

return AccessController.doPrivileged(
new PrivilegedAction<AppClassLoader>() {
public AppClassLoader run() {
URL[] urls =
(s == null) ? new URL[0] : pathToURLs(path);
return new AppClassLoader(urls, extcl);
}
});
}

/*
* Creates a new AppClassLoader
*/
AppClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent, factory);
}

/**
* Override loadClass so we can checkPackageAccess.
*/
public Class loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
int i = name.lastIndexOf('.');
if (i != -1) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPackageAccess(name.substring(0, i));
}
}
return (super.loadClass(name, resolve));
}

/**
* allow any classes loaded from classpath to exit the VM.
*/
protected PermissionCollection getPermissions(CodeSource codesource)
{
PermissionCollection perms = super.getPermissions(codesource);
perms.add(new RuntimePermission("exitVM"));
return perms;
}

/**
* This class loader supports dynamic additions to the class path
* at runtime.
*
* @see java.lang.instrument.Instrumentation#appendToSystemClassPathSearch
*/
private void appendToClassPathForInstrumentation(String path) {
assert(Thread.holdsLock(this));

// addURL is a no-op if path already contains the URL
super.addURL( getFileURL(new File(path)) );
}

/**
* create a context that can read any directories (recursively)
* mentioned in the class path. In the case of a jar, it has to
* be the directory containing the jar, not just the jar, as jar
* files might refer to other jar files.
*/

private static AccessControlContext getContext(File[] cp)
throws java.net.MalformedURLException
{
PathPermissions perms =
new PathPermissions(cp);

ProtectionDomain domain =
new ProtectionDomain(new CodeSource(perms.getCodeBase(),
(java.security.cert.Certificate[]) null),
perms);

AccessControlContext acc =
new AccessControlContext(new ProtectionDomain[] { domain });

return acc;
}
}

哈,看了AppClassLoader的源代码后,大家明白了吧,AppClassLoader 继承了URLClassLoader,而且构造函数是直接调用URLClassLoader的构造

函数,loadClass(String name, boolean resolve)方法只是简单做了包的安全检查,然后就调用ClassLoader的 loadClass(String name, boolean resolve)方法了,其它的话,也是差不多..所以其功能和URLClassLoader差不多...

在ExtClassLoader也差不多,大家看看源代码就明了的:

/*
* Creates a new ExtClassLoader for the specified directories.
*/
public ExtClassLoader(File[] dirs) throws IOException {
super(getExtURLs(dirs), null, factory);
}

private static File[] getExtDirs() {
String s = System.getProperty("java.ext.dirs");
File[] dirs;
if (s != null) {
StringTokenizer st =
new StringTokenizer(s, File.pathSeparator);
int count = st.countTokens();
dirs = new File[count];
for (int i = 0; i < count; i++) {
dirs[i] = new File(st.nextToken());
}
} else {
dirs = new File[0];
}
return dirs;
}

private static URL[] getExtURLs(File[] dirs) throws IOException {
Vector<URL> urls = new Vector<URL>();
for (int i = 0; i < dirs.length; i++) {
String[] files = dirs[i].list();
if (files != null) {
for (int j = 0; j < files.length; j++) {
if (!files[j].equals("meta-index")) {
File f = new File(dirs[i], files[j]);
urls.add(getFileURL(f));
}
}
}
}
URL[] ua = new URL[urls.size()];
urls.copyInto(ua);
return ua;
}

/*
* Searches the installed extension directories for the specified
* library name. For each extension directory, we first look for
* the native library in the subdirectory whose name is the value
* of the system property <code>os.arch</code>. Failing that, we
* look in the extension directory itself.
*/
public String findLibrary(String name) {
name = System.mapLibraryName(name);
URL[] urls = super.getURLs();
File prevDir = null;
for (int i = 0; i < urls.length; i++) {
// Get the ext directory from the URL
File dir = new File(urls[i].getPath()).getParentFile();
if (dir != null && !dir.equals(prevDir)) {
// Look in architecture-specific subdirectory first
// Read from the saved system properties to avoid deadlock
String arch = VM.getSavedProperty("os.arch");
if (arch != null) {
File file = new File(new File(dir, arch), name);
if (file.exists()) {
return file.getAbsolutePath();
}
}
// Then check the extension directory
File file = new File(dir, name);
if (file.exists()) {
return file.getAbsolutePath();
}
}
prevDir = dir;
}
return null;
}

private static AccessControlContext getContext(File[] dirs)
throws IOException
{
PathPermissions perms =
new PathPermissions(dirs);

ProtectionDomain domain = new ProtectionDomain(
new CodeSource(perms.getCodeBase(),
(java.security.cert.Certificate[]) null),
perms);

AccessControlContext acc =
new AccessControlContext(new ProtectionDomain[] { domain });

return acc;
}
}

---------------------
作者:irelandken
来源:CSDN
原文:https://blog.csdn.net/irelandken/article/details/7046689
版权声明:本文为博主原创文章,转载请附上博文链接!

最新文章

  1. BZOJ 4518 征途
  2. 差分:IncDec Sequence 差分数组
  3. CodeSmith连接Oracle
  4. AD 10 原理图编译错误
  5. python面向对象编程(下)
  6. MyBatis与Hibernate对比
  7. bzoj 3437 斜率优化DP
  8. 微软Office与金山WPS Office有何私密关系?
  9. 虚拟机迁移(QEMU动态迁移,Libvirt动(静)态迁移)
  10. 推荐eclipse插件Properties Editor(转)
  11. Ibatis和Hibernate的比较
  12. Django系列之web应用与http协议
  13. 完整卸载 kUbuntu-desktop from Ubuntu 14.04 LTS系统 ubuntu14.04 LTS 64Bit
  14. Java枚举的小知识点
  15. Go sql insert update使用举例
  16. PHP 协程最简洁的讲解
  17. js switch case注意事项
  18. Swagger本地环境配置
  19. sampleFactory(女娲造人)
  20. NHibernate初学四之关联一对一关系

热门文章

  1. grep/sed/awk命令查看指定时间段的日志
  2. Java代码手段防止非法请求——防盗链
  3. C++中局部变量的返回
  4. eclipse怎么debug项目
  5. python使用selenium驱动chromium防止浏览器自动升级失效!
  6. Mysql多实例数据库安装应用
  7. HttpModule介绍
  8. ProgressTimer 控件
  9. ❀❀ selenium 学习网站 ★★★★★
  10. 记录 shell学习过程(9)正则表达式 转自树明聊运维