- 浏览: 914771 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (537)
- Java SE (114)
- Struts (18)
- Hibernate (25)
- Spring (3)
- Page_Tech (41)
- Others (87)
- Database (29)
- Server (24)
- OpenSource_Tools (15)
- IDE_Tool (22)
- Algorithm (28)
- Interview (22)
- Test (28)
- Hardware (1)
- Mainframe (25)
- Web application (4)
- Linux (3)
- PHP (17)
- Android (1)
- Perl (6)
- ubuntu (1)
- Java EE (9)
- Web Analysis (5)
- Node.js (2)
- javascript (2)
最新评论
-
一键注册:
request.getRequestURL()和request.getRequestURI() -
SuperCustomer:
...
SED的暂存空间和模式空间 -
juyo_ch:
讲得挺好理解的,学习了
java 死锁及解决 -
chinaalex:
最后一题答案正确,但是分析有误.按照如下过程,上一行为瓶,下一 ...
zz智力题 -
liaowuxukong:
多谢博主啦,弱弱的了解了一点。
C++/Java 实现多态的方法(C++)
本文出自 “专注J2EE系列规范下的..” 博客,请务必保留此出处http://danni505.blog.51cto.com/15547/227437
主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作。
主要负责jdk_home/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作。
主要负责java -classpath/-Djava.class.path所指的目录下的类与jar包装入工作。
在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件, 体现java动态实时类装入特性。
Class c = findLoadedClass(name);
if (c == null ) {
// 指定类未被装载过
try {
if (parent != null ) {
// 如果父类加载器不为空, 则委派给父类加载
c = parent.loadClass(name, false );
} else {
// 如果父类加载器为空, 则委派给启动类加载加载
c = findBootstrapClass0(name);
}
} catch (ClassNotFoundException e) {
// 启动类加载器或父类加载器抛出异常后, 当前类加载器将其
// 捕获, 并通过findClass方法, 由自身加载
c = findClass(name);
}
}
java默认的线程上下文类加载器是 系统类加载器(AppClassLoader)。
try {
loader = AppClassLoader.getAppClassLoader(extcl);
} catch (IOException e) {
throw new InternalError(
"Could not create application class loader" );
}
// Also set the context class loader for the primordial thread.
Thread.currentThread().setContextClassLoader(loader);
典型的例子有, 通过线程上下文来加载第三方库jndi实现, 而不依赖于双亲委派.
大部分java app服务器(jboss, tomcat..)也是采用contextClassLoader来处理web服务。
还有一些采用 hotswap 特性的框架, 也使用了线程上下文类加载器, 比如 seasar (full stack framework in japenese).
使java类加载体系显得更灵活.
在编写基础设施时, 通过使用线程上下文来加载类, 应该是一个很好的选择。
防止因为不同的类加载器, 导致类型转换异常(ClassCastException)。
这种特性, 证明了java类加载器中的名称空间是唯一的, 不会相互干扰。
即在一般情况下, 保证同一个类中所关联的其他类都是由当前类的类加载器所加载的。
throws ClassNotFoundException {
return forName0(className, true , ClassLoader.getCallerClassLoader());
}
/** Called after security checks have been made. */
private static native Class forName0(String name, boolean initialize,
ClassLoader loader)
throws ClassNotFoundException;
1.ClassLoader分类
类装载器是用来把类(class)装载进JVM的。
JVM规范定义了两种类型的类装载器:启动内装载器(bootstrap)和用户自定义装载器(user-defined class loader)。
JVM在运行时会产生三个ClassLoader:Bootstrap ClassLoader、Extension ClassLoader和AppClassLoader.Bootstrap是用C++编写的,我们在Java中看不到它,是null,是JVM自带的类装载器,用来装载核心类库,如java.lang.*等。
AppClassLoader的Parent是ExtClassLoader,而ExtClassLoader的Parent为Bootstrap ClassLoader。
Java提供了抽象类ClassLoader,所有用户自定义类装载器都实例化自ClassLoader的子类。 System Class Loader是一个特殊的用户自定义类装载器,由JVM的实现者提供,在编程者不特别指定装载器的情况下默认装载用户类。系统类装载器可以通过ClassLoader.getSystemClassLoader() 方法得到。
例1,测试你所使用的JVM的ClassLoader
/*LoaderSample1.java*/
public static void main(String[] args) {
Class c;
ClassLoader cl;
cl = ClassLoader.getSystemClassLoader();
System.out.println(cl);
while (cl != null ) {
cl = cl.getParent();
System.out.println(cl);
}
try {
c = Class.forName( " java.lang.Object " );
cl = c.getClassLoader();
System.out.println( " java.lang.Object's loader is " + cl);
c = Class.forName( " LoaderSample1 " );
cl = c.getClassLoader();
System.out.println( " LoaderSample1's loader is " + cl);
} catch (Exception e) {
e.printStackTrace();
}
}
}
sun.misc.Launcher$AppClassLoader@1a0c10f
sun.misc.Launcher$ExtClassLoader@e2eec8
null
java.lang.Object's loader is null
LoaderSample1's loader is sun.misc.Launcher$AppClassLoader@1a0c10f
第一行表示,系统类装载器实例化自类sun.misc.Launcher$AppClassLoader
第二行表示,系统类装载器的parent实例化自类sun.misc.Launcher$ExtClassLoader
第三行表示,系统类装载器parent的parent为bootstrap
第四行表示,核心类java.lang.Object是由bootstrap装载的
第五行表示,用户类LoaderSample1是由系统类装载器装载的
二.parent delegation模型
从1.2版本开始,Java引入了双亲委托模型,从而更好的保证Java平台的安全。在此模型下,当一个装载器被请求装载某个类时,它首先委托自己的parent去装载,若parent能装载,则返回这个类所对应的Class对象,若parent不能装载,则由parent的请求者去装载。
图 1 parent delegation模型
如图1所示,loader2的parent为loader1,loader1的parent为system class loader。假设loader2被要求装载类MyClass,在parent delegation模型下,loader2首先请求loader1代为装载,loader1再请求系统类装载器去装载MyClass。若系统装载器能成功装载,则将MyClass所对应的Class对象的reference返回给loader1,loader1再将reference返回给loader2,从而成功将类MyClass装载进虚拟机。若系统类装载器不能装载MyClass,loader1会尝试装载MyClass,若loader1也不能成功装载,loader2会尝试装载。若所有的parent及loader2本身都不能装载,则装载失败。
若有一个能成功装载,实际装载的类装载器被称为定义类装载器,所有能成功返回Class对象的装载器(包括定义类装载器)被称为初始类装载器。如图1所示,假设loader1实际装载了MyClass,则loader1为MyClass的定义类装载器,loader2和loader1为MyClass的初始类装载器。
需要指出的是,Class Loader是对象,它的父子关系和类的父子关系没有任何关系。
那么parent delegation模型为什么更安全了?因为在此模型下用户自定义的类装载器不可能装载应该由父亲装载器装载的可靠类,从而防止不可靠甚至恶意的代码代替由父亲装载器装载的可靠代码。实际上,类装载器的编写者可以自由选择不用把请求委托给parent,但正如上所说,会带来安全的问题。
三.命名空间及其作用
每个类装载器有自己的命名空间,命名空间由所有以此装载器为创始类装载器的类组成。不同命名空间的两个类是不可见的,但只要得到类所对应的Class对象的reference,还是可以访问另一命名空间的类。
例2演示了一个命名空间的类如何使用另一命名空间的类。在例子中,LoaderSample2由系统类装载器装载,LoaderSample3由自定义的装载器loader负责装载,两个类不在同一命名空间,但LoaderSample2得到了LoaderSample3所对应的Class对象的reference,所以它可以访问LoaderSampl3中公共的成员(如age)。
例2不同命名空间的类的访问
/*LoaderSample2.java*/
import java.lang.reflect. * ;
public class LoaderSample2 {
public static void main(String[] args) {
try {
String path = System.getProperty( " user.dir " );
URL[] us = { new URL( " file:// " + path + " /sub/ " )};
ClassLoader loader = new URLClassLoader(us);
Class c = loader.loadClass( " LoaderSample3 " );
Object o = c.newInstance();
Field f = c.getField( " age " );
int age = f.getInt(o);
System.out.println( " age is " + age);
} catch (Exception e) {
e.printStackTrace();
}
}
}
static {
System.out.println( " LoaderSample3 loaded " );
}
public int age = 30 ;
}
运行:java LoaderSample2
LoaderSample3 loaded
age is 30
从运行结果中可以看出,在类LoaderSample2中可以创建处于另一命名空间的类LoaderSample3中的对象并可以访问其公共成员age。
运行时包(runtime package)
由同一类装载器定义装载的属于相同包的类组成了运行时包,决定两个类是不是属于同一个运行时包,不仅要看它们的包名是否相同,还要看的定义类装载器是否相同。只有属于同一运行时包的类才能互相访问包可见的类和成员。这样的限制避免了用户自己的代码冒充核心类库的类访问核心类库包可见成员的情况。假设用户自己定义了一个类java.lang.Yes,并用用户自定义的类装载器装载,由于java.lang.Yes和核心类库java.lang.*由不同的装载器装载,它们属于不同的运行时包,所以java.lang.Yes不能访问核心类库java.lang中类的包可见的成员。
总结
命名空间并没有完全禁止属于不同空间的类的互相访问,双亲委托模型加强了Java的安全,运行时包增加了对包可见成员的保护。
二. 扩展ClassLoader方法
我们目的是从本地文件系统使用我们实现的类装载器装载一个类。为了创建自己的类装载器我们应该扩展ClassLoader类,这是一个抽象类。我们创建一个FileClassLoader extends ClassLoader。我们需要覆盖ClassLoader中的findClass(String name)方法,这个方法通过类的名字而得到一个Class对象。
{
byte [] data = loadClassData(name);
return defineClass(name, data, 0 , data.length);
}
节数组。然后使用ClassLoader提供的defineClass()方法我们就可以返回Class对象了。
{
FileInputStream fis = null ;
byte [] data = null ;
try
{
fis = new FileInputStream( new File(drive + name + fileType));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int ch = 0 ;
while ((ch = fis.read()) != - 1 )
{
baos.write(ch);
}
data = baos.toByteArray();
} catch (IOException e)
{
e.printStackTrace();
}
return data;
}
发表评论
-
maven 在Mac OS下运行的问题总结
2014-05-16 17:24 824在maven下生成基本的项目结构。 生成eclipse项 ... -
【zz】 java函数参数类型后添加三点的用法
2012-07-02 09:48 1046今天看到一个没见过的函数参数列表test(int... a), ... -
【zz】Java编码的理解和Java加载器的理解
2012-06-08 15:59 747一,我对java中编码的理解1. 编码的产生 对电脑而言 ... -
类加载器入门级应用
2012-06-08 15:17 9241、类加载器负责加载 Ja ... -
Java静态代理与动态代理
2012-05-29 10:32 937JAVA的静态代理与动态代 ... -
JDK的动态代理深入解析(Proxy,InvocationHandler)(转)
2012-05-29 10:31 5183调用处理器InvocationHandle ... -
zz 动态反射实现AOP的简单原理
2012-05-28 17:46 895其实AOP的意思就是面向切面编程. OO注重的是我们 ... -
理解Java枚举在单例模式的应用
2012-06-05 15:50 12725.3.9 单例和枚举 按照《高效Java 第二版》中的说 ... -
Java 枚举的介绍
2012-05-23 16:50 0一、使用简单程序完成枚举的功能 例:使用简单类完成枚举操作 ... -
枚举类型的用法
2012-06-05 15:50 1428DK1.5引入了新的类型——枚举。在 Java 中它虽然算 ... -
单例模式的七种写法 (包括1.5新特性)
2012-05-23 16:18 0第一种(懒汉,线程不安全): <!--<br / ... -
重写hashCode方法的意义
2012-05-23 16:01 1640Java中的很多对象都override了equ ... -
JDK Log的设计思想
2012-05-23 14:39 1307最近在看《Agile Java》,看到日志一节,收获颇多,所以 ... -
[zz] Synchronized和Static Synchronized区别
2012-05-23 14:07 780通过分析这两个用法的分析,我们可以理解java中锁的概念。一 ... -
双精度、单精度的有效位数
2012-05-22 17:25 5101浮点数7位有效数字。(应该是单精度数) 双精度数16位有效 ... -
DecimalFormat 使用方法
2012-05-22 16:44 1021我们经常要将数字进行格式化,比如取2位小数,这是最常见的。Ja ... -
Java Applet 无法运行的一个问题
2012-04-28 15:09 2529当你用JDK1.6开发出的新功能,在JDK1.6上re ... -
JDK1.5之中的Map相关的类
2012-04-26 10:14 1859java5的java.util包提供了大量集合类。其中最常用的 ... -
设计模式应用场景总结
2012-04-11 16:47 1264在J2EE的开发和测试中,其实不知不觉已经使用了许多设计模式。 ... -
【转】有状态和无状态的Servlet
2012-04-06 14:57 3742我相信有不少人还不明白有状态和无状态(Stateful and ...
相关推荐
《ClassLoader详解》 Java应用程序的运行离不开类的加载,而ClassLoader正是这个过程的关键角色。它负责将类的字节码加载到Java虚拟机(JVM)中并转换为可执行的Java对象。深入理解ClassLoader的工作原理对于优化...
### Java ClassLoader 详解 #### 一、ClassLoader 概述 在 Java 语言中,类加载器(ClassLoader)是 Java 运行时环境的核心组成部分之一,它负责将编译后的 `.class` 文件加载到 JVM 中执行。从 JDK 1.0 开始,...
#### 二、ClassLoader详解 ##### 2.1 类加载器的概念 类加载器(`ClassLoader`)是Java运行时环境的一部分,它的主要职责是从文件系统或网络中获取字节码,将其转换为`Class`对象,并在Java虚拟机中运行。Java中的...
### Tomcat中的ClassLoader详解 #### 一、引言 在深入了解Tomcat的工作原理时,一个重要的组成部分就是其ClassLoader机制。本文旨在深入剖析Tomcat中特有的类加载器(ClassLoader)体系结构,帮助读者理解Tomcat...
《Tomcat类加载机制——ClassLoader详解》 在Java Web开发中,Tomcat作为最常用的Servlet容器,其类加载机制对于理解和优化应用性能至关重要。本文将深入探讨Tomcat的ClassLoader是如何工作的,以及它如何影响到...
### Java ClassLoader详解:以淘宝网为例 #### 一、ClassLoader概述 在Java环境中,类加载器(ClassLoader)是负责加载Java类到JVM的重要组件。它不仅实现了类的加载机制,还支持了动态加载与卸载的功能。本文将...
在Java编程语言中,ClassLoader是核心组件之一,它负责加载类到JVM(Java虚拟机)中执行。本文将深入探讨ClassLoader的工作原理和类加载机制,帮助开发者理解这个至关重要的概念。 1. 类加载机制概述 Java的类加载...
2. **ClassLoader详解**: 在Android中,类加载器(ClassLoader)遵循双亲委派模型,即首先由父加载器尝试加载,如果父加载器无法加载,再由当前加载器尝试。默认情况下,Android使用`PathClassLoader`加载应用的....
### Java虚拟机中ClassLoader概述与双亲委托机制详解 #### 一、ClassLoader概念与作用 在Java编程语言中,`ClassLoader`是一个非常重要的组件,它负责加载程序运行所需的类文件到Java虚拟机(JVM)中。`ClassLoader`...
### Java ClassLoader理解详解 #### 一、引言 在商业流行的编程语言中,Java以其独特的运行机制脱颖而出:它在Java虚拟机(JVM)上运行。这意味着编译后的程序采用一种特殊的、与平台无关的格式,而不是针对特定...
Android类加载器(ClassLoader)是Android系统中负责查找和加载类的重要组件。在深入理解Android的ClassLoader之前,我们先回顾一下Java的类加载机制。Java的类加载采用的是双亲委派模型,即当一个类加载器需要加载...
### Java ClassLoader原理详解 #### 摘要 本文探讨了Java虚拟机(JVM)中的一个重要特性:动态类加载(Dynamic Class Loading)。这一机制为Java平台提供了强大的能力,允许在运行时安装软件组件,例如从网络下载...
### Java自定义类加载器(Class Loader)详解 #### 一、引言 在Java语言中,类加载机制是其动态特性的核心之一。通过类加载器(Class Loader),Java程序能够在运行时根据需要加载所需的类,从而实现高度的灵活性...
### Java ClassLoader (类加载器)详解 #### 一、教程提示 如果你正在查看这份文档,在线版中你可以点击下面的任何主题直接跳转到相应的部分。 1. **教程提示** 2. **介绍** 3. **类加载器结构** 4. **编译类加载...
Java类加载器(ClassLoader)是Java虚拟机(JVM)中的一个重要组成部分,用于将Java类文件加载到JVM中,以便能够执行Java程序。在Java中,类加载器的设计采用了一种称为“双亲委派模式”(Parent Delegation Model)...
Java类装载器分为三个主要的层次:Bootstrap ClassLoader、Extension ClassLoader和Application ClassLoader,以及用户自定义的ClassLoader。 Bootstrap ClassLoader是JVM的启动类装载器,它由C/C++实现,不继承自...
Java的ClassLoader机制是Java运行时环境的核心组成部分,它负责加载.class文件到JVM(Java Virtual Machine)中,以便程序能够使用这些类。ClassLoader的主要任务是将类的二进制数据转换为可执行的Java对象。它使得...