深入研究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. 强势围观,CSDN代码引用bug

    看我写的一篇blog  http://blog.csdn.net/laijieyao/article/details/41014355,在代码上引用了微软雅黑的字体,结果代码显示出来把我给惊呆了 竟然 ...

  2. 学习 easyui 之二:jQuery 的 ready 函数和 easyloader 的加载回调函数

    Ready 事件不一定 ready 使用 easyloader 的时候,必须要注意到脚本的加载时机问题,easyloader 会异步加载模块,所以,你使用的模块不一定已经加载了.比如下面的代码. &l ...

  3. ecshop 调用其他数据库中的商品

    ecshop中修改includes/cls_ecshop.php中第53行 function table($str) { /* if($str=='goods'){ return '`ecshop3' ...

  4. java去全半角空格,trim(), replaceAll(" +",""),replaceAll("\\s*", ""), replaceAll(" | ", "")

    JAVA中去掉空格 . String.trim() trim()是去掉首尾空格 .str.replace(" ", ""); 去掉所有空格,包括首尾.中间 St ...

  5. Json,Gson,FastJson解析笔记

    Json,Gson,FastJson解析笔记 1.将JavaBean转换成Json对象: public static String CreatJsonFromObject(Object key,Obj ...

  6. Akka边学边写(3)-- ByteString介绍

    Akka的IO层设计能够參考这篇文档,本文简介一下ByteString的设计. Immutable消息 Actor之间是通过消息沟通的.但为了避免同步问题,消息必须是Immutable. 因此.Akk ...

  7. mongodb之java CRUD 简单操作

    我下载的是 mongo-2.8.0.jar — Version 2.8.0 打开mongo shell -- 新建数据库test --( use test) 打开eclipse新建工程,把junit, ...

  8. Hadoop-2.2.0中国文档—— MapReduce 下一代 -- 公平调度

    目的 此文档描写叙述了 FairScheduler, Hadoop 的一个可插入式的调度器,同意 YARN 应用在一个大集群中公平地共享资源. 简单介绍 公平调度是一种分配资源给应用的方法.以致到最后 ...

  9. 行人检测(Pedestrian Detection)资源整合

    一.纸 评论文章分类: [1] D. Geronimo, and A. M.Lopez. Vision-based Pedestrian Protection Systems for Intellig ...

  10. .net机试题总结

    1.下面是一个由*号组成的4行倒三角形图案.要求:1.输入倒三角形的行数,行数的取值3-21之间,对于非法的行数,要求抛出提示“非法行数!”:2.在屏幕上打印这个指定了行数的倒三角形. ******* ...