深入研究Java类载入机制
 
类载入是Java程序运行的第一步,研究类的载入有助于了解JVM运行过程,并指导开发人员採取更有效的措施配合程序运行。
研究类载入机制的第二个目的是让程序能动态的控制类载入,比方热部署等,提高程序的灵活性和适应性。
 
一、简单过程
 
Java程序执行的场所是内存,当在命令行下执行:
java HelloWorld
命令的时候,JVM会将HelloWorld.class载入到内存中,并形成一个Class的对象HelloWorld.class。
当中的过程就是类载入过程:
1、寻找jre文件夹,寻找jvm.dll,并初始化JVM;
2、产生一个Bootstrap Loader(启动类载入器);
3、Bootstrap Loader自己主动载入Extended Loader(标准扩展类载入器),并将其父Loader设为Bootstrap Loader。
4、Bootstrap Loader自己主动载入AppClass Loader(系统类载入器),并将其父Loader设为Extended Loader。
5、最后由AppClass Loader载入HelloWorld类。
 
以上就是类载入的最一般的过程。
 
二、类载入器各自搜索的文件夹
 
为了弄清楚这个问题,首先还要看看System类的API doc文档。
 
 
相关值的描写叙述
java.version Java 执行时环境版本号
java.vendor Java 执行时环境供应商
java.vendor.url Java 供应商的 URL
java.home Java 安装文件夹
java.vm.specification.version Java 虚拟机规范版本号
java.vm.specification.vendor Java 虚拟机规范供应商
java.vm.specification.name Java 虚拟机规范名称
java.vm.version Java 虚拟机实现版本号
java.vm.vendor Java 虚拟机实现供应商
java.vm.name Java 虚拟机实现名称
java.specification.version Java 执行时环境规范版本号
java.specification.vendor Java 执行时环境规范供应商
java.specification.name Java 执行时环境规范名称
java.class.version Java 类格式版本
java.class.path Java 类路径
java.library.path 载入库时搜索的路径列表
java.io.tmpdir 默认的暂时文件路径
java.compiler 要使用的 JIT 编译器的名称
java.ext.dirs 一个或多个扩展文件夹的路径
os.name 操作系统的名称
os.arch 操作系统的架构
os.version 操作系统的版本号
file.separator 文件分隔符(在 UNIX 系统中是“/”)
path.separator 路径分隔符(在 UNIX 系统中是“:”)
line.separator 行分隔符(在 UNIX 系统中是“/n”)
user.name 用户的账户名称
user.home 用户的主文件夹
user.dir 用户的当前工作文件夹
 
可惜这个帮助文档并不全,直接用程序打印出来例如以下:
                for (Map.Entry<Object, Object> entry : System.getProperties().entrySet()) { 

                        System.out.println(entry.getKey()+"\t"+entry.getValue()); 

                }
 
java.runtime.name Java(TM) SE Runtime Environment
sun.boot.library.path Q:\jdk6\jre\bin
java.vm.version 14.0-b16
java.vm.vendor Sun Microsystems Inc.
java.vendor.url http://java.sun.com/
path.separator ;
idea.launcher.port 7532
java.vm.name Java HotSpot(TM) Client VM
file.encoding.pkg sun.io
sun.java.launcher SUN_STANDARD
user.country CN
sun.os.patch.level Service Pack 3
java.vm.specification.name Java Virtual Machine Specification
user.dir E:\projects\testScanner
java.runtime.version 1.6.0_14-b08
java.awt.graphicsenv sun.awt.Win32GraphicsEnvironment
java.endorsed.dirs Q:\jdk6\jre\lib\endorsed
os.arch x86
java.io.tmpdir C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\
line.separator
java.vm.specification.vendor Sun Microsystems Inc.
user.variant
os.name Windows XP
sun.jnu.encoding GBK
java.library.path Q:\jdk6\bin;.;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;Q:\jdk6\bin;Q:\JavaFX\javafx-sdk1.2\bin;Q:\JavaFX\javafx-sdk1.2\emulator\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\MySQL Server 5.1\bin;C:\Program
Files\StormII\Codec;C:\Program Files\StormII
java.specification.name Java Platform API Specification
java.class.version 50
sun.management.compiler HotSpot Client Compiler
os.version 5.1
user.home d:\我的文档
user.timezone
java.awt.printerjob sun.awt.windows.WPrinterJob
idea.launcher.bin.path C:\IDEA8\bin
file.encoding UTF-8
java.specification.version 1.6
java.class.path Q:\jdk6\jre\lib\alt-rt.jar;Q:\jdk6\jre\lib\charsets.jar;Q:\jdk6\jre\lib\deploy.jar;Q:\jdk6\jre\lib\javaws.jar;Q:\jdk6\jre\lib\jce.jar;Q:\jdk6\jre\lib\jsse.jar;Q:\jdk6\jre\lib\management-agent.jar;Q:\jdk6\jre\lib\plugin.jar;Q:\jdk6\jre\lib\resources.jar;Q:\jdk6\jre\lib\rt.jar;Q:\jdk6\jre\lib\ext\dnsns.jar;Q:\jdk6\jre\lib\ext\localedata.jar;Q:\jdk6\jre\lib\ext\sunjce_provider.jar;Q:\jdk6\jre\lib\ext\sunmscapi.jar;Q:\jdk6\jre\lib\ext\sunpkcs11.jar;E:\projects\testScanner\out\production\testScanner;C:\IDEA8\lib\idea_rt.jar
user.name Administrator
java.vm.specification.version 1
java.home Q:\jdk6\jre
sun.arch.data.model 32
user.language zh
java.specification.vendor Sun Microsystems Inc.
awt.toolkit sun.awt.windows.WToolkit
java.vm.info mixed mode, sharing
java.version 1.6.0_14
java.ext.dirs Q:\jdk6\jre\lib\ext;C:\WINDOWS\Sun\Java\lib\ext
sun.boot.class.path Q:\jdk6\jre\lib\resources.jar;Q:\jdk6\jre\lib\rt.jar;Q:\jdk6\jre\lib\sunrsasign.jar;Q:\jdk6\jre\lib\jsse.jar;Q:\jdk6\jre\lib\jce.jar;Q:\jdk6\jre\lib\charsets.jar;Q:\jdk6\jre\classes
java.vendor Sun Microsystems Inc.
file.separator \
java.vendor.url.bug http://java.sun.com/cgi-bin/bugreport.cgi
sun.io.unicode.encoding UnicodeLittle
sun.cpu.endian little
sun.desktop windows
sun.cpu.isalist
 
1、Bootstrap Loader(启动类载入器):载入System.getProperty("sun.boot.class.path")所指定的路径或jar。
2、Extended Loader(标准扩展类载入器ExtClassLoader):载入System.getProperty("java.ext.dirs")所指定的路径或jar。在使用Java执行程序时,也能够指定其搜索路径,比如:java -Djava.ext.dirs=d:\projects\testproj\classes HelloWorld
 
3、AppClass Loader(系统类载入器AppClassLoader):载入System.getProperty("java.class.path")所指定的路径或jar。在使用Java执行程序时,也能够加上-cp来覆盖原有的Classpath设置,比如: java -cp ./lavasoft/classes HelloWorld
 
ExtClassLoader和AppClassLoader在JVM启动后,会在JVM中保存一份,而且在程序执行中无法改变其搜索路径。假设想在执行时从其它搜索路径载入类,就要产生新的类载入器。
 
三、类载入器的特点
 
1、执行一个程序时,总是由AppClass Loader(系统类载入器)開始载入指定的类。
2、在载入类时,每一个类载入器会将载入任务上交给其父,假设其父找不到,再由自己去载入。

3、Bootstrap Loader(启动类载入器)是最顶级的类载入器了,其父载入器为null.
 
四、类载入器的获取
 
非常easy,看以下样例
public class HelloWorld { 

        public static void main(String[] args) { 

                HelloWorld hello = new HelloWorld(); 

                Class c = hello.getClass(); 

                ClassLoader loader = c.getClassLoader(); 

                System.out.println(loader); 

                System.out.println(loader.getParent()); 

                System.out.println(loader.getParent().getParent()); 

        } 

}
 
打印结果:
sun.misc.Launcher$AppClassLoader@19821f 

sun.misc.Launcher$ExtClassLoader@addbf1 

null 



Process finished with exit code 0
 
从上面的结果能够看出,并没有获取到ExtClassLoader的父Loader,原因是Bootstrap Loader(启动类载入器)是用C语言实现的,找不到一个确定的返回父Loader的方式,于是就返回null。
 
五、类的载入
 
类载入有三种方式:
1、命令行启动应用时候由JVM初始化载入
2、通过Class.forName()方法动态载入
3、通过ClassLoader.loadClass()方法动态载入
 
三种方式差别比較大,看个样例就明确了:
public class HelloWorld { 

        public static void main(String[] args) throws ClassNotFoundException { 

                ClassLoader loader = HelloWorld.class.getClassLoader(); 

                System.out.println(loader); 

                //使用ClassLoader.loadClass()来载入类,不会运行初始化块 

                loader.loadClass("Test2"); 

                //使用Class.forName()来载入类,默认会运行初始化块 

//                Class.forName("Test2"); 

                //使用Class.forName()来载入类,并指定ClassLoader,初始化时不运行静态块 

//                Class.forName("Test2", false, loader); 

        } 

}
 
public class Test2 { 

        static { 

                System.out.println("静态初始化块运行了!"); 

        } 

}
 
分别切换载入方式,会有不同的输出结果。
 
六、自己定义ClassLoader
 
为了说明问题,先看样例:
package test; 



import java.net.MalformedURLException; 

import java.net.URL; 

import java.net.URLClassLoader; 



/** 

* 自己定义ClassLoader 



* @author leizhimin 2009-7-29 22:05:48 

*/ 

public class MyClassLoader { 

        public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, IllegalAccessException, InstantiationException { 

                URL url = new URL("file:/E:\\projects\\testScanner\\out\\production\\testScanner"); 

                ClassLoader myloader = new URLClassLoader(new URL[]{url}); 

                Class c = myloader.loadClass("test.Test3"); 

                System.out.println("----------"); 

                Test3 t3 = (Test3) c.newInstance(); 

        } 

}
 
public class Test3 { 

        static { 

                System.out.println("Test3的静态初始化块运行了!"); 

        } 

}
 
执行后:
---------- 

Test3的静态初始化块运行了! 



Process finished with exit code 0
 
能够看出自己定义了ClassLoader myloader = new URLClassLoader(new URL[]{url});已经成功将类Test3载入到内存了,并通过默认构造方法构造了对象Test3 t3 = (Test3) c.newInstance();
 
有关ClassLoader还有非常重要一点:
同一个ClassLoader载入的类文件,仅仅有一个Class实例。可是,假设同一个类文件被不同的ClassLoader载入,则会有两份不同的ClassLoader实例(前提是着两个类载入器不能用同样的父类载入器)。

深入研究Java类载入机制的更多相关文章

  1. 深入研究Java类装载机制

    目录 1.为什么要研究java类装在机制? 2.了解类装载机制,对于我们在项目开发中有什么作用? 3.装载实现细节. 4.总结 一.为什么药研究Java类装载机制 java类加载机制,便于我们使用自定 ...

  2. Java虚拟机的类载入机制

    Java虚拟机类载入过程是把Class类文件载入到内存.并对Class文件里的数据进行校验.转换解析和初始化,终于形成能够被虚拟机直接使用的java类型的过程. 在载入阶段,java虚拟机须要完毕下面 ...

  3. java类载入器——ClassLoader

    Java的设计初衷是主要面向嵌入式领域,对于自己定义的一些类,考虑使用依需求载入原则.即在程序使用到时才载入类,节省内存消耗,这时就可以通过类载入器来动态载入. 假设你平时仅仅是做web开发,那应该非 ...

  4. Java 类反射机制分析

    Java 类反射机制分析 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某 ...

  5. JVM系列文章(四):类载入机制

    作为一个程序猿,只知道怎么用是远远不够的. 起码,你须要知道为什么能够这么用.即我们所谓底层的东西. 那究竟什么是底层呢?我认为这不能一概而论.以我如今的知识水平而言:对于Web开发人员,TCP/IP ...

  6. Java类载入器 ClassLoader的解析

    //參考 : http://www.ibm.com/developerworks/cn/java/j-lo-classloader/ 类载入器基本概念 类载入器是 Java 语言的一个创新,也是 Ja ...

  7. Java类载入器原理分析

    一:Java虚拟机中能够安装多个类载入器,系统默认是三个基本的类载入器: Bootstrap  ExtClassLoader  AppClassLoader 类载入器也是Java类.由于其它Java类 ...

  8. DexClassLoader和PathClassLoader类载入机制

    0x00 在DexClassLoader和PathClassLoader载入Dex流程一文中,我们分析了dex文件怎样形成了DexFile结构体.本文中解说类载入机制,实际上就是生成ClassObje ...

  9. Java类载入器(一)——类载入器层次与模型

    类载入器   虚拟机设计团队把类载入阶段中的"通过一个类的全限定名来获取描写叙述此类的二进制字节流"这个动作放到Java虚拟机外部去实现.以便让应用程序自己决定怎样去获取所须要的类 ...

随机推荐

  1. 牛逼的验证码,printf返回值

    牛逼的验证码,如下图, 结果是4321,为什么呢,主要是printf返回值问题?那么printf到底返回什么? 经查阅,printf的返回值是打印的字符个数,因此结果是4321就很明显了.

  2. 50个最受网友欢迎的HTML5资源下载列表

    完整附件下载地址:http://down.51cto.com/data/413867 附件预览: HTML 5游戏源码精选(共含9个游戏源码) http://down.51cto.com/zt/227 ...

  3. WPF界面设计技巧(11)-认知流文档 & 小议WPF的野心

    原文:WPF界面设计技巧(11)-认知流文档 & 小议WPF的野心 流文档是WPF中的一种独特的文档承载格式,它的书写和呈现方式都很像HTML,它也几乎具备了HTML的绝大多数优势,并提供了更 ...

  4. 自己动手写CPU之第六阶段(2)——移动操作指令实现思路

    将陆续上传本人写的新书<自己动手写CPU>(尚未出版),今天是第21篇,我尽量每周四篇 6.2 移动操作指令实现思路 6.2.1 实现思路 这6条移动操作指令能够分为两类:一类是不涉及特殊 ...

  5. 关于cocos2dx3.0 UITextField不能使用退格键删除字符的解决方式

    近日開始将项目移植到cocos2dx 3.0版本号,出现了一些问题,UI方面眼下就发现UITextField控件不能响应退格键或者删除键,在Windows以下调试如此,我開始以为是平台支持不好,后来公 ...

  6. Linux从零到高手的进阶心得(转)

    从2006年毕业至今,从事IT行业已经接近8个年头. 一路走来有很多心路历程和技术心得都写在了51CTO的博客中,不少文字现在看来已显稚嫩,但是这正是我真实的成长之路.这八年,从最基础的网络管理员开 ...

  7. ZOJ 3795 Grouping 求最长链序列露点拓扑

    意甲冠军:特定n积分.m向边条. 该点被划分成多个集合随机的每个集合,使得2问题的关键是无法访问(集合只能容纳一个点) 问至少需要被分成几个集合. 假设没有戒指,接着这个话题正在寻求产业链最长的一个有 ...

  8. swift 笔记 (十八) —— 扩展

    扩展 扩展能够让我们给一个已有的类.结构体.枚举等类型加入�新功能,包含属性和方法,甚至是构造器,下标,支持协议等等... 甚至是我们拿不到源码的类.结构体.枚举,我们依旧能够给它加扩展... 看到这 ...

  9. google多语言通信框架gRPC

    google多语言通信框架gRPC系列(一)概述 gRPC概述 3/26/2016 9:16:08 AM 目录 一.概述 二.编译gRPC 三.C#中使用gRPC 四.C++中使用gRPC 一直在寻找 ...

  10. uva10465(完全背包,要求装满背包)

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&c ...