`
jja1982
  • 浏览: 112541 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Java深度历险 读书笔记

    博客分类:
  • J2SE
阅读更多
1. 深入Java 2 SDK
JDK与JRE的关系



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




从上图您可以知道,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。

2. 深入类别载入器
类别载入器的功能,就是把类别从静态的硬盘里(.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()方法。您可以任意选用其中一种方法。



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和由哪个类别载入器载入没有关系。



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



这张图说明了两件事器,第一,假设我们利用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设置


  • 大小: 44.1 KB
  • 大小: 36.1 KB
  • 大小: 31.9 KB
  • 大小: 53.6 KB
  • 大小: 44.5 KB
1
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics