ClassLoader基本概念
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的子类。 Customer Class Loader是一个特殊的用户自定义类装载器,由JVM的实现者提供,在编程者不特别指定装载器的情况下默认装载用户类。系统类装载器可以通过ClassLoader.getSystemClassLoader() 方法得到。
例1,测试你所使用的JVM的ClassLoader
Java代码
-
/*LoaderSample1.java*/
-
-
public class LoaderSample1 {
- 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 Java 1.4.2)的运行结果
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所示,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不同命名空间的类的访问
Java代码
- *LoaderSample2.java*/
-
-
import java.net. * ;
-
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();
- }
- }
- }
Java代码
-
/*sub/Loadersample3.java*/
-
-
public class LoaderSample3 {
- static {
- System.out.println( " LoaderSample3 loaded " );
- }
- public int age = 30 ;
- }
编译:javac LoaderSample2.java; javac sub/LoaderSample3.java
运行:java LoaderSample2
LoaderSample3 loaded
age is 30
从运行结果中可以看出,在类LoaderSample2中可以创建处于另一命名空间的类LoaderSample3中的对象并可以访问其公共成员age。
4. 运行时包(runtime package)
由同一类装载器定义装载的属于相同包的类组成了运行时包,决定两个类是不是属于同一个运行时包,不仅要看它们的包名是否相同,还要看的定义类装载器是否相同。只有属于同一运行时包的类才能互相访问包可见的类和成员。这样的限制避免了用户自己的代码冒充核心类库的类访问核心类库包可见成员的情况。假设用户自己定义了一个类java.lang.Yes,并用用户自定义的类装载器装载,由于java.lang.Yes和核心类库java.lang.*由不同的装载器装载,它们属于不同的运行时包,所以java.lang.Yes不能访问核心类库java.lang中类的包可见的成员。
总结
命名空间并没有完全禁止属于不同空间的类的互相访问,双亲委托模型加强了Java的安全,运行时包增加了对包可见成员的保护。
本文转载于:http://andynjux.blogbus.com/logs/48220001.html 辛显龙
分享到:
相关推荐
理解ClassLoader的工作原理以及如何定制它,对于深入学习Java的运行机制和进行高级应用开发具有重要意义。本篇文章将深入探讨Java ClassLoader的内部工作,并通过一个具体的实例来展示如何定制自己的ClassLoader。 ...
首先,我们来了解一下ClassLoader的基本层次结构。在Java中,ClassLoader分为三个主要层次:Bootstrap ClassLoader、Extension ClassLoader和App ClassLoader(也称为System ClassLoader)。Bootstrap ClassLoader是...
理解ClassLoader的工作原理对于优化Java应用程序性能以及解决类冲突等问题具有重要意义。 一、ClassLoader的基本概念 Java程序由多个类组成,每个类对应一个.class文件。当程序运行时,ClassLoader根据需要动态...
通过本教程的学习,你将能够理解Java ClassLoader的基本概念及其工作原理,并学会如何创建自定义的ClassLoader。自定义ClassLoader不仅能够扩展JVM的功能,还能够在实际项目中解决特定问题,如动态加载远程资源、...
### Java ClassLoader详解:以淘宝网为例...以上内容详细介绍了Java ClassLoader的基本概念、工作原理、自定义方式及其实战应用,并结合淘宝网的实际案例进行了分析,希望能够帮助读者更深入地理解和运用ClassLoaders。
一、ClassLoader 基本概念 1. 类加载器的层次结构:在Java中,类加载器形成了一个树形结构,通常由Bootstrap ClassLoader(引导类加载器)、Extension ClassLoader(扩展类加载器)和App ClassLoader(应用程序类...
ClassLoader原理的理解对于深入学习Java和进行系统优化至关重要。这篇博文将带你深入了解ClassLoader的工作机制。 首先,我们来理解ClassLoader的基本概念。ClassLoader是一个抽象的概念,它是Java中的一个接口,...
### Java ClassLoader (类加载器)详解 #### 一、教程提示 如果你正在查看这份文档,在线版中你可以点击下面的任何主题直接跳转到相应的部分。 1. **教程提示** 2. **介绍** 3. **类加载器结构** 4. **编译类加载...
1. **ClassLoader基本概念** - ClassLoader是一个Java类,用于动态加载Java类到JVM中。Java程序中的每个类都由某个ClassLoader实例加载。 - JVM中有三个内置的ClassLoader:Bootstrap ClassLoader、Extension ...
Java 编程语言的基本原理 Java 编程语言是当今最流行的编程语言之一,它的基本原理是确保 Java 程序可以跨平台运行的。为了实现这一点,Java 虚拟机(JVM)扮演着至关重要的角色。 一、Java 程序跨平台原理 Java ...
学习ClassLoader的工作原理以及如何创建自己的ClassLoader是必要的。 首先,让我们深入了解ClassLoader的基本概念。在传统编程语言中,如C或C++,程序通常是一个单一的可执行文件,而Java则不同,它的编译结果是以...
前面已经写过一篇关于java classloader的拙文java classloader原理初探。 时隔几年,再看一遍,觉得有些地方显得太过苍白,于是再来一篇: 完成一个Java类之后,经过javac编译,会生成一个class文件,这个...
- **类结构**:`java.lang.ClassLoader` 是所有类加载器的超类,提供了基本的类加载框架。 - **关键方法**: - `getParent()`:获取父类加载器。 - `loadClass(String name)`:根据给定的类名加载类。 - `find...
总之,这个名为“测试普通Java程序ClassLoader等级关系的Demo程序”旨在帮助开发者掌握Java中类加载器的工作原理和它们之间的层次关系,这对于理解Java应用程序的运行机制和进行问题排查具有非常实际的意义。...
通过对`ClassLoader`的基本概念、工作原理、双亲委托机制以及不同类型的类加载器的了解,我们可以更好地理解Java类加载的过程及其背后的设计哲学。这对于深入理解Java虚拟机的内部机制以及开发高质量的应用程序都至...
Java虚拟机工作原理详解 Java虚拟机工作原理详解是 Java 程序执行的核心组件之一。了解 Java 虚拟机的工作原理对 Java 开发人员来说非常重要。本文将详细介绍 Java 虚拟机工作原理的详细过程和类加载器的工作机理。...
### WebSphere ClassLoader原理 #### 一、概述 在探讨WebSphere Application Server v6中的ClassLoaders之前,我们首先简要回顾一下ClassLoaders的基本概念及其在Java虚拟机(JVM)中的作用。 **ClassLoaders**是...
总之,ClassLoader是Java程序运行的基础,理解其工作原理及特性对于成为一名合格的Java开发者至关重要。通过本文档的学习,读者可以深入理解Java虚拟机加载类的过程,掌握如何自定义和优化类加载机制,从而提升应用...
本示例"ClassLoader小例子"将深入探讨这个概念,并通过一个具体的程序来演示其工作原理。下面我们将详细讨论ClassLoader的基本概念、工作流程以及如何自定义ClassLoader。 1. **ClassLoader的基本概念** - 类加载...