java ClassLoader

测试代码:

package com.lang;

import junit.framework.TestCase;

public class TestClassLoader extends TestCase {

	public void testClassLoader1() {
		ClassLoader cl = TestClassLoader.class.getClassLoader();
		while (cl != null) {
			System.out.println(cl);
			cl = cl.getParent();
		}
	}

	public void testClassLoader2() {
		ClassLoader cl = TestClassLoader.class.getClassLoader();
		try {
			Class<?> clazz = cl.loadClass(TestClassLoader.class.getName() + "$User");
			User user = (User) clazz.newInstance();
			user.setAge(10);
			user.setName("yang");
			System.out.println(user);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}

	static class User {
		private int age;
		private String name;

		public int getAge() {
			return age;
		}

		public void setAge(int age) {
			this.age = age;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		@Override
		public String toString() {
			return "User [age=" + age + ", name=" + name + "]";
		}
	}
}

运行testClassLoader1,输出:

sun.misc.Launcher$AppClassLoader@192d342
sun.misc.Launcher$ExtClassLoader@6b97fd

运行testClassLoader2,输出:

User [age=10, name=yang]

一个类是如何加载的,看loadClass的代码:

    public Class<?> loadClass(String name) throws ClassNotFoundException {
	    return loadClass(name, false);
    }

    protected synchronized Class<?> loadClass(String name, boolean resolve)
	throws ClassNotFoundException
    {
	// First, check if the class has already been loaded
	Class c = findLoadedClass(name);
	if (c == null) {
	    try {
		if (parent != null) {
		    c = parent.loadClass(name, false);
		} else {
		    c = findBootstrapClassOrNull(name);
		}
	    } catch (ClassNotFoundException e) {
                // ClassNotFoundException thrown if class not found
                // from the non-null parent class loader
            }
            if (c == null) {
	        // If still not found, then invoke findClass in order
	        // to find the class.
	        c = findClass(name);
	    }
	}
	if (resolve) {
	    resolveClass(c);
	}
	return c;
    }

private ClassLoader parent;

其实,就是先判断一下这个类是否已经被加载过了,如果已经加载,就直接返回。

如果还未被加载,就让上级的ClassLoader去加载,一级一级递归让上级去加载。

最底下的是sun.misc.Launcher$AppClassLoader,上级是sun.misc.Launcher$ExtClassLoader,再上级就是null了,

null最后由findBootstrapClassOrNull来加载。

    private Class findBootstrapClassOrNull(String name)
    {
        if (!checkName(name)) return null;

        return findBootstrapClass(name);
    }

    // return null if not found
    private native Class findBootstrapClass(String name);

findBootstrapClass是个native的方法,是由C++写的。

如果还是没找到,就调用findClass。

    protected Class<?> findClass(String name) throws ClassNotFoundException {
	        throw new ClassNotFoundException(name);
    }

这个方法,在子类里面进行实现。

jdk提供了很多ClassLoader,如图:



你可能感兴趣的:(java ClassLoader)