JAVA学习篇--Java类加载
由来:
与普通程序不同的是,Java程序(class文件)并非本地的可执行程序(解释性语言)。
当执行Java程序时。首先执行JVM(Java虚拟机),然后再把Javaclass载入到JVM里头执行,负责载入Javaclass的这部分就ClassLoader。
中文叫做类载入器。
类载入器就好比一个代理,你须要什么。我通过类载入器将你须要的内容返回给你!
类载入器有什么作用?
当程序须要的某个类,那么须要通过类载入器把类的二进制载入到内存中.
解释:
类载入器也是Java类,由于其它是java类的类载入器本身也要被类载入器载入,显然必须有第一个类载入器不是java类,这正是BootStrap。
Java虚拟机中的全部类装载器採用具有父子关系的树形结构进行组织。在实例化每一个类装载器对象时,须要为其指定一个父级类装载器对象或者默认採用系统类装载器为其父级类载入。
Java类载入器:
Java中的类载入器大致能够分成两类。一类是系统提供的。另外一类则是由 Java 应用开发者编写的。
系统提供的类载入器主要有以下三个:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGVqaW5neXVhbjY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
引导类载入器(bootstrap classloader):
它用来载入 Java 的核心库,是用原生代码来实现的,并不继承自java.lang.ClassLoader。
扩展类载入器(extensions classloader):
它用来载入 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库文件夹。该类载入器在此文件夹里面查找并载入 Java 类。
系统类载入器(system classloader):
它依据 Java 应用的类路径(CLASSPATH)来载入 Java 类。一般来说。Java 应用的类都是由它来完毕载入的。能够过ClassLoader.getSystemClassLoader() 来获取它。
关系:
能够简单理解它们三者之间是父与子的关系。不同的是每一个ClassLoader本身仅仅能分别载入特定位置和文件夹中的类,但它们能够托付其它的类装载器去载入类。这也就是类载入器的托付模式。托付的过程是子类托付父类!
除了系统提供的类载入器以外,开发者能够通过继承java.lang.ClassLoader 类的方式实现自己的类载入器,以满足一些特殊的需求。
类载入器的托付机制(双亲委派机制):
1>当Java虚拟机要载入一个类时,究竟派出哪个类载入器去载入呢?
①首先当前线程的类载入器去载入线程中的第一个类.
②假设类A中引用了类B,Java虚拟机将使用载入类A的类载入器载入类B
③还能够直接调用ClassLoader.loadClass()方法来指定某个类载入器去载入某个类.
2>每一个类载入器载入类时,又先托付给其上级类载入器.
①类装载器一级级托付到BootStrap类载入器,当BootStrap无法载入当前所要载入的类时,然后才一级级回退到子孙类装载器去进行真正的载入。当回退到最初的类装载器时,假设它自己也不能完毕类的装载,那就应报告ClassNotFoundException异常。
简单解释双亲委派机制:
为了安全。java中有String或者其它的核心类,我们想覆盖是覆盖不了的,由于我们自己写的类都属于在classpath路径下。那classpath的装载器都是系统类装载器,即使我们写了一个一模一样的String,它也会一直请求,一直请求到根,假设上面有一个能载入,比如根,那么它就用根载入那个对象给我们返回,我们自己的永远载入不上。这种话我们不至于破坏java的核心库
代码演示样例:
public class Test {
public static void main(String[] args) {
//载入器:sun.misc.Launcher$AppClassLoader
System.out.println(Test.class.getClassLoader().getClass().getName());
//载入器:BootStrap(loader为null的情况)
System.out.println(System.class.getClassLoader());//
System.out.println("----------------查看类载入器的层次结构关系-------------------");
ClassLoader loader = Test.class.getClassLoader();
while(loader != null){
System.out.println(loader.getClass().getName());
loader = loader.getParent();
}
System.out.println(loader);
}
/**
* 执行结果:
* sun.misc.Launcher$AppClassLoader
null
----------------查看类载入器的层次结构关系-------------------
sun.misc.Launcher$AppClassLoader
sun.misc.Launcher$ExtClassLoader
null
*/
}
能不能自己写一个类叫java.lang.System?
为了不让我们写System类,类载入採用托付机制,这样能够保证爸爸优先,也就是使用的永远是爸爸的(系统的)System类,而不是我们写的System类.
设计动机:
Java 虚拟机是怎样判定两个 Java类是同样的呢?
Java虚拟机不仅要看类的全名是否同样,还要看载入此类的类载入器是否一样。
仅仅有两者都同样的情况,才觉得两个类是同样的。即便是同样的字节代码,被不同的类载入器载入之后所得到的类。也是不同的。
比方一个Java 类com.example.Sample。编译之后生成了字节代码文件 Sample.class。两个不同的类载入器 ClassLoaderA 和ClassLoaderB 分别读取了这个 Sample.class 文件,并定义出两个 java.lang.Class 类的实例来表示这个类。这两个实例是不同样的。
对于Java 虚拟机来说,它们是不同的类。
了解了以上这一点之后,就能够理解设计动机了,这样的托付机制是为了保证Java 核心库的类型全。
全部 Java 应用都至少须要引用 java.lang.Object 类。也就是说在执行的时候,java.lang.Object这个类须要被载入到 Java 虚拟机中。假设这个载入过程由 Java 应用自己的类载入器来完毕的话。非常可能就存在多个版本号的java.lang.Object类,并且这些类之间是不兼容的。通过托付机制,对于 Java 核心库的类的载入工作由引导类载入器来统一完毕。保证了
Java 应用所使用的都是同一个版本号的Java 核心库的类。是互相兼容的。
类载入器与 Web 容器:
对于执行在容器中的 Web 应用来说。类载入器的实现方式与一般的 Java 应用有所不同。不同的 Web 容器的实现方式也会有所不同。
以Apache Tomcat 来说,每一个 Web 应用都有一个相应的类载入器实例。该类载入器也使用托付机制,所不同的是它是首先尝试去载入某个类。假设找不到再托付给父类载入器。这与一般类载入器的顺序是相反的。这是
Java Servlet 规范中的推荐做法。其目的是使得 Web应用自己的类的优先级高于 Web 容器提供的类。
这样的托付的一个例外是:Java 核心库的类是不在查找范围之内的。
这也是为了保证 Java核心库的类型安全。
Tomcat载入器:
和第一幅图有什么关系呢?
本图是基于第一幅图(java自带机制)的又一层封装,它是基于第一幅图的,仅仅是tomcat在java的基础上自己定义了一些非核心类库的载入器,以供用户使用!
总结:
绝大多数情况下。对于Web应用的开发者不须要考虑与类载入器相关的细节。可是当出现ClassNotFoundException异常我们能大概了解问题所在。
以下给出几条简单的原则:
每一个 Web 应用自己的 Java类文件和使用的库的 jar 包,分别放在 WEB-INF/classes和 WEB-INF/lib文件夹以下。
多个应用共享的 Java 类文件和 jar包。分别放在 Web 容器指定的由全部 Web 应用共享的文件夹以下。
当出现找不到类的错误时,检查当前类的类载入器和当前线程的上下文类载入器是否正确。这些原则也是依据java类载入器和自己定义载入器的实现方式总结而来。须要我们简单的理解!
版权声明:本文博客原创文章,博客,未经同意,不得转载。
JAVA学习篇--Java类加载的更多相关文章
- JAVA学习篇--JAVA两种编程模式控制
在Drp项目中,解说了两种编程模式Model 1和Model2.以下是对这两种模式的简单理解.以及因为Model2是基于MVC架构的模式,就将我们易混淆的MVC与我们之前学的三层架构进行对照学习一下. ...
- [java学习笔记]java语言核心----面向对象之this关键字
一.this关键字 体现:当成员变量和函数的局部变量重名时,可以使用this关键字来区别:在构造函数中调用其它构造函数 原理: 代表的是当前对象. this就是所在函数 ...
- [java学习笔记]java语言核心----面向对象之构造函数
1.构造函数概念 特点: 函数名与类名相同 不用定义返回值类型 没有具体的返回值 作用: 给对象进行初始化 注意: 默认构造函数 多个构造函数是以重载出现的 一个类中如果 ...
- [ Java学习基础 ] Java构造函数
构造方法是类中特殊方法,用来初始化类的实例变量,它在创建对象(new运算符)之后自动调用. Java构造方法的特点如下: 构造方法名必须与类名相同. 构造方法没有任何返回值,包括void. 构造方法只 ...
- [ Java学习基础 ] Java的继承与多态
看到自己写的东西(4.22的随笔[ Java学习基础 ] Java构造函数)第一次达到阅读100+的成就还是挺欣慰的,感谢大家的支持!希望以后能继续和大家共同学习,共同努力,一起进步!共勉! ---- ...
- [ Java学习基础 ] Java的抽象类与接口
一.抽象类 1. 抽象类 Java语言提供了两种类:一种是具体类:另一种是抽象子类. 2. 抽象类概念: 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的 ...
- Java基础篇(JVM)——类加载机制
这是Java基础篇(JVM)的第二篇文章,紧接着上一篇字节码详解,这篇我们来详解Java的类加载机制,也就是如何把字节码代表的类信息加载进入内存中. 我们知道,不管是根据类新建对象,还是直接使用类变量 ...
- 8.6(java学习笔记)类加载过程及类加载器
一.类加载 1.加载 将class字节码加载到内存中,同时在方法区形成改类运行时数据结构. 同时在堆中产生一个Class对象,反射就是获取这个对象并对其进行操作. 2.链接 2.1验证:验证加载的类信 ...
- 学习Java第一篇——Java 安装及环境搭配
内容提要: 1.下载JDK: 2.安装JDK: 3.配置JDK; 第一,下载JDK: 1.登陆网址:www.oracle.com 2.点击 Downloads 3.选择 Java SE 4.选择 ...
随机推荐
- jquery经常使用事件(整理)
Jquery事件 (一).事件列表. 1.blur() 当失去焦点时触发.包含鼠标点击离开和TAB键离开. 2.change() 当元素获取焦点后,值改变失去焦点事触发. 3.click() 当鼠标单 ...
- 讲座:html5于canvas疯狂的炮轰实现
<html> <head> <title>坎农</title> <script src="../js/jscex.jscexRequir ...
- 遗传算法解决旅行商问题(TSP)
这次的文章是以一份报告的形式贴上来,代码只是简单实现,难免有漏洞,比如循环输入的控制条件,说是要求输入1,只要输入非0就行.希望会帮到以后的同学(*^-^*) 一.问题描述 旅行商问题(Traveli ...
- Codeforces Round #256 (Div. 2)——Multiplication Table
题目链接 题意: n*m的一个乘法表,从小到大排序后,输出第k个数 (1 ≤ n, m ≤ 5·105; 1 ≤ k ≤ n·m) 分析: 对于k之前的数,排名小于k:k之后的数大于,那么就能够採用 ...
- 使用 Visual Studio 对exe文件进行数字签名
使用"VS2013 开发人员命令提示"运行签名工具.转到要签名的文件目录运行命令: signtool sign /a 要签名的程序.exe signtool 的相关命令 Usage ...
- SQL Server 2008 R2 性能计数器详细列表(五)
原文:SQL Server 2008 R2 性能计数器详细列表(五) SQL Server:SQL Statistics 对象: 监视编译和发送到 SQL Server 实例的请求类型 SQL Ser ...
- opengl编程指南
第一章 opengl简单介绍 1.1 什么是opengl opengl是图形硬件的一种软件接口. 1>渲染(rendering)是计算机依据模型创建图像的过程. 2>模型(m ...
- C++输出IP地址段内的合法地址
近半年的Intel实习生活快要结束了.马上要找工作了,这段时间打算把以前的知识复习复习,顺便在这里记录一下.这是当时去Intel面试的时候,面试官问的一道题.当时因为时间关系,只让我提供一个思路,并没 ...
- VS2013上利用InstallShield2013LimitedEdition/C#生成安装包
1.文件-新建项目-其它项目类型-安装和部署 一開始是没有InstallShield2013LimitedEdition这个软件的.你须要去站点上填写信息而且下载 2.填写信息下载 訪问站点:http ...
- Android 异步消息处理机制 让你在深入了解 Looper、Handler、Message之间的关系
转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/38377229 ,本文出自[张鸿洋的博客] 非常多人面试肯定都被问到过,请问And ...