本文研究的主要是Java语言中的自定义类加载器实例解析的相关内容,具体如下。
自己写的类加载器
需要注意的是:如果想要对这个实例进行测试的话,首先需要在c盘建立一个c://myjava的目录。然后将相应的java文件放在这个目录中。并将产生的.clas文件放在c://myjava/com/lg.test目录下,否则是找不到的。这是要注意的。。
class FileClassLoader :
package com.lg.test; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; /** * Created by 鏉庢灉 on 2016/8/6. */ public class FileClassLoader extends ClassLoader { String rootDir=null; public FileClassLoader(String rootDir) { this.rootDir = rootDir; } @Override protected Class<?> findClass(String className) throws ClassNotFoundException { //首先检查是否已经被加载了。 Class<?> c = findLoadedClass(className); String path = rootDir + "/" + className.replace('.', '/') + ".class"; if (c != null) { return c; } else { /*双亲委托模式*/ ClassLoader loaderParent = this.getParent(); c = loaderParent.loadClass(className); if (c != null) { return c; } else { /*如果再不行的话,就再进行加载。因为字节码的本质就是一个字节数组*/ InputStream is = null; ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); try { is = new FileInputStream(path); byte[] buffer = new byte[1024]; int len = 0; while ((len = is.read(buffer)) != -1) { outputStream.write(buffer, 0, len); } c = defineClass(className, buffer, 0, buffer.length); } catch (Exception e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } } return c; } } }
class Demo :
package com.lg.test; /** * Created by 鏉庢灉 on 2016/8/6. */ /*相同的类加载器对同一个类进行加载,得到的hascode是相同的 * 不同的类加载器对同一类进行加载,得到的hascode是不一样的*/ public class Demo { public static void main(String[] args) { FileClassLoader loader = new FileClassLoader("c://myjava"); FileClassLoader loader2=new FileClassLoader("c://myjava"); try { Class<?> c = loader.findClass("com.lg.test.HelloWorld"); Class<?> c0=loader.findClass("com.lg.test.HelloWorld"); Class<?> c1=loader2.findClass("com.lg.test.HelloWorld"); Class<?> c2=loader.findClass("com.lg.test.Demo01"); Class<?> c3=loader.findClass("java.lang.String"); System.out.println(c.hashCode()); System.out.println(c.getClassLoader()); System.out.println(c0.hashCode()); System.out.println(c0.getClassLoader()); System.out.println(c1.hashCode()); System.out.println(c1.getClassLoader()); System.out.println(c2.hashCode()); System.out.println(c2.getClassLoader()); System.out.println(c3.hashCode()); System.out.println(c3.getClassLoader()); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
最后运行的结果为:
366712642
sun.misc.Launcher$AppClassLoader@4e0e2f2a
366712642
sun.misc.Launcher$AppClassLoader@4e0e2f2a
366712642
sun.misc.Launcher$AppClassLoader@4e0e2f2a
1829164700
sun.misc.Launcher$AppClassLoader@4e0e2f2a
2018699554
null
如果是定义网络类加载器的话,那么就需要使用URL来进行了。这是要注意的。
可以将rootDie的值变为com.bjsxt.cn. 然后利用Url.openStream()就可以了。
以上就是本文关于Java语言中的自定义类加载器实例解析的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!
本文向大家介绍java 类加载与自定义类加载器详解,包括了java 类加载与自定义类加载器详解的使用技巧和注意事项,需要的朋友参考一下 类加载 所有类加载器,都是ClassLoader的子类。 类加载器永远以.class运行的目录为准。 读取classpath根目录下的文件有以下几种方式: 1 在Java项目中可以通过以下方式获取classspath下的文件: 在Tomcat中tomcat又声明了
18.6 解释器模式总结 解释器模式为自定义语言的设计和实现提供了一种解决方案,它用于定义一组文法规则并通过这组文法规则来解释语言中的句子。虽然解释器模式的使用频率不是特别高,但是它在正则表达式、XML文档解释等领域还是得到了广泛使用。与解释器模式类似,目前还诞生了很多基于抽象语法树的源代码处理工具,例如Eclipse中的Eclipse AST,它可以用于表示Java语言的语法结构,用户可以通过扩
18.5 再谈Context的作用 在解释器模式中,环境类Context用于存储解释器之外的一些全局信息,它通常作为参数被传递到所有表达式的解释方法interpret()中,可以在Context对象中存储和访问表达式解释器的状态,向表达式解释器提供一些全局的、公共的数据,此外还可以在Context中增加一些所有表达式解释器都共有的功能,减轻解释器的职责。 在上面的机器人
18.4 完整解决方案 为了能够解释机器人控制指令,Sunny软件公司开发人员使用解释器模式来设计和实现机器人控制程序。针对五条文法规则,分别提供五个类来实现,其中终结符表达式direction、action和distance对应DirectionNode类、ActionNode类和DistanceNode类,非终结符表达式expression和composite对应SentenceNode类和A
18.3 解释器模式概述 解释器模式是一种使用频率相对较低但学习难度较大的设计模式,它用于描述如何使用面向对象语言构成一个简单的语言解释器。在某些情况下,为了更好地描述某一些特定类型的问题,我们可以创建一种新的语言,这种语言拥有自己的表达式和结构,即文法规则,这些问题的实例将对应为该语言中的句子。此时,可以使用解释器模式来设计这种新的语言。对解释器模式的学习能够加深我们对面向对象思想
18.2 文法规则和抽象语法树 解释器模式描述了如何为简单的语言定义一个文法,如何在该语言中表示一个句子,以及如何解释这些句子。在正式分析解释器模式结构之前,我们先来学习如何表示一个语言的文法规则以及如何构造一棵抽象语法树。 在前面所提到的加法/减法解释器中,每一个输入表达式,例如“1 + 2 + 3 – 4 + 1”,都包含了三个语言单位,可以使用如下文法规则来定义: