类加载器[4]由不同ClassLoader对象加载的同名类属于不同类
2017-03-06 15:49
239 查看
由不同ClassLoader对象加载的同名类属于不同的类型,不能相互转化和兼容。
新建一个工程NotSameClass。将如下代码,一份放入NoSameClass工程源代码目录下,一份编译成.class放入D:\temp目录下
运行如下代码,使用不同的类加载器加载同一个类(源代码都一样,不过一个来自bin目下的.class,一个来自D:\temp下的.class)
Java Code
package com.bjsxt.test; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Test { public static void main(String[] args) { //先用应用类加载器加载HelloLoader HelloLoader object1=new HelloLoader(); System.out.println(object1.getClass().getClassLoader()); //再用扩展类加载器加载HelloLoader ClassLoader cl = ClassLoader.getSystemClassLoader(); try { byte[] classBytes = loadClassBytes("com.bjsxt.test.HelloLoader"); Method defineClassMethod = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); defineClassMethod.setAccessible(true); defineClassMethod.invoke(cl.getParent(), classBytes, 0, classBytes.length); Class<?> clazz = cl.getParent().loadClass("com.bjsxt.test.HelloLoader"); System.out.println(clazz.getClassLoader()); //两个不同类的对象强制类型转换 object1=(HelloLoader)clazz.newInstance(); } catch (ClassNotFoundException e) { e.printStackTrace(); }catch (SecurityException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } /** * 将包名中的.替换成路径分隔符,从D:/temp/目录下查找这个文件,如果存在的话,将其读取到字节数组 * @param name * @return */ public static byte[] loadClassBytes(java.lang.String name) { String path="D:/temp/"+name.replace(".", "/")+".class"; InputStream is=null; ByteArrayOutputStream baos=null; try { is=new FileInputStream(path); baos=new ByteArrayOutputStream(); byte[] buffer=new byte[1024]; int ret=0; while((ret=is.read(buffer))!=-1){ baos.write(buffer, 0, ret); } return baos.toByteArray(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ try { if(is!=null) is.close(); if(baos!=null) baos.close(); } catch (IOException e) { e.printStackTrace(); } } return null; } } |
并且,即便是同一类 类加载器,不同的对象加载出来的类也不是同一个类。
相关文章推荐
- 在不同的classloader之间进行对象的序列化和反序列化
- Java ClassLoader基础及加载不同依赖 Jar 中的公共类
- 不同jar包相同同名类--Classloader.getResource--slf4j原理
- Java ClassLoader基础及加载不同依赖 Jar 中的公共类
- Java ClassLoader基础及加载不同依赖 Jar 中的公共类
- Java ClassLoader基础及加载不同依赖 Jar 中的公共类
- 同一个java类由不同的classloader加载问题
- 深入类加载器-类加载器作用,类缓存、类加载器的层次结构、ClassLoader类介绍、代理模式之双亲委派机制
- 单例 变 多例--多ClassLoader实例加载
- 利用URLClassLoader加载class到当前线程
- Java ClassLoader 类加载器
- JVM类加载机制-ClassLoader
- ClassLoader的几个概念、类和对象的解释
- 使用反射+缓存+委托,实现一个不同对象之间同名同类型属性值的快速拷贝
- JVM类加载机制(ClassLoader)源码解析
- ClassLoader的加载顺序
- ClassLoader如何加载class
- 【转载】<实战> 分析PermGen上存放的被Classloader所加载的类实践
- classloader加载class的流程及自定义ClassLoader
- Tomcat类加载原理(WebappClassLoader)