测试代码:
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 + "]"; } } }
sun.misc.Launcher$AppClassLoader@192d342 sun.misc.Launcher$ExtClassLoader@6b97fd
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,如图: