Java深度历险 读书笔记

[b]1. 深入Java 2 SDK[/b]
JDK与JRE的关系

[img]http://dl.iteye.com/upload/attachment/441695/20d9db2b-e20d-3c50-8031-6ddf245a2872.jpg[/img]

从上图可以得知,如果您装了JDK,那么您的电脑底下一定会有两套JRE、一套位于<jdk安装目录>\jre底下,另外一套位于C:\Program File\Java底下。


[img]http://dl.iteye.com/upload/attachment/441697/b03f65d8-f618-3bcd-9638-9be4bace9867.jpg[/img]

从上图您可以知道,JRE的地位就像一台PC一样,Java虚拟机只是JRE里头的其中一个成员而已,以更技术的角度来说,Java虚拟机只是JRE里头的一个动态链接函数库罢了。
JDK里面的工具几乎是用Java说写的,所以JDK本身就是Java应用程序,因此要使用JDK附的工具来开发Java程序,也必须要自行附一套JRE才行,这就是<JDK安装目录>\jre底下需要一套JRE的原因。而位于Program File\底下的那套JRE就是拿来执行我们自己所写的Java应用程序。不过,两套中任何一套JRE都可以拿来执行我们所写的Java应用程序,可是JDK内附的开发工具在预设使用包装器(.exe)来启动的情况下,都会自己去选用<jdk安装目录>\jre底下那套JRE。

[b]2. 深入类别载入器[/b]
类别载入器的功能,就是把类别从静态的硬盘里(.class档),复制一份放到记忆体之中,并做一些初始化的工作,让这个类别“活起来”,其他人就能够使用它的功能。
像基础类别函数库这样的载入方法我们叫做预先载入(pre-loading),这是因为基础类别函数库里头的类别大多是Java程序执行时所必备的类别,所以为了不要老是做浪费时间的I/O动作(读取档案系统,然后将类别档载入记忆体之中),预先载入这些类别会让Java应用程式在执行时速度稍微快一些。相对来说,我们自己所写的类别值载入方式,叫做依需求载入(load-on-demand),也就是Java程序真正用到该类别的时候,才真的把类别档从档案系统之中载入记忆体。
只有单独宣告(如:B类别)而已,是不会促使类别载入器帮我们载入类别的,只有实体化指令(new XXX())才会让类别载入器帮我们载入该类别。
依需求载入的优点是节省记忆体,但是仍有其缺点,举例来说,当程序第一次用带该类别的时候,系统就必须花一些额外的事件来载入该类别,使得整体执行效能受到影响,尤其是由数以万计的类别所构成的Java程序。可是往后需要用到该类别时,由于类别在初次载入之后就会被永远存放在记忆体之中,直到Java虚拟机关闭,所以不再需要花费额外的事件来载入。
Java提供两种方法来达成动态性。一种是隐式的(implicit),另一种是显式的(explicit)。显示的方法,又分成两种方式,一种是由java.lang.Class里面的forName()方法,另一种则是由java.lang.ClassLoader里面的loadClass()方法。您可以任意选用其中一种方法。

[img]http://dl.iteye.com/upload/attachment/441699/c152f610-313e-317e-aa30-f8beec137419.jpg[/img]

Class c = Class.forName(“classA”);
Object o = c.newInstance();
pulbic static Class forName(String name, Boolean initialize, ClassLoader loader)
如果第二个参数给定的是false,那么就只会命令类别载入器载入该类别,但不会叫用其静态初始话区块,只有等到整个程式第一次实体化某个类别时,静态初始化区块才会被叫用。
在Java之中,每个类别都是由某个类别载入器(ClassLoader的实体)来载入,因此,Class类别的实体中,都会有栏位记录着载入它的ClassLoader的实体(注意:如果该栏位是null,并不代表它不是类别载入器说载入,而是代表这个类别由bootstrap loader,也有人称root loader说载入,只不过因为这个载入器并不是Java所写成,所以编辑上没有实体。

类别载入器的阶层实体(classloader hierarchy)
Bootstrap Loader所做的初始工作中,除了也做一些基本的初始化动作之外,最重要的就是载入定义在sun.misc命名空间底下的Launcher.java之中的ExtClassLoader,并设定其Parent为null,代表其父载入器为Bootstrap Loader。然后Bootstrap Loader在要求载入定义于sun.misc命名空间底下的Launcher.java之中的AppClassLoader,并设定其Parent为之前产生的ExtClassLoader实体。这里要请大家注意的是,Launcher$ExtClassLoader.class与Launcher$AppClassLoader.class都是由Bootstrap Loader所载入,所以 Parent和由哪个类别载入器载入没有关系。

[img]http://dl.iteye.com/upload/attachment/441701/c4143437-9ad6-3fcf-b168-c20c3fdb2dde.jpg[/img]

类别载入器有载入类别的需求时,会先请示其Parent使用其搜索路径帮忙载入,如果Parent找不到,那么才由自己按照自己的搜索路径搜寻类别。类别载入器可以看到Parent所载入的所有类别,但是反过来并非如此。
类别载入器的功用

[img]http://dl.iteye.com/upload/attachment/441703/b5c2508d-327c-3e19-bc6a-2d8e531b4bf8.jpg[/img]

这张图说明了两件事器,第一,假设我们利用URLClassLoader到网络上的任何地方下载了其他的类别,URLClassLoader都不可能下载AppClassLoader、ExtClassLoader、或者Bootstrap Loader可以找到的同名名称(指全名,套件名称+类别名称),因此,蓄意破坏者根本没有机会植入有问题的程序码于我们的电脑之中。其二,类别载入器无法看到其他相同界称之类别载入器说载入的类别。

Bootstrap Loader的搜索路径%/lib/rt.jar:%/lib/i18n.jar:%/lib/sunrsasign.jar:%/lib/jsse.jar:%lib/jce.jar:%/lib/charsets.jar:%/classes
ExtClassLoader的搜索路径%/lib/ext/下的文件夹及其jar,通过-Dsun.boot.class.path=…设置
AppClassLoader的搜索路径通过-classpath/-cp设置
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值