利用URLClassLoader解决类名冲突

  • 类加载器只能加载.class文件,或者是jar包文件
  • 通过本次实践发现,两个相同全类名的类(jar包里面存在相同的类),编译后只保留一个

目录结构

在这里插入图片描述

自定义加载类


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) {
                    //防止上步骤 findClass报错在控制台上抛出异常
                }
            }
            //上述步骤都没有找到的话交给“父类”加载
            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/");//class文件存放位置
        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));
    }

    /**
     * 获取ArrayUtils类中静态变量的值
     * @param classLoader
     * @return
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     */
    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;
    }

    /**
     * 打印ArrayUtils类中的静态变量的值并修改
     * @param classLoader
     * @param isModify 是否修改
     * @param modifyValue 修改值
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     */
    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]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值