本文目录一览:
- 1、Java:如何编写自己的Java类加载器
- 2、java中class类中一个class对象获取的类加载器在何
- 3、曲靖java培训学校告诉你Java类加载机制?
- 4、java中类加载器是怎么工作的
- 5、java类加载器有几种???
- 6、北大青鸟java培训:Tomcat的类加载器架构?
Java:如何编写自己的Java类加载器
给你简单介绍一下类加载器
1.类加载器就加载字节码文件(.class)
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; } }
}
/*
相同的类加载器对同一个类进行加载,得到的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(); } }}
java中class类中一个class对象获取的类加载器在何
lang包。在java这个编译语言中,class类中的一个class对象,其获取的类加载器就位于lang包中,Java是一种面向对象的语言。
曲靖java培训学校告诉你Java类加载机制?
每个开发人员对java.lang.ClassNotFoundExcetpion这个异常肯定都不陌生,这背后就涉及到了java技术体系中的类加载。Java的类加载机制是技术体系中比较核心的部分,虽然和大部分开发人员直接打交道不多,但是对其背后的机理有一定理解有助于排查程序中出现的类加载失败等技术问题,对理解java虚拟机的连接模型和java语言的动态性都有很大帮助。电脑培训就得好好的为大家介绍一下。
那么什么是类的加载?
类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。
Java类加载机制
类加载器是Java语言的一个创新,也是Java语言流行的重要原因之一。它使得Java类可以被动态加载到Java虚拟机中并执行。类加载器从JDK1.0就出现了,最初是为了满足JavaApplet的需要而开发出来的。JavaApplet需要从远程下载Java类文件到浏览器中并执行。现在类加载器在Web容器和OSGi中得到了广泛的使用,而类加载器并不需要等到某个类被“首次主动使用”时再加载它,JVM规范允许类加载器在预料某个类将要被使用时就预先加载它,如果在预先加载的过程中遇到了.class文件缺失或存在错误,类加载器必须在程序首次主动使用该类时才报告错误(LinkageError错误)如果这个类一直没有被程序主动使用,那么类加载器就不会报告错误。
类的生命周期
类加载的过程中包括有加载,验证,准备,解析,初始化五个阶段。而需要注意的是在这五个阶段中,加载、验证、准备和初始化这四个阶段发生的顺序是确定的,而解析阶段则不一定,它在某些情况下可以在初始化阶段之后开始,这是为了支持Java语言的运行时绑定(也成为动态绑定或晚期绑定)。另外注意这里的几个阶段是按顺序开始,而不是按顺序进行或完成,因为这些阶段通常都是互相交叉地混合进行的,通常在一个阶段执行的过程中调用或激活另一个阶段。
java中类加载器是怎么工作的
JVM将类加载过程分为三个步骤:装载(Load),链接(Link)和初始化(Initialize)
链接又分为三个步骤,验证、准备、解析
1) 装载:查找并加载类的二进制数据;
2)链接:
验证:确保被加载类的正确性;
准备:为类的静态变量分配内存,并将其初始化为默认值;
解析:把类中的符号引用转换为直接引用;
3)初始化:为类的静态变量赋予正确的初始值;
那为什么我要有验证这一步骤呢?首先如果由编译器生成的class文件,它肯定是符合JVM字节码格式的,但是万一有高手自己写一个class文件,让JVM加载并运行,用于恶意用途,就不妙了,因此这个class文件要先过验证这一关,不符合的话不会让它继续执行的,也是为了安全考虑吧。
准备阶段和初始化阶段看似有点牟盾,其实是不牟盾的,如果类中有语句:private static int a = 10,它的执行过程是这样的,首先字节码文件被加载到内存后,先进行链接的验证这一步骤,验证通过后准备阶段,给a分配内存,因为变量a是static的,所以此时a等于int类型的默认初始值0,即a=0,然后到解析(后面在说),到初始化这一步骤时,才把a的真正的值10赋给a,此时
java类加载器有几种???
Java中加载器的种类大致可以分为四种:Bootstrap ClassLoader(由C++语言写成),系统加载器(也就是内部类AppClassLoader),ExtClassLoader,以及java.net.UrlClassLoader.
当我们运行一个程序时,首先是找到JDK安装目下的jvm.dll来启动JAVA虚拟机,而后Bootstrap ClassLoader产生,接下来就是Bootstrap ClassLoader来加载ExtClassLoader,并且指定ExtClassLoader的父加载器为Bootstrap ClassLoader,但是因为Bootstrap ClassLoader用C++语言写的,所以用JAVA的观点来看,这个加载器的实例是不存在的,所以ExtClassLoader的父加载器被设置为了null,然后就是Bootstrap ClassLoader将AppClassLoader装载,并指定其父加载器为ExtClassLoader。
JAVA是按照加载器的委派模型来实现的。这种模型是JAVA安全性机制的保证。并且值得我们注意的就是这几个加载器的默认加载类的路径。对于AppCLassLoder来说,它的路径也就是我们的classpath里面的路径。而对于ExtClassLoader来说,它的路径是jre\lib\ext\classes.对于URLClassLoader来说,它的加载路径是我们指定的url。
北大青鸟java培训:Tomcat的类加载器架构?
主流的Web服务器(也就是Web容器),如Tomcat、Jetty、WebLogic、WebSphere或其他笔者没有列举的服务器,都实现了自己定义的类加载器(一般都不止一个)。
因为一个功能健全的Web容器,要解决如下几个问题:1)部署在同一个Web容器上的两个Web应用程序所使用的类库可以实现相互隔离。
这是最基本的需求,两个不同的应用程序可能会依赖同一个第三方类库的不同版本,不能要求一个类库在一个服务器中只有一份,服务器应当保证两个应用程序的类库可以互相独立使用。
2)部署在同一个Web容器上的两个Web应用程序所使用的类库可以互相共享。
这个需求也很常见,例如,用户可能有10个使用Spring组织的应用程序部署在同一台服务器上,如果把10份Spring分别存放在各个应用程序的隔离目录中,将会是很大的资源浪费——这主要倒不是浪费磁盘空间的问题,而是指类库在使用时都要被加载到Web容器的内存,如果类库不能共享,虚拟机的方法区就会很容易出现过度膨胀的风险。
3)Web容器需要尽可能地保证自身的安全不受部署的Web应用程序影响。
目前,有许多主流的Web容器自身也是使用语言来实现的。
因此,Web容器本身也有类库依赖的问题,一般来说,基于安全考虑,容器所使用的类库应该与应用程序的类库互相独立。
4)支持JSP应用的Web容器,大多数都需要支持HotSwap功能。
我们知道,JSP文件最终要编译成Class才能由虚拟机执行,但JSP文件由于其纯文本存储的特性,运行时修改的概率远远大于第三方类库或程序自身的Class文件。
而且ASP、PHP和JSP这些网页应用也把修改后无须重启作为一个很大的“优势”来看待,因此“主流”的Web容器都会支持JSP生成类的热替换,当然也有“非主流”的,如运行在生产模式(ProductionMode)下的WebLogic服务器默认就不会处理JSP文件的变化。
由于存在上述问题,在部署Web应用时,单独的一个ClassPath就无法满足需求了,所以各种Web容都“不约而同”地提供了好几个ClassPath路径供用户存放第三方类库,这些路径一般都以“lib”或“classes”命名。
被放置到不同路径中的类库,河南电脑培训认为具备不同的访问范围和服务对象,通常,每一个目录都会有一个相应的自定义类加载器去加载放置在里面的类库。
现在,就以Tomcat容器为例,看一看Tomcat具体是如何规划用户类库结构和类加载器的。