- 类加载器只能加载.class文件,或者是jar包文件
- 通过本次实践发现,两个相同全类名的类(jar包里面存在相同的类),编译后只保留一个
目录结构
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/e460ce6e115403a071fdec17293fceae.png)
自定义加载类
import java.net.URL;
import java.net.URLClassLoader;
public class TestClassLoader extends URLClassLoader {
public TestClassLoader(URL[] urls) {
super(urls);
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
synchronized (getClassLoadingLock(name)) {
Class<?> c = findLoadedClass(name);
if (c == null) {
try {
c = findClass(name);
} catch (ClassNotFoundException e) {
}
}
ClassLoader parent;
if (c == null && (parent = this.getParent()) != null) {
c = parent.loadClass(name);
}
return c;
}
}
}
测试
import java.lang.reflect.Field;
import java.net.*;
import java.util.Arrays;
public class TestMain {
public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, IllegalAccessException {
URL url = new URL("file:/D:/file/JavaWeb/program/demo_practice/out/production/demo_practice/");
URL[] urls = new URL[]{url};
ClassLoader loaderOne = TestMain.class.getClassLoader();
ClassLoader loaderTwo = new TestClassLoader(urls);
ClassLoader loaderThree = new TestClassLoaderTwo(urls);
printArrayUtilsFieldValue(loaderOne,false,"");
printArrayUtilsFieldValue(loaderTwo,true,"2222");
printArrayUtilsFieldValue(loaderThree,true,"22223");
System.out.println("loaderOne值:" + getValue(loaderOne));
System.out.println("loaderTwo值:" + getValue(loaderTwo));
System.out.println("loaderThree值:" + getValue(loaderThree));
}
public static String getValue(ClassLoader classLoader) throws ClassNotFoundException, IllegalAccessException {
Class<?> aClass = classLoader.loadClass("org.apache.commons.lang.ArrayUtils");
Field[] fields = aClass.getFields();
for (Field field : fields) {
Object o = field.get(aClass);
if (o instanceof String[]){
String[] strs = (String[]) o;
return Arrays.toString(strs);
}
}
return null;
}
public static void printArrayUtilsFieldValue(ClassLoader classLoader, boolean isModify,String modifyValue) throws ClassNotFoundException, IllegalAccessException {
System.out.println("当前类加载器:" + classLoader);
ClassLoader parent = classLoader.getParent();
System.out.println("父类加载器:" + parent);
Class<?> arrayUtils = classLoader.loadClass("org.apache.commons.lang.ArrayUtils");
Field[] fields = arrayUtils.getFields();
for (Field field : fields) {
Object o = field.get(arrayUtils);
if (o instanceof String[]){
String[] strs = (String[]) o;
System.out.println(Arrays.toString(strs));
if (isModify){
String[] temp = new String[]{modifyValue};
field.set(arrayUtils,temp);
o = field.get(arrayUtils);
if (o instanceof String[]){
strs = (String[]) o;
System.out.println("修改后:" + Arrays.toString(strs));
}
}
}
}
System.out.println("=======");
}
}
输出结果
当前类加载器:sun.misc.Launcher$AppClassLoader@18b4aac2
父类加载器:sun.misc.Launcher$ExtClassLoader@7f31245a
[123]
=======
当前类加载器:day1120.TestClassLoader@330bedb4
父类加载器:sun.misc.Launcher$AppClassLoader@18b4aac2
[123]
修改后:[2222]
=======
当前类加载器:day1120.TestClassLoaderTwo@7ea987ac
父类加载器:sun.misc.Launcher$AppClassLoader@18b4aac2
[123]
修改后:[22223]
=======
loaderOne值:[123]
loaderTwo值:[2222]
loaderThree值:[22223]