在普通的Main程序中,
某个类是被哪个加载器所加载的?
print(String.class.getClassLoader()); //打印null, 这在HotSpot里代表Bootstrap ClassLoader,它负责加载$JAVA_HOME/lib里的类库 print(List.class.getClassLoader()); // 同上 print(learn.classloader.WhoLoadsMe.class.getClassLoader()); // 打印sun.misc.Launcher$AppClassLoader,它在HotSpot里代表System Class Loader, 负责加载用户类路径上的类库 print(learn.classloader.Friend.class.getClassLoader()); //同上 //看看sun.misc.Launcher$AppClassLoader的父加载器和祖父加载器是哪些 print(learn.classloader.Friend.class.getClassLoader().getParent()); //打印sun.misc.Launcher$ExtClassLoader,它在HotSpot里用于加载$JAVA_HOME/lib/ext下的类库 print(learn.classloader.Friend.class.getClassLoader().getParent().getParent()); //打印null, 即Bootstrap ClassLoader Class<?> remoteFriendClass = new learn.classloader.RemoteClassLoader().loadClass( "learn.classloader.RemoteFriend"); print(remoteFriendClass.getClassLoader()); //打印 learn.classloader.RemoteClassLoader,即自写的class loader(后文有这个class loader的代码) //看看自写加载器的父加载器是哪个 print(remoteFriendClass.getClassLoader().getParent()); //打印sun.misc.Launcher$AppClassLoader,即System ClassLoader print(remoteFriendClass.getField("friendOfFriend").getType() .getClassLoader()); //同上, 这意味着在"RemoteFriend"里直接引用的类(后文附上了代码描述这个引用)是由RemoteFriend的加载器所加载的 //最后看下context class loader print(Thread.currentThread().getContextClassLoader()); //打印sun.misc.Launcher$AppClassLoader,即system classloader
附:
RemoteClassLoader
package learn.classloader; public class RemoteClassLoader extends ClassLoader { @Override public Class<?> loadClass(String name) throws ClassNotFoundException { Class<?> clazz = findLoadedClass(name); if (clazz != null) { return clazz; } clazz = letParentLoad(name); if (clazz != null) { return clazz; } String classDir = "/home/kent/another-project/classes/"; String classFile = classDir + name.replaceAll("\\.", "\\/") + ".class"; byte[] bytes = readToBytes(classFile); return defineClass(name, bytes, 0, bytes.length); } ... }
附:
RemoteFriend类里的FriendOfFriend
package learn.classloader; public class RemoteFriend { public static FriendOfFriend friendOfFriend = new FriendOfFriend(); }