使用自定义类加载器和默认类加载器加载两个相同的类

package test.ask;

import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) {
        try{
            Class<?> c1 = Main.class.getClassLoader().loadClass("test.Me");
            Field f = c1.getDeclaredField("i");
            System.out.println(f.get(null));//15
            f.setInt(null, 33);
            System.out.println(f.get(null));//33
            /** 相同的类加载器 */
            Class<?> c2 = Main.class.getClassLoader().loadClass("test.Me");
            f = c2.getDeclaredField("i");
            System.out.println(f.get(null));//33
            
            /** 不同的类加载器,该类加载器会加载java.lang.Object,这时候可以直接用默认加载器 */
            Class<?> c3 = new Load().loadClass("test.Me");
            f = c3.getDeclaredField("i");//i值并输出还是未改变的值
            System.out.println(f.get(null));//15
            
            System.out.println(c3.equals(c1));//false

            System.out.println("c3:"+c3+"\nc1:"+c1); //c3和c1输出相同

        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在一个应用程序中同时加载两个版本的OJDBC驱动是比较困难的,因为Java类加载器默认使用委派模型,即当一个需要被加载时,它首先会请求其父类加载器加载,如果父类加载器无法加载,则由当前类加载器尝试加载。 为了解决这个问题,我们可以使用自定义类加载器加载不同版本的OJDBC驱动。自定义类加载器可以绕过默认的委派模型,从而使得我们可以在同一个应用程序中加载不同版本的。 下面是一个简单的例子,演示如何使用自定义类加载器加载两个版本的OJDBC驱动: ```java import java.net.URL; import java.net.URLClassLoader; public class CustomClassLoader extends URLClassLoader { public CustomClassLoader(URL[] urls, ClassLoader parent) { super(urls, parent); } @Override public Class<?> loadClass(String name) throws ClassNotFoundException { if (name.startsWith("oracle.jdbc.")) { String version = System.getProperty("oracle.jdbc.version"); if (version != null && version.equals("11g")) { return loadClassFromVersion(name, "11g"); } else { return loadClassFromVersion(name, "12c"); } } return super.loadClass(name); } private Class<?> loadClassFromVersion(String name, String version) throws ClassNotFoundException { String className = name.replace(".", "/") + ".class"; URL url = getResource(className.replace(version, "common")); if (url == null) { throw new ClassNotFoundException(name); } byte[] bytes = null; try { bytes = IOUtils.toByteArray(url.openStream()); } catch (IOException e) { throw new ClassNotFoundException(name, e); } return defineClass(name, bytes, 0, bytes.length); } } ``` 在这个自定义类加载器中,我们重写了loadClass方法,并根据系统属性oracle.jdbc.version的值来判断应该加载哪个版本的OJDBC驱动。 如果oracle.jdbc.version的值为11g,则加载11g版本的驱动,否则加载12c版本的驱动。 在loadClass方法中,我们首先判断要加载是否以oracle.jdbc.开头,如果是,则调用loadClassFromVersion方法加载对应版本的。 在loadClassFromVersion方法中,我们首先使用getResource方法获取该对应的URL,然后读取该URL对应的字节码,并使用defineClass方法将该加载到内存中。 最后,我们在应用程序中使用自定义类加载器加载OJDBC驱动: ```java URL[] urls = new URL[] { new URL("file:///path/to/ojdbc11.jar"), new URL("file:///path/to/ojdbc12.jar") }; ClassLoader parent = ClassLoader.getSystemClassLoader(); CustomClassLoader loader = new CustomClassLoader(urls, parent); System.setProperty("oracle.jdbc.version", "11g"); // 设置oracle.jdbc.version属性为11g Class<?> driverClass = loader.loadClass("oracle.jdbc.driver.OracleDriver"); Driver driver = (Driver) driverClass.newInstance(); ``` 在这个例子中,我们首先创建一个CustomClassLoader对象,并将ojdbc11.jar和ojdbc12.jar的URL作为参数传入。 然后,我们设置oracle.jdbc.version属性为11g,并使用CustomClassLoader加载对应版本的OracleDriver,并创建该的实例。 这样,我们就可以在同一个应用程序中同时使用不同版本的OJDBC驱动了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值