- 浏览: 140773 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
zi_wu_xian:
docx格式的word文件虽然是zip格式的,也可以看到xml ...
用Java操作Office 2007 -
MyDreamNotDream:
看代码看到这里很不容易呢。
Java中HashMap的实现原理 -
四书五经:
to 楼上的 SonofGod :这个时候这样去获取:如果(值 ...
Java中HashMap的实现原理 -
SonofGod:
请问 楼主 在疑问3中。多个key的hash值一样的话,存储时 ...
Java中HashMap的实现原理 -
SonofGod:
请问 楼主 在疑问2中。多个可以的hash得到一样的hash值 ...
Java中HashMap的实现原理
Java的类装载器(Class Loader)和命名空间(NameSpace)
1.摘要:
Java的类装载器是Java动态性的核心,本文将向大家简要介绍Java的类装载器,及相关的双亲委派模型,命名空间,运行时包等概念,同时讨论一些在学习中容易混淆的问题。
2.类装载器的功能及分类:
顾名思义,类装载器是用来把类(class)装载进JVM的。JVM规范定义了两种类型的类装载器:启动内装载器(bootstrap)和用户自定义装载器(user-defined class loader)。
bootstrap是JVM自带的类装载器,用来装载核心类库,如java.lang.*等。由例1可以看出,java.lang.Object是由bootstrap装载的。
Java提供了抽象类ClassLoader,所有用户自定义类装载器都实例化自ClassLoader的子类。
System Class Loader是一个特殊的用户自定义类装载器,由JVM的实现者提供,在编程者不特别指定装载器的情况下默认装载用户类。系统类装载器可以通过ClassLoader.getSystemClassLoader() 方法得到。
例1,测试你所使用的JVM的ClassLoader
/*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是由系统类装载器装载的
3.双亲委派模型:
从1.2版本开始,Java引入了双亲委托模型,从而更好的保证Java平台的安全。在此模型下,当一个装载器被请求装载某个类时,它首先委托自己的parent去装载,若parent能装载,则返回这个类所对应的Class对象,若parent不能装载,则由parent的请求者去装载。
如图1所示,loader2的parent为loader1,loader1的parent为system class loader。假设loader2被要求装载类MyClass,在双亲委派模型下,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的初始类装载器。
system class loader
loader1
loader2
MyClass
图1
需要指出的是,Class Loader是对象,它的父子关系和类的父子关系没有任何关系。一对父子loader可能实例化自同一个Class,也可能不是,甚至父loader实例化自子类,子loader实例化自父类。假设MyClassLoader继承自ParentClassLoader,我们可以有如下父子loader:
ClassLoader loader1 = new MyClassLoader();
ClassLoader loader2 = new ParentClassLoader(loader1); //参数 loader1为parent
那么双亲委托模型为什么更安全了?因为在此模型下用户自定义的类装载器不可能装载应该由父亲装载器装载的可靠类,从而防止不可靠甚至恶意的代码代替由父亲装载器装载的可靠代码。实际上,类装载器的编写者可以自由选择不用把请求委托给parent,但正如上所说,会带来安全的问题。
4.命名空间及其作用:
每个类装载器有自己的命名空间,命名空间由所有以此装载器为创始类装载器的类组成。
不同命名空间的两个类是不可见的,但只要得到类所对应的Class对象的reference,还是可以访问另一命名空间的类。
例2演示了一个命名空间的类如何使用另一命名空间的类。在例子中,LoaderSample2由系统类装载器装载,LoaderSample3由自定义的装载器loader负责装载,两个类不在同一命名空间,但LoaderSample2得到了LoaderSample3所对应的Class对象的reference,所以它可以访问LoaderSampl3中公共的成员(如age)。
例2不同命名空间的类的访问
/*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();
}
}
}
/*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。
5.运行时包(runtime package):
由同一类装载器定义装载的属于相同包的类组成了运行时包,决定两个类是不是属于同一个运行时包,不仅要看它们的包名是否相同,还要看的定义类装载器是否相同。只有属于同一运行时包的类才能互相访问包可见的类和成员。这样的限制避免了用户自己的代码冒充核心类库的类访问核心类库包可见成员的情况。假设用户自己定义了一个类java.lang.Yes,并用用户自定义的类装载器装载,由于java.lang.Yes和核心类库java.lang.*由不同的装载器装载,它们属于不同的运行时包,所以java.lang.Yes不能访问核心类库java.lang中类的包可见的成员。
6.总结:
在简单讨论了类装载器,双亲委派模型,命名空间,运行时包后,相信大家已经对它们的作用有了一定的了解。命名空间并没有完全禁止属于不同空间的类的互相访问,双亲委托模型加强了Java的安全,运行时包增加了对包可见成员的保护
1.摘要:
Java的类装载器是Java动态性的核心,本文将向大家简要介绍Java的类装载器,及相关的双亲委派模型,命名空间,运行时包等概念,同时讨论一些在学习中容易混淆的问题。
2.类装载器的功能及分类:
顾名思义,类装载器是用来把类(class)装载进JVM的。JVM规范定义了两种类型的类装载器:启动内装载器(bootstrap)和用户自定义装载器(user-defined class loader)。
bootstrap是JVM自带的类装载器,用来装载核心类库,如java.lang.*等。由例1可以看出,java.lang.Object是由bootstrap装载的。
Java提供了抽象类ClassLoader,所有用户自定义类装载器都实例化自ClassLoader的子类。
System Class Loader是一个特殊的用户自定义类装载器,由JVM的实现者提供,在编程者不特别指定装载器的情况下默认装载用户类。系统类装载器可以通过ClassLoader.getSystemClassLoader() 方法得到。
例1,测试你所使用的JVM的ClassLoader
/*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是由系统类装载器装载的
3.双亲委派模型:
从1.2版本开始,Java引入了双亲委托模型,从而更好的保证Java平台的安全。在此模型下,当一个装载器被请求装载某个类时,它首先委托自己的parent去装载,若parent能装载,则返回这个类所对应的Class对象,若parent不能装载,则由parent的请求者去装载。
如图1所示,loader2的parent为loader1,loader1的parent为system class loader。假设loader2被要求装载类MyClass,在双亲委派模型下,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的初始类装载器。
system class loader
loader1
loader2
MyClass
图1
需要指出的是,Class Loader是对象,它的父子关系和类的父子关系没有任何关系。一对父子loader可能实例化自同一个Class,也可能不是,甚至父loader实例化自子类,子loader实例化自父类。假设MyClassLoader继承自ParentClassLoader,我们可以有如下父子loader:
ClassLoader loader1 = new MyClassLoader();
ClassLoader loader2 = new ParentClassLoader(loader1); //参数 loader1为parent
那么双亲委托模型为什么更安全了?因为在此模型下用户自定义的类装载器不可能装载应该由父亲装载器装载的可靠类,从而防止不可靠甚至恶意的代码代替由父亲装载器装载的可靠代码。实际上,类装载器的编写者可以自由选择不用把请求委托给parent,但正如上所说,会带来安全的问题。
4.命名空间及其作用:
每个类装载器有自己的命名空间,命名空间由所有以此装载器为创始类装载器的类组成。
不同命名空间的两个类是不可见的,但只要得到类所对应的Class对象的reference,还是可以访问另一命名空间的类。
例2演示了一个命名空间的类如何使用另一命名空间的类。在例子中,LoaderSample2由系统类装载器装载,LoaderSample3由自定义的装载器loader负责装载,两个类不在同一命名空间,但LoaderSample2得到了LoaderSample3所对应的Class对象的reference,所以它可以访问LoaderSampl3中公共的成员(如age)。
例2不同命名空间的类的访问
/*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();
}
}
}
/*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。
5.运行时包(runtime package):
由同一类装载器定义装载的属于相同包的类组成了运行时包,决定两个类是不是属于同一个运行时包,不仅要看它们的包名是否相同,还要看的定义类装载器是否相同。只有属于同一运行时包的类才能互相访问包可见的类和成员。这样的限制避免了用户自己的代码冒充核心类库的类访问核心类库包可见成员的情况。假设用户自己定义了一个类java.lang.Yes,并用用户自定义的类装载器装载,由于java.lang.Yes和核心类库java.lang.*由不同的装载器装载,它们属于不同的运行时包,所以java.lang.Yes不能访问核心类库java.lang中类的包可见的成员。
6.总结:
在简单讨论了类装载器,双亲委派模型,命名空间,运行时包后,相信大家已经对它们的作用有了一定的了解。命名空间并没有完全禁止属于不同空间的类的互相访问,双亲委托模型加强了Java的安全,运行时包增加了对包可见成员的保护
发表评论
-
微信收货地址共享接口-终极解决
2015-06-25 13:10 8298最近要接入微信的收货地址共享接口,总是不成功,折腾了好 ... -
Java中HashMap的实现原理
2011-04-28 14:30 2721昨天有人来公司面试,因为面试的地方和我坐的地方比较近,所以也听 ... -
java注解(annotation)简介
2010-06-13 10:10 1310[Java 5.0] Annotation – @Deprec ... -
quartz和spring-quartz
2010-06-13 10:03 865quartz和spring-quartz -
Java 线程实例讲解综述
2010-06-13 09:57 979Java 线程实例讲解综述 编写具有多线程能力的程序经常会用 ... -
Java Double 精度问题总结
2010-06-13 09:56 5244使用Java,double 进行运算时,经常出现精度丢失的问题 ... -
eXtremeComponents的eXtremeTable分页特性
2010-05-14 17:27 3276下面是我使用的例子: <ec:table ite ... -
java---final 关键字 和 static 用法
2010-03-17 13:58 836final 关键字 和 static 用法 一、final ... -
java版的escape和unescape方法
2010-03-17 09:21 2494其中unescape方法可以用来解开javascript的es ... -
StatSVN的使用说明
2010-03-04 10:27 998一、 checkout 希望统计的版本或者分支到某个目录(不管 ... -
Velocity语法
2010-03-01 18:01 8341. 变量 (1)变量的 ... -
用KeyTool生成安全证书
2010-02-22 17:14 1087详细请见:Tomcat的帮助文档,:https://local ... -
Spring 注解学习手札
2010-02-10 10:02 774http://snowolf.iteye.com/blog/5 ... -
JDK、JRE、JVM的关系
2010-01-25 11:23 850JDK就是Java Development Kit.简单的说J ... -
Tomcat发布项目方法
2010-01-22 10:46 2561第一种方法:在tomcat中的conf目录中,在server. ... -
理解Java ClassLoader机制
2010-01-21 16:20 846当JVM(Java虚拟机)启动时,会形成由三个类加载器组成的初 ... -
cookie和session的工作机制
2010-01-19 15:19 759转载自:http://hi.baidu.com/jmtbai/ ... -
如何设置Tomcat的JVM虚拟机内存大小
2010-01-18 14:25 920Tomcat本身不能直接在计算机上运行,需要依赖于硬件基础之上 ... -
浅谈设置JVM内存分配的几个妙招
2010-01-18 14:24 1564安装Java开发软件时,默 ... -
java数据库设计中的14个技巧
2009-12-16 14:41 777下述十四个技巧,是许多人在大量的数据库分析与设计实践中,逐步总 ...
相关推荐
类装载器学习一、类加载器的基本概念 类装载器学习一、类加载器的基本概念 类装载器学习一、类加载器的基本概念
java之jvm学习笔记五(实践写自己的类装载器)
因此,基于深度学习的矿车装载状态计数系统可以实现对矿车装载状态的自动检测和计数,提高检测和计数的准确性和速度。 Python作为一种简单易学、功能强大的编程语言,被广泛应用于深度学习领域。Python提供了许多...
学习网上的相关介绍,写成的完整类,可以直接使用,用于动态装载并执行程序集中的方法 也可以使用插件管理域进行动态装载\执行方法\卸载程序域 但日常工作中还是习惯对所有项目引用一个公共的项目(主要是设计接口\...
装载存储传送类指令的作用是把源操作数从源存储器(寄存器)中送到目的操作数指定的寄存器(存储器)里,用于完成数据的读入、保存或传送。 c54x的数据传送指令包括装载指令、存储指令(含条件存储指令...
通过运行时类获取 bean;通过有参构造创建 bean;给 bean 注入集合;scope 作用域;Spring 的继承;Spring 的依赖;Spring 的 p 命名空间;Spring 的工厂方法;IoC 自动装载(Autowire);AOP以及如何使用; 适用...
Ruby是"一种用于迅速和简便的面向对象编程的解释性脚本语言";这意味着什么?...类,继承,方法,等等 单态方法 模块糅合 迭代器和闭包(closures) 以及: 多精度整数 异常处理模式 动态装载 线程
sun提供了各个平台的JVM实现–也是说jvm不是跨平台的,编译好的字节码文件被放在不同的操作系统平台上的jvm所解释执行,这个章节主要解释一下JVM装载类的机制 1.ClassLoader是什么? 一个类如果要被JVM所调度...
单片机类相关论文资料51 msp430 PIC 单片机设计学习资料200个合集: 基于at89c2051+单片机的防盗自动报警电子密码锁系统的设计.pdf 基于at89c2051单片机应用设计.pdf 基于AT89C2051单片机的电子称设计.pdf 基于AT89C...
hasConstructor.java 拥有构造器的类 hasFinalFun.java 拥有最终方法的类 hasRecall.java 可以完成回调功能的类 HasStatic.java 一个简单的拥有静态成员的类 hideMember_1.java 成员隐藏示例1 hideMember_2....
如何系统学习单片机?单片机系统设计的流程是怎样的,需要掌握哪些辅助软件?本篇将针对这些问题一一阐述,为读者掀开单片机完全学习与应用的华丽序幕。 第1章 单片机在哪里 1.1 ■寻找单片机 1.1.1 电磁炉与单片机...
Adriod学习笔记,Adriod入门示例。 总结Android开发的特点 1.布局文件是通过XML实现。 2.文件分类清晰。 3.代码和UI分开,在国际化和程序维护方面有着巨大的作用。如果你的Android程序需要自适应国际化,比如说多国...
2.JVM运行机制.mp4 3.常用JVM配置参数.mp4 4.GC算法与种类.mp4 5.GC参数.mp4 6.类装载器.mp4 7.性能监控工具,mp4 8.Java堆分析.mp4 9.锁.mp4 10.Class文件结构.mp4 11.字节码执行.mp4
virtual在派生类中声明其实现可由重写成员更改的方法或访问器。 volatile指示字段可由操作系统、硬件或并发执行的线程等在程序中进行修改。 9,语句 语句是程序指令。除非特别说明,语句都按顺序执行。C# 具有下列...
其实,它是Location类的一个实例,它还有一个reload()方法可以装载信的URL(用Back按钮不能回退到原页面)。 12) history属性可看成是代表历史URL的一个特殊数组,它的可读length属性表明数组的长度。支持三种方法...
对于长时间装载的ASP.NET页面如何在客户端浏览器中显示进度?).txt 根据不同的dropdownlist选择值选择数据.txt 购物车代码.txt 关于TextBox和Label控件显示数据的问题.在线等.txt 广告代码.txt 获取键盘上任意按键的...
面试题集共分为以下十部分: 一、Core Java: 1 — 95 题1 — 24 页 基础及语法: 1 — 61 题1 — 13 页 异常: 62 — 69 题13 — 15 页 集合: 70 — 80 题15 — 18 页 线程: 81 — 90 题18 — 21 页 ...
TestSuite类:该类是一个测试集,即把相关的TestCase类集合到一起形成一个TestSuiteTestLoader类:该类负责搜索和装载TestCase到TestSuite中。TextTestRunner类:该类负责运行测试用例。TextTestResult类:该类负责存
1、在计算机上学习安装虚拟机 2、在虚拟机上安装操作系统(win98或win2000) 3、实现虚拟机与主机通讯(比如在主机和虚拟机之间实现QQ聊天) 4、在虚拟机上运行软件实验(比如安装VideoPack5软件) 实验原理:所有的...
我最初是为CS Graphics类编写此脚本的,因此我们不必仅拥有用于模型的多维数据集和球体即可学习WebGL。 当时,WebGL唯一的模型加载器是 。 为了使用装载程序,您必须使用整个框架(或进行一些非常认真的修改和录音...