类加载器ClassLoader是用来将java的类加载到虚拟机中,类加载器负责读取class字节文件到内存中,并将它转为Class的对象(类对象),通过此实例的 newInstance()
方法就可以创建出该类的一个对象。
其中重要的方法为findClass(String name)。
如何写一个自己的类加载器呢?
首先写一个便于测试的类Student
有一个属性和一个方法
package 类的加载; public class Student { int x; public void setX(int x) { this.x = x; System.out.println(x); } }
写一个自己的类加载器。就是读取class文件,并将其实例化为Class对象的一个过程。
但是必须注意,同一个类如果用不同的加载器对其进行多次加载,会产生异常。所以一旦有一个加载器加载过了就不用再进行加载。
public class MyClassLoder extends ClassLoader { @Override protected Class<?> findClass(String name) throws ClassNotFoundException { Class c = findLoadedClass(name); // 保证加载的唯一性,如果之前已经被加载过了,就不用再加载了。 if (c == null) { byte data[] = readFile(name); c = this.defineClass(data, 0, data.length); this.resolveClass(c);// 将对象c交给虚拟机去管理 System.out.println("加载好了"); } return c; } /** * 读取指定的class文件的字节数据 * * @param name * @return */ public byte[] readFile(String name) { byte[] bt = null; String path = "bin/" + name.replace(".", "/") + ".class"; System.out.println(path); try { FileInputStream fis = new FileInputStream(new File(path)); // // 但是无法确定你会读到多少数据 // byte bt[] = new byte[100]; // fis.read(bt); // 用字节数组流临时存储数据,可以不管其长度 ByteArrayOutputStream baos = new ByteArrayOutputStream(); int t = fis.read(); while (t != -1) { baos.write(t); t = fis.read(); } bt = baos.toByteArray(); fis.close(); } catch (Exception e) { e.printStackTrace(); } return bt; } }
创建一个加载器
MyClassLoder mcl = new MyClassLoder();
得到这个类
Class c = mcl.findClass("类的加载.Student");
同样,进行方法的测试
Method m = c.getMethod("setX", int.class);
Constructor cs = c.getConstructor();
Object obj = cs.newInstance();
m.invoke(obj, 1);
输出结果为
bin/类的加载/Student.class
加载好了
1
在下面再加一个:
Class c2 = mcl.findClass("类的加载.Student");
Method m2 = c2.getMethod("setX", int.class);
Constructor cs2 = c.getConstructor();
Object obj2 = cs2.newInstance();
m2.invoke(obj2, 1);
System.out.println(c==c2);
输出结果为
bin/类的加载/Student.class
加载好了
1
1
true
可以发现都是同一个类
Class c3 = Class.forName("类的加载.Student"); System.out.println(c); System.out.println(c3); Constructor cs3 = c3.getConstructor(); Object obj3 = cs3.newInstance(); System.out.println((Student)obj2);
输出结果为:
class 类的加载.Student
class 类的加载.Student
java.lang.ClassCastException: 类的加载.Student cannot be cast to 类的加载.Student
at 类的加载.Test.main(Test.java:33)
也就是说不能重复对其加载。
相关推荐
java自定义类加载classloader文档,包括代码,以及详细的原理及过程
本篇文章主要介绍了详解Android类加载ClassLoader,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
ClassLoader类加载机制和原理详解
类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一。它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java ...
ClassLoader类加载器讲解,理解JAVA类加载机制
【图解版】深入分析ClassLoader类加载工作机制,从原理到JVM的装载过程,详情分析了ClassLoader加载类以及自定义类加载器的过程,不可用于商业用途,如有版权问题,请联系删除!
ClassLoader的API使用和自定义
java应用程序类加载器(ClassLoader for java Application),类似exe4j, 方便启动java程序, 配置灵活,支持多平台选择性配置
如果户创建的JAR放在此录下,也会动由扩展类加载器加载.应程序类加载器(系统类加载器,Application ClassLoader)java语编写,由sun.
NULL 博文链接:https://shulianghan.iteye.com/blog/1699341
Java的类加载机制:加载,连接,初始化。JAVA类加载器: Bootstrap ClassLoader : 根类加载器, Extension ClassLoader: 扩展类加载器, System ClassLoader : 系统类加载器, Java反射
NULL 博文链接:https://yjhexy.iteye.com/blog/668334
下面小编就为大家带来一篇classloader类加载器_基于java类的加载方式详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
1. ClassLoader(类加载机制) 3. findLoadedClass (查找JVM已经加载过的类) 4. defineClass (定义一个Java
jvm运行的过程中,需要载入类,而类的加载需要类加载器,本文章提供了java的类加载器的工作原理。可以使读者更加理解jvm的运行机制。
该电子书详细介绍了java虚拟机类加载机制,对于深入理解jvm工作原理有很好的帮助作用,对于初学java,有一定工作经验的小伙伴来说是一本提高自身java素养,夯实自己java基本技能的“葵花宝典”。
本篇文章主要给大家讲述了Java中ClassLoader类加载的原理以及用法总结,一起学习下。
类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一。它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java ...
主要介绍了Java类加载器ClassLoader用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下