- 浏览: 578856 次
- 性别:
- 来自: 南京
文章分类
- 全部博客 (214)
- web (36)
- oracle (10)
- http (1)
- 设计 (2)
- 项目 (1)
- 方法论 (0)
- 需求 (0)
- 成长 (6)
- 工作日志 (0)
- java基础 (20)
- java线程 (2)
- CMMI (0)
- Ext (19)
- JavaScript (16)
- OpenGL (0)
- 我的管理 (3)
- 敏捷 (0)
- mysql (7)
- 其他 (3)
- tools (10)
- 3d (1)
- 音视频直播 (9)
- C++ (1)
- 测试 (3)
- 开源 (3)
- css (4)
- 安全 (1)
- 项目管理 (1)
- NoSql (1)
- 文件系统 (1)
- cache (2)
- easyui (1)
- 3G (1)
- 单点登录 (1)
- portal (2)
- 问题 (0)
- ORM (0)
- 视频教程 (1)
- 电子书 (1)
- 规范 (2)
- spring (5)
- xml (0)
- ibatis (1)
- struts (2)
- 面试 (6)
- svn (0)
- 自考 (1)
- tomcat (3)
- html (1)
- jmesa Grid 组件 (1)
- 日志 (0)
- Jquery (1)
- os (1)
- books (0)
- download (0)
最新评论
-
remoteJavaSky:
弱弱的问一下,关于那个登录,登录后服务端会给客户端一个sess ...
Java Session 是如何实现的 -
jiangshuiy:
2中的报错是因为的源码有 package,而你的命令里面没有p ...
javac、java命令的使用 -
yanwushu:
简介明了,好文章......
ServletContext -
516456267:
第四个说明很有用
对log4j的ConversionPattern的学习 -
meShare2011:
加载顺序是先加载Tomcat Lib文件夹下的Jar包对么? ...
(转)jar not loaded. See Servlet Spec 2.3, section 9.7.2. 错误原因和解决办法
该文章来源于网上,如果侵权请留言。
这篇文章将比较深入的介绍java类加载原理和过程,虽然很多情况你都不需要了解类加载的过程,但是如果你希望了解java是如何工作的,或者希望定义自己的类加载器,就一定要了解类加载的过程,当然,无论你是否要参与类加载过程,了解这个过程对你都会有很大的帮助。本文希望通过一步一步的分析来说明类加载的过程,希望这种分析方法也会对你有某些帮助。本文使用的JDK是sun的jdk_1.4.2版本,当然这里重在阐述原理,和JDK本身没有多大的关系。这篇文章试图解决下面一些问题:类加载原理引导类加载器,扩展类加载器和系统类加载器如果知道某个类是哪个类加载器加载的如果得到系统类加载器加载了那些类首先我们要分析类加载原理,java中默认有三种类加载器:引导类加载器,扩展类加载器,系统类加载器(也叫应用类加载器)
引导类加载器负责加载jdk中的系统类,这种类加载器都是用c语言实现的,在java程序中没有办法获得这个类加载器,对于java程序是一个概念而已,基本上不用考虑它的存在,像String,Integer这样的类都是由引导类加载器加载器的.
扩展类加载器负责加载标准扩展类,一般使用java实现,这是一个真正的java类加载器,负责加载jre/lib/ext中的类,和普通的类加载器一样,其实这个类加载器对我们来说也不是很重要,我们可以通过java程序获得这个类加载器。
系统类加载器,加载第一个应用类的加载器(其实这个定义并不准确,下面你将会看到),也就是执行java MainClass 时加载MainClass的加载器,这个加载器使用java实现,使用的很广泛,负责加载classpath中指定的类。
类加载器之间有一定的关系(父子关系),我们可以认为扩展类加载器的父加载器是引导类加载器(当然不这样认为也是可以的,因为引导类加载器表现在java中就是一个null),不过系统类加载器的父加载器一定是扩展类加载器,类加载器在加载类的时候会先给父加载器一个机会,只有父加载器无法加载时才会自己去加载。我们无法获得引导类加载器,因为它是使用c实现的,而且使用引导类加载器加载的类通过getClassLoader方法返回的是null.所以无法直接操作引导类加载器,但是我们可以根据Class.getClassLoader方法是否为null判断这个类是不是引导类加载器加载的,可以通过下面的方法获得引导类加载器加载的类路径(每个jar包或者文件夹对应了一个URL);
sun.misc.Launcher.getBootstrapClassPath().getURLs()你可以直接在你的main函数中输出就可以了System.out.println(java.util.Arrays.asList(sun.misc.Launcher.getBootstrapClassPath().getURLs()).toString());
得到的结果是:[file:/C:/Program%20Files/Java/j2re1.4.2_10/lib/rt.jar, file:/C:/Program%20Files/Java/j2re1.4.2_10/lib/i18n.jar, file:/C:/Program%20Files/Java/j2re1.4.2_10/lib/sunrsasign.jar, file:/C:/Program%20Files/Java/j2re1.4.2_10/lib/jsse.jar, file:/C:/Program%20Files/Java/j2re1.4.2_10/lib/jce.jar, file:/C:/Program%20Files/Java/j2re1.4.2_10/lib/charsets.jar, file:/C:/Program%20Files/Java/j2re1.4.2_10/classes]
其实我们是可以指定引导类加载器的类路径的,java提供了一个-Xbootclasspath参数,不过这个参数不是标准参数。
java -Xbootclasspath: 运行时指定引导类加载器的加载路径(jar文件或者目录)java -Xbootclasspath/p:和上面的相同,不过把这个路径放到原来的路径前面java -Xbootclasspath/a:这个就是在原引导类路径后面添加类路径。上面我们有提过加载第一个应用类未必就是系统加载器。如果我把这个应用类的路径放到引导类路径中,它将会被引导类加载器加载,大致这样java -Xbootclasspath/a:myjar.jar MainClass如果MainClass在myjar.jar中,那么这个类将会被引导类加载器加载。如果希望看详情,使用-verbose参数,为了看的更清楚,使用重定向,大致为(windows下):
java -verbose -Xbootclasspath/a:myjar.jar MainClass -> C:\out.txt
通过这个参数我们可以实现自己的系统类,比如替换掉java.lang.Object的实现,自己可以扩展一些方法,不过这样做似乎没有好处,因为那就不是标准了。
我们最关心的还是系统类加载器,一般都认为系统类加载器是加载应用程序第一个类的加载器,也就是java MainClass命令中加载MainClass的类加载器,这种说法虽然不是很严谨,但基本上还是可以这样认为的,因为我们很少会改变引导类加载器和扩展类加载器的默认行为。
应该说系统类加载器负责加载classpath路径中的而且没有被扩展类加载器加载的类(当然也包括引导类加载器加载的)。如果classpath中有这个类,但是这个类也在扩展类加载器的类路径,那么系统类加载器将没有机会加载它。我们很少改变扩展类加载器的行为,所以一般你自己定义的类都是系统类加载器加载器的。获得系统类加载器非常简单,假设MyClass是你定义的一个类MyClass.class.getClassLoader()返回的就是系统类加载器,当然这种方法无法保证绝对正确,我们可以使用更简单而且一定正确的方式:ClassLoader.getSystemClassLoader()获得系统类加载器。
我们知道ClassLoader是一个抽象类,所以系统类加载器肯定是ClassLoader的一个子类实现。我们来看看它是什么ClassLoader.getSystemClassLoader().getClass();
结果是class sun.misc.Lancher$AppClassLoader 可以看出这是sun的一个实现,从名字可以看出是一个内部类,目前我也没有看到这个源代码,似乎还不是很清晰:我们在看看它的父类是什么:
ClassLoader.getSystemClassLoader().getClass().getSuperclass();
结果是:class java.net.URLClassLoader这个是j2se的标准类,它的父类是SecureClassLoader,而SecureClassLoader是继承ClassLoader的。
现在整个关系应该很清楚,我们会看到几乎所有的ClassLoader实现都是继承URLClassLoader的。
因为系统类加载器是非常重要的,而且是我们可以直接控制的,所以我们后面还会介绍,不过先来看一下扩展类加载器以及它们之间的关系。扩展类加载器似乎是一个不起眼的角色,它负责加载java的标准扩展(jre/lib/ext目录下的所有jar),它其实就是一个普通的加载器,看得见摸得着的
。首先的问题是怎么知道扩展类加载器在哪里?的确没有直接途径获得扩展类加载器,但是我们知道它是系统类加载器的父加载器,我们已经很容易的获得系统类加载器了,所以我们可以间接的获得扩展类加载器:ClassLoader.getSystemClassLoader().getParent().getClass();其实是通过系统类加载器间接的获得了扩展类加载器,看看是什么东西:
结果是:class sun.misc.Launcher$ExtClassLoader这个类和系统类加载器一样是一个内部类,而且定义在同一个类中。同样看看它的父类是什么:ClassLoader.getSystemClassLoader().getParent().getClass().getSuperclass();
可以看出结果也是class java.net.URLClassLoader扩展类加载jre/lib/ext目录下的所有类,包括jar,目录下的所有类(目录名不一定要classes).现在可以回答上面的问题了,你写一个HelloWorld,放到jre/lib/ext/下的某个目录比如 jre/lib/ext/myclass/HelloWorld.class然后在你classpath也设置一份到这个类的路径,结果执行java HelloWorld时,这个类是被扩展类加载器加载器的,可以这样证明public static void main(String[] args){ System.out.println("loaded by"+HelloWorld.class.getClassLoader().getClass()); System.out.println("Hello World");}
结果可以得到class sun.misc.Launcher$ExtClassLoader当然如果你把jre/lib/ext下myclass这个目录删除,仍然可以运行,但是这样结果是class sun.misc.Lancher$AppClassLoader如果你不知道这个过程的话,假设在你扩展类路径下有一份classpath中的拷贝,或者是比较低的版本,当你使用新的版本时会发现没有起作用,知道这个过程你就不会觉得奇怪了。
另外就是两个不同的类加载器是可以加载一个同名的类的,也就是说虽然扩展类加载器加载了某个类,系统类加载器是可以加载自己的版本的,但是现有的实现都没有这样做,ClassLoader中的方法是会请求父类加载器先加载的,如果你自己定义类加载器完全可以修改这种默认行为,甚至可以让他没有父加载器。
这里给出一个方法如何获得扩展类加载器加载的路径:
说明:通过上面的代码可以看出扩展类加载器只能加载ext目录下的jar包.
对于扩展类加载器我们基本上不会去关心,也很少把你自己的jar放到扩展路径,大部分情况下我们都感觉不到它的存在,当然如果你一定要放到这个目录下,一定要知道这个过程,它会优先于classpath中的类。现在我们应该很清楚知道某个类是哪个加载器加载的,并且知道为什么是它加载的,如果要在运行时获得某个类的类加载器,直接使用Class的getClassLoader()方法就可以了。用户定义的类一般都是系统类加载器加载的,我们很少直接使用类加载器加载类,我们甚至很少自己加载类。因为类在使用时会被自动加载,我们用到某个类时该类会被自动加载,比如new A()会导致类A自动被加载,不过这种加载只发生一次。我们也可以使用系统类加载器手动加载类,ClassLoader提供了这个接口
ClassLoader.getSystemClassLoader().loadClass("classFullName");
这就很明确的指定了使用系统类加载器加载指定的类,但是如果该类能够被扩展类加载器加载,系统类加载器还是不会有机会的。我们最常用的还是使用Class.forName加载使用的类,这种方式没有指定某个特定的ClassLoader,会使用调用类的ClassLoader。也就是说调用这个方法的类的类加载器将会用于加载这个类。比如在类A中使用Class.forName加载类B,那么加载类A的类加载器将会用于加载类B,这样两个类的类加载器是同一个。
最后讨论一下如何获得某个类加载器加载了哪些类,这个似乎有一定的使用价值,可以看出哪些类被加载了。其实这个也不是很难,因为ClassLoader中有一个classes成员变量就是用来保存类加载器加载的类列表,而且有一个方法void addClass(Class c) { classes.addElement(c);}这个方法被JVM调用。我们只要利用反射获得classes这个值就可以了,不过classes声明为private的,我们需要修改它的访问权限(没有安全管理器时很容易做到)
classes = ClassLoader.class.getDeclaredField("classes");
classes.setAccessible(true);
List ret=(List) classes.get(cl);
//classes是一个Vector可惜的是对于引导类加载器没有办法获得加载的类,因为它是c实现的,在java中很难控制了。
总结说明:
java中共有三种类型的类加载器:
1、引导类加载器(用来加载java API类)
2、扩展类加载器(用来加载jre\lib\ext目录下的jar包)
3、系统类加载器(主要用来加载用户自定义的类)
这三种类加载器之间存在父子
完整测试代码如下
这篇文章将比较深入的介绍java类加载原理和过程,虽然很多情况你都不需要了解类加载的过程,但是如果你希望了解java是如何工作的,或者希望定义自己的类加载器,就一定要了解类加载的过程,当然,无论你是否要参与类加载过程,了解这个过程对你都会有很大的帮助。本文希望通过一步一步的分析来说明类加载的过程,希望这种分析方法也会对你有某些帮助。本文使用的JDK是sun的jdk_1.4.2版本,当然这里重在阐述原理,和JDK本身没有多大的关系。这篇文章试图解决下面一些问题:类加载原理引导类加载器,扩展类加载器和系统类加载器如果知道某个类是哪个类加载器加载的如果得到系统类加载器加载了那些类首先我们要分析类加载原理,java中默认有三种类加载器:引导类加载器,扩展类加载器,系统类加载器(也叫应用类加载器)
引导类加载器负责加载jdk中的系统类,这种类加载器都是用c语言实现的,在java程序中没有办法获得这个类加载器,对于java程序是一个概念而已,基本上不用考虑它的存在,像String,Integer这样的类都是由引导类加载器加载器的.
扩展类加载器负责加载标准扩展类,一般使用java实现,这是一个真正的java类加载器,负责加载jre/lib/ext中的类,和普通的类加载器一样,其实这个类加载器对我们来说也不是很重要,我们可以通过java程序获得这个类加载器。
系统类加载器,加载第一个应用类的加载器(其实这个定义并不准确,下面你将会看到),也就是执行java MainClass 时加载MainClass的加载器,这个加载器使用java实现,使用的很广泛,负责加载classpath中指定的类。
类加载器之间有一定的关系(父子关系),我们可以认为扩展类加载器的父加载器是引导类加载器(当然不这样认为也是可以的,因为引导类加载器表现在java中就是一个null),不过系统类加载器的父加载器一定是扩展类加载器,类加载器在加载类的时候会先给父加载器一个机会,只有父加载器无法加载时才会自己去加载。我们无法获得引导类加载器,因为它是使用c实现的,而且使用引导类加载器加载的类通过getClassLoader方法返回的是null.所以无法直接操作引导类加载器,但是我们可以根据Class.getClassLoader方法是否为null判断这个类是不是引导类加载器加载的,可以通过下面的方法获得引导类加载器加载的类路径(每个jar包或者文件夹对应了一个URL);
sun.misc.Launcher.getBootstrapClassPath().getURLs()你可以直接在你的main函数中输出就可以了System.out.println(java.util.Arrays.asList(sun.misc.Launcher.getBootstrapClassPath().getURLs()).toString());
得到的结果是:[file:/C:/Program%20Files/Java/j2re1.4.2_10/lib/rt.jar, file:/C:/Program%20Files/Java/j2re1.4.2_10/lib/i18n.jar, file:/C:/Program%20Files/Java/j2re1.4.2_10/lib/sunrsasign.jar, file:/C:/Program%20Files/Java/j2re1.4.2_10/lib/jsse.jar, file:/C:/Program%20Files/Java/j2re1.4.2_10/lib/jce.jar, file:/C:/Program%20Files/Java/j2re1.4.2_10/lib/charsets.jar, file:/C:/Program%20Files/Java/j2re1.4.2_10/classes]
其实我们是可以指定引导类加载器的类路径的,java提供了一个-Xbootclasspath参数,不过这个参数不是标准参数。
java -Xbootclasspath: 运行时指定引导类加载器的加载路径(jar文件或者目录)java -Xbootclasspath/p:和上面的相同,不过把这个路径放到原来的路径前面java -Xbootclasspath/a:这个就是在原引导类路径后面添加类路径。上面我们有提过加载第一个应用类未必就是系统加载器。如果我把这个应用类的路径放到引导类路径中,它将会被引导类加载器加载,大致这样java -Xbootclasspath/a:myjar.jar MainClass如果MainClass在myjar.jar中,那么这个类将会被引导类加载器加载。如果希望看详情,使用-verbose参数,为了看的更清楚,使用重定向,大致为(windows下):
java -verbose -Xbootclasspath/a:myjar.jar MainClass -> C:\out.txt
通过这个参数我们可以实现自己的系统类,比如替换掉java.lang.Object的实现,自己可以扩展一些方法,不过这样做似乎没有好处,因为那就不是标准了。
我们最关心的还是系统类加载器,一般都认为系统类加载器是加载应用程序第一个类的加载器,也就是java MainClass命令中加载MainClass的类加载器,这种说法虽然不是很严谨,但基本上还是可以这样认为的,因为我们很少会改变引导类加载器和扩展类加载器的默认行为。
应该说系统类加载器负责加载classpath路径中的而且没有被扩展类加载器加载的类(当然也包括引导类加载器加载的)。如果classpath中有这个类,但是这个类也在扩展类加载器的类路径,那么系统类加载器将没有机会加载它。我们很少改变扩展类加载器的行为,所以一般你自己定义的类都是系统类加载器加载器的。获得系统类加载器非常简单,假设MyClass是你定义的一个类MyClass.class.getClassLoader()返回的就是系统类加载器,当然这种方法无法保证绝对正确,我们可以使用更简单而且一定正确的方式:ClassLoader.getSystemClassLoader()获得系统类加载器。
我们知道ClassLoader是一个抽象类,所以系统类加载器肯定是ClassLoader的一个子类实现。我们来看看它是什么ClassLoader.getSystemClassLoader().getClass();
结果是class sun.misc.Lancher$AppClassLoader 可以看出这是sun的一个实现,从名字可以看出是一个内部类,目前我也没有看到这个源代码,似乎还不是很清晰:我们在看看它的父类是什么:
ClassLoader.getSystemClassLoader().getClass().getSuperclass();
结果是:class java.net.URLClassLoader这个是j2se的标准类,它的父类是SecureClassLoader,而SecureClassLoader是继承ClassLoader的。
现在整个关系应该很清楚,我们会看到几乎所有的ClassLoader实现都是继承URLClassLoader的。
因为系统类加载器是非常重要的,而且是我们可以直接控制的,所以我们后面还会介绍,不过先来看一下扩展类加载器以及它们之间的关系。扩展类加载器似乎是一个不起眼的角色,它负责加载java的标准扩展(jre/lib/ext目录下的所有jar),它其实就是一个普通的加载器,看得见摸得着的
。首先的问题是怎么知道扩展类加载器在哪里?的确没有直接途径获得扩展类加载器,但是我们知道它是系统类加载器的父加载器,我们已经很容易的获得系统类加载器了,所以我们可以间接的获得扩展类加载器:ClassLoader.getSystemClassLoader().getParent().getClass();其实是通过系统类加载器间接的获得了扩展类加载器,看看是什么东西:
结果是:class sun.misc.Launcher$ExtClassLoader这个类和系统类加载器一样是一个内部类,而且定义在同一个类中。同样看看它的父类是什么:ClassLoader.getSystemClassLoader().getParent().getClass().getSuperclass();
可以看出结果也是class java.net.URLClassLoader扩展类加载jre/lib/ext目录下的所有类,包括jar,目录下的所有类(目录名不一定要classes).现在可以回答上面的问题了,你写一个HelloWorld,放到jre/lib/ext/下的某个目录比如 jre/lib/ext/myclass/HelloWorld.class然后在你classpath也设置一份到这个类的路径,结果执行java HelloWorld时,这个类是被扩展类加载器加载器的,可以这样证明public static void main(String[] args){ System.out.println("loaded by"+HelloWorld.class.getClassLoader().getClass()); System.out.println("Hello World");}
结果可以得到class sun.misc.Launcher$ExtClassLoader当然如果你把jre/lib/ext下myclass这个目录删除,仍然可以运行,但是这样结果是class sun.misc.Lancher$AppClassLoader如果你不知道这个过程的话,假设在你扩展类路径下有一份classpath中的拷贝,或者是比较低的版本,当你使用新的版本时会发现没有起作用,知道这个过程你就不会觉得奇怪了。
另外就是两个不同的类加载器是可以加载一个同名的类的,也就是说虽然扩展类加载器加载了某个类,系统类加载器是可以加载自己的版本的,但是现有的实现都没有这样做,ClassLoader中的方法是会请求父类加载器先加载的,如果你自己定义类加载器完全可以修改这种默认行为,甚至可以让他没有父加载器。
这里给出一个方法如何获得扩展类加载器加载的路径:
String path=System.getProperty("java.ext.dirs"); File dir=new File(path); if(!dir.exists()||!dir.isDirectory()){ return Collections.EMPTY_LIST; } File[] jars=dir.listFiles(); URL[] urls=new URL[jars.length]; for(int i=0;i<jars.length;i++){ urls[i]=sun.misc.URLClassPath.pathToURLs(jars[i].getAbsolutePath())[0]; } return Arrays.asList(urls);
说明:通过上面的代码可以看出扩展类加载器只能加载ext目录下的jar包.
对于扩展类加载器我们基本上不会去关心,也很少把你自己的jar放到扩展路径,大部分情况下我们都感觉不到它的存在,当然如果你一定要放到这个目录下,一定要知道这个过程,它会优先于classpath中的类。现在我们应该很清楚知道某个类是哪个加载器加载的,并且知道为什么是它加载的,如果要在运行时获得某个类的类加载器,直接使用Class的getClassLoader()方法就可以了。用户定义的类一般都是系统类加载器加载的,我们很少直接使用类加载器加载类,我们甚至很少自己加载类。因为类在使用时会被自动加载,我们用到某个类时该类会被自动加载,比如new A()会导致类A自动被加载,不过这种加载只发生一次。我们也可以使用系统类加载器手动加载类,ClassLoader提供了这个接口
ClassLoader.getSystemClassLoader().loadClass("classFullName");
这就很明确的指定了使用系统类加载器加载指定的类,但是如果该类能够被扩展类加载器加载,系统类加载器还是不会有机会的。我们最常用的还是使用Class.forName加载使用的类,这种方式没有指定某个特定的ClassLoader,会使用调用类的ClassLoader。也就是说调用这个方法的类的类加载器将会用于加载这个类。比如在类A中使用Class.forName加载类B,那么加载类A的类加载器将会用于加载类B,这样两个类的类加载器是同一个。
最后讨论一下如何获得某个类加载器加载了哪些类,这个似乎有一定的使用价值,可以看出哪些类被加载了。其实这个也不是很难,因为ClassLoader中有一个classes成员变量就是用来保存类加载器加载的类列表,而且有一个方法void addClass(Class c) { classes.addElement(c);}这个方法被JVM调用。我们只要利用反射获得classes这个值就可以了,不过classes声明为private的,我们需要修改它的访问权限(没有安全管理器时很容易做到)
classes = ClassLoader.class.getDeclaredField("classes");
classes.setAccessible(true);
List ret=(List) classes.get(cl);
//classes是一个Vector可惜的是对于引导类加载器没有办法获得加载的类,因为它是c实现的,在java中很难控制了。
总结说明:
java中共有三种类型的类加载器:
1、引导类加载器(用来加载java API类)
2、扩展类加载器(用来加载jre\lib\ext目录下的jar包)
3、系统类加载器(主要用来加载用户自定义的类)
这三种类加载器之间存在父子
完整测试代码如下
package com.mz.hw; public class HelloWorld{ public static void main(String[] args){ System.out.println("Hello World!"); System.out.println("HelloWorld的类加在器:"+HelloWorld.class.getClassLoader()); //启动类加载器 System.out.println("引导类(启动类)加载器加载的包:"+java.util.Arrays.asList(sun.misc.Launcher.getBootstrapClassPath().getURLs()).toString()); //系统类加载器 System.out.println("获得系统类加载器:"+ClassLoader.getSystemClassLoader()); System.out.println("获得系统类加载器的父类:"+ClassLoader.getSystemClassLoader().getClass().getSuperclass()); //查看系统类加载器加载了哪些类? try{ ClassLoader cl = ClassLoader.getSystemClassLoader(); java.lang.reflect.Field classes = ClassLoader.class.getDeclaredField("classes"); classes.setAccessible(true);//修改字段的可访问权限. java.util.List ret=(java.util.List)classes.get(cl); System.out.println("系统类加载类列表:"+ret.toString()); }catch(Exception e){ } //扩展类加载器 System.out.println("获得扩展类加载器:"+ClassLoader.getSystemClassLoader().getParent().getClass()); System.out.println("获得扩展类加载器的父类:"+ClassLoader.getSystemClassLoader().getParent().getClass().getSuperclass()); } }
发表评论
-
Hibernate createSQLQuery list 返回结果转成Map的方法
2012-03-03 17:24 2295Query query = session.creat ... -
转==Java获取请求客户端的真实IP地址
2010-10-17 17:03 1517通常通过request.getRemoteAddr() 取得 ... -
jsp中还可以定义方法,不错
2010-08-31 18:35 2130<%! public String myDecode ... -
jstl 对国际化i18n的支持
2010-08-24 16:02 2694下面是我转自:http://spaceflysky-163-c ... -
jstl学习-变量的取值范围和编译后的代码
2010-08-24 15:42 3142主要测试问题: 1、隐式EL变量 pageScope: ... -
基于多种协议的消息传递机制简介(转)
2010-08-24 10:25 2867转载 基于多种协议的 ... -
(转)AssertionError 的来源
2010-08-24 10:23 1253下面哪些类与AssertionError 类是"is ... -
Java单例模式-双重检查为什么会有问题
2010-08-24 10:22 0参考资源: http://www.iteye.com/topi ... -
(转)接口与抽象接口(interface & abstract interface)
2010-07-23 14:57 1344前一段用到Spring的ApplicationContext接 ... -
(转)用Hash目录优化文件存储
2010-07-23 13:27 2562Hash目录是一种优化文件存储性能的方法。无论是Windows ... -
(转)传智播客学习文件上传
2010-07-22 11:14 1290今天讲了文件的上传文件上传与下载工程。这在实际的应用中非常常见 ... -
输出XXX{0}YYY{1}ZZZ格式的字符串方法
2010-07-21 15:10 1567public static void main(Strin ... -
(转)findstr 命令学习
2010-07-12 18:02 1662findstr 命令学习 findstr 是 Windows ... -
Apache lnag 包生成随机数的方法
2010-07-10 12:02 1495使用 apache 包的 RandomStringUtils类 ... -
(转载)javamail 发送邮件的简单实例
2010-07-09 18:31 1003今天学习了一下JavaMail,javamail发送邮件确实是 ... -
(转载)使用Servlet实现文件下载的时候,避免浏览器自动打开文件
2010-07-07 15:35 1517response.addHeader("Cont ... -
File 协议
2010-01-29 15:41 2745英文原义:File Protocol 中文释义:本地文件传输 ... -
深入了解字符集和编码
2009-03-03 11:22 1306关键字: 字符集 编码 ... -
在命令行中"执行命令"的搜索路径
2009-02-27 10:25 1642问题:在命令行中输入一个命令,如telnet,javac,ja ... -
Java中-classpath和路径的使用
2009-02-25 11:05 1405如有侵权请告知 javac -classpath的使用: ...
相关推荐
java类加载原理分析,引导类加载器,扩展类加载器,系统类加载器(也叫应用类加载器)
Java类加载原理解析,深度解剖了java中的类的执行内部机制!
看完一个Java加载原理教程后,写了这个自己的类加载器,作个笔记,以便以且使用
自己根据一些文章总结的,不知道有没有漏洞,希望大家知道,谢谢
Java类加载原理解析.docx 注意:这是一篇文档。。。
类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一。它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java ...
深入研究Java类加载机制 深入研究Java类加载机制 深入研究Java类加载机制 深入研究Java类加载机制
java类加载器学习三、类加载器的委托模式
java类加载机制原理与实现
ClassLoader 三种类加载方式 Boostrap Extenxsion 以及Application ClassLoad分别适用的场景
java 类加密 使用类加载器解密加载类 反射执行main
Java类加载器.pdf
springboot 、java类热加载、jarinjar、动态编译、自动引用依赖
该文件是JVM中关于类加载机制的知识整理的思维导图,包括类加载机制概述、类加载的生命周期、加载时机、加载过程、类加载、类的初始化和实例化等几个大方面进行了讲解,其中类加载中还对JVM三种预定义类加载器进行了...
Java虚拟机类加载顺序,Java虚拟机类加载顺序,Java虚拟机类加载顺序
类加载是java语言提供的最强大的机制之一,但所有的编程人员都应该了解其工作机制,明白如何做才能让其满足我们的需要。这能有效节省我们的编码时间,从不断调试ClassNotFoundException的工作中解脱出来。