类加载器分析(高新技术)
来源:互联网 发布:java猜拳游戏代码 编辑:程序博客网 时间:2024/06/07 07:09
类加载器分析
一、类加载器
1、什么是类加载器?
加载类的工具,当程序需要的某个类,那么需要通过类加载器把类的二进制加载到内存中,类加载器也是Java类2、类的加载过程
当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。加载:
就是指将class文件读入内存,并为之创建一个Class对象。任何类被使用时系统都会建立一个Class对象。
连接:
验证 是否有正确的内部结构,并和其他类协调一致
准备 负责为类的静态成员分配内存,并设置默认初始化值
解析 将类的二进制数据中的符号引用替换为直接引用
初始化: 这里就不细说了。。。
3、类初始化时机
b.访问类的静态变量,或者为静态变量赋值
c.调用类的静态方法
d.使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
e.初始化某个类的子类
f.直接使用java.exe命令来运行某个主类
4、java.lang.ClassLoader类介绍
java.lang.ClassLoader类的基本职责就是根据一个指定的类的名称,找到或者生成其对应的字节代码,然后从这些字节代码中定义出一个 Java 类,即 java.lang.Class类的一个实例。ClassLoader提供了一系列的方法,比较重要的方法如:
5、类加载器的树状组织结构
Java 中的类加载器大致可以分成两类,一类是系统提供的,另外一类则是由 Java 应用开发人员编写的。5.1、系统提供的类加载器
系统提供的类加载器主要有下面三个:
引导类加载器(bootstrap class loader):它用来加载 Java 的核心库,比如System,String等,是用原生代码(C++)来实现的,并不继承自java.lang.ClassLoader。
扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。 可以通ClassLoader.getSystemClassLoader()来获取它。
5.2、Java 应用开发人员编写的类加载器
属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader
加载过程中会先检查类是否被已加载,检查顺序是自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个classloader已加载就视为已加载此类,保证此类只所有ClassLoader加载一次。而加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。除了引导类加载器之外,所有的类加载器都有一个父类加载器。通过 上面表中给出的 getParent()方法可以得到。对于系统提供的类加载器来说,系统类加载器的父类加载器是扩展类加载器,而扩展类加载器的父类加载器是引导类加载器;对于开发人员编写的类加载器来说,其父类加载器是加载此类加载器 Java 类的类加载器。因为类加载器 Java 类如同其它的 Java 类一样,也是要由类加载器来加载的。一般来说,开发人员编写的类加载器的父类加载器是系统类加载器。类加载器通过这种方式组织起来,形成树状结构。树的根节点就是引导类加载器。
下图中给出了一个典型的类加载器树状组织结构示意图。
5.3、演示类加载器的树状组织结构
package cn.wangjing_10;public class ClassLoaderTree {public static void main(String[] args) {ClassLoader loader = ClassLoaderTree.class.getClassLoader();while (loader != null) {System.out.println(loader.toString());loader = loader.getParent();}}}
程序输出结果是:
sun.misc.Launcher$AppClassLoader@1c0ec97
sun.misc.Launcher$ExtClassLoader@ecb281
6、类加载器的委托机制:
1>当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?①首先当前线程的类加载器去加载线程中的第一个类.
②如果类A中引用了类B,Java虚拟机将使用加载类A的类加载器加载类B
③还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类.
2>每个类加载器加载类时,又先委托给其上级类加载器.
①当所有祖宗类加载器没有加载到类,回到发起者类加载器,如果还加载不了,则抛出ClassNotFoundException异常,它不会 去找发起者类加载器的儿子,因为没有getChild()方法,即使有,有那么多的儿子交给那一个呢?所以干错就不叫给儿子处理了.委托机制有什么好处?集中管理,如果我们写了几个类加载器,都去加载某个类,那么内存中就有多份这个类的字节码。 能不能自己写一个类叫java.lang.System?为了不让我们写System类,类加载采用委托机制,这样可以保证爸爸优先,也就是使用的永远是爸爸的(系统的)System类,而不是我们写的System类.
7、自定义类加载器演示
public class People {public void say(){ System.out.println("hello world!"); }}
class MyClassLoader extends ClassLoader { //类加载器的名称 private String name; //类存放的路径 private String path = "C:\\eclipse_workplace1\\File\\src\\cn\\wangjing_10\\"; MyClassLoader(String name) { this.name = name; } MyClassLoader(ClassLoader parent, String name) { super(parent); this.name = name; } /** * 重写findClass方法 */ @Override public Class<?> findClass(String name) { byte[] data = loadClassData(name); return this.defineClass(name, data, 0, data.length); } public byte[] loadClassData(String name) { try { name = name.replace(".", "//"); FileInputStream is = new FileInputStream(new File(path + name + ".class")); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int b = 0; while ((b = is.read()) != -1) { baos.write(b); } return baos.toByteArray(); } catch (Exception e) { e.printStackTrace(); } return null; }}
public class ClassLoaderTest { public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException { //新建一个类加载器 MyClassLoader cl = new MyClassLoader("myClassLoader"); //加载类,得到Class对象 Class<?> clazz = cl.loadClass("classloader.Animal"); //得到类的实例 People people=(People) clazz.newInstance(); people.say(); } }
- 类加载器分析(高新技术)
- 高新技术:类加载器
- 黑马程序员-高新技术(类加载器)
- 黑马程序员-------(高新技术)类加载器
- Java 高新技术(类加载器)
- 黑马程序员-(高新技术)类加载器
- Java高新技术-类加载器
- Java高新技术 类加载器
- Java高新技术:类加载器
- Java深入(高新技术)(七):类加载器
- 黑马程序员-JAVA 高新技术(类加载器)
- 黑马程序员-高新技术(类加载器与动态代理)
- 黑马程序员——高新技术(类加载器)
- 黑马程序员——高新技术(类加载器)
- 黑马程序员-类加载器与委托机制(高新技术)
- 黑马程序员_高新技术:5)类加载器、代理
- 黑马程序员 (高新技术) 类加载器学习总结
- 高新技术(反射、内省、类加载器、代理)
- 题目1522:包含min函数的栈
- Ubuntu 14.04用户修改更新源和替换软件源的方法
- 待修改P124.41
- C++作业4.17
- php学习笔记之将word文档转化为HTML文件
- 类加载器分析(高新技术)
- android assets下rar文件解压到sd卡
- WLAN基于MAC地址的AP接入控制
- JS魔法堂之实战:纯前端的图片预览
- 父线程用标志变量控制子线程的范例
- android自定义标题栏
- hdu 2060 Snooker(数学题)
- Netty那点事(三)Channel与Pipeline
- adb启动APP