[Java Platform, Standard Edition Tools Reference ]第一章

Home: Java Platform, Standard Edition (Java SE) 8 Release 8

https://docs.oracle.com/javase/8/docs/technotes/tools/windows/index.html

这一章节要介绍的内容:

How the Java Runtime Finds Classes

jvm查找and加载class的顺序:
1.Bootstrap class:就是启动程序classes,一般是指rt.jar中的class和一些其他jar包中的类
2.Extension class: 扩展classes,使用了Java的扩展机制,位于jre/lib/ext目录中
3.User classes :用户自定义的class,也就是我们自己写的java生成的class文件或者第三方的一些class。要让jvm能找到并加载这些类,需要在命令行中使用-classpath或者在环境变量中设置CLASSPATH 才行。

How the Java Runtime Finds Bootstrap Classes(jvm是如何查找和加载上面说的Bootstrap class的)
jvm会通过sun.boot.class.path这个系统属性中设置的值去加载Bootstrap classes, 可以System.getProperty("sun.boot.class.path")方法查看包含classes的jar文件,一般结果如下:
【D:\software\Java\jre6\lib\resources.jar;D:\software\Java\jre6\lib\rt.jar;D:\software\Java\jre6\lib\sunrsasign.jar;D:\software\Java\jre6\lib\jsse.jar;
D:\software\Java\jre6\lib\jce.jar;D:\software\Java\jre6\lib\charsets.jar;D:\software\Java\jre6\lib\modules\jdk.boot.jar;D:\software\Java\jre6\classes】
 当然,如果想要指定设置不同的启动程序类路径,可以使用 –Xbootclasspath设置不同的启动程序类路径(不过一般来说是没有必要指定其他位置的)

注意:关于jdk的tools,已经不在作为bootstrap classes了,被单独放到了\lib\tools.jar,它现在是被作为User classes了,一般是在user class path中指定了他的位置来加载。


How the Java Runtime Finds Extension Classes
jre\lib\ext中的jar文件被称为Extentsion classes。这个文件夹中只要jar或者zip文件中的class文件才能被jvm识别并加载,如果你在这个文件夹中直接放一个class文件,这个文件是不会被jvm加载的。
如果这个文件夹中存在的多个jar中有相同名字的class文件,那么重名的类有可能就不能被加载,也就不能不使用了。就会出现找不到类的现象。

How the Java Runtime Finds User Classes
要想让jvm找到User Classes,就必须设置user class path,这个path中的jar文件,或者zip文件或者文件夹中的所有class文件都会被jvm找到后进行加载。
user class path是一个字符串,一般这个值是放在java.class.path系统属性中,jvm一般可以从下面几个位置来查找加载User Classes:
 1. 默认值.,意味着用户类文件为当前目录下的所有类文件或者该目录下包中的类文件。
 2. CLASSPATH环境变量的值,该值将会覆盖默认值。
 3. -cp或者-classpath命令行选项指定的值,该值将覆盖默认值和CLASSPATH的值。
 4. -jar选项执行的jar文件,该值将覆盖掉所有其它的值,即默认值,CLASSPATH的值和-cp或-classpath指定的值。如果使用了-jar选项,所有的用户类文件必须为jar文件中的类文件。

How the Java Runtime Finds JAR-class-path Classes

这一节的要讲的是,当我们的jar中的class类文件中应用了其他的jar文件中的类(比如,你的java代码中使用了apache.common.lang3的StringUitl这个类),那么你怎样让jvm知道去哪里查找这个StringUtil这个类。
这就需要用到manifest这个文件,一个jar文件通常都包含一个manifest文件,这个文件中列出jar文件的一些信息。如下(jfr.jar):

Manifest-Version: 1.0
Implementation-Vendor: Oracle Corporation
Implementation-Title: Java Runtime Environment
Implementation-Version: 1.8.0_51
Class-Path: lib/commons-lang-2.6.jar

 这个Manifest文件中,有一个Class-Path,他的作用就是告诉jvm,我的jar中的类代码中,用到了一个第三方的commons-lang-2.6.jar中的类,jvm你从Class-Path设置的路径去找他们。


如果还不太明白Class-Path的,可以参考下面文章:Java工程打包及MANIFEST.MF文件编写的注意事项_NearEast的专栏-CSDN博客

下面通过一个实例来说明一下:
首先下载commons-lang-2.6.jar,然后放到桌面的lib文件夹下。
java代码如下(代码没报错,是因为在idea中引入了桌面lib文件夹下的commons-lang-2.6.jar):

 对应的Manifest.xml文件如下:

Manifest-Version: 1.0
Class-Path: lib/commons-lang-2.6.jar
Main-Class: com.lhb.practice.jse.Test

这里需要注意的是这里的Class-Path中的路径的值表示的是相对于我们工程打包后的jar所放的位置,另外我们引用的第三方jar不能放到我们工程里面(lib文件夹不能放到工程中),因为jvm不识别。如下:
 


最后运行下面命令就可以看到结果了:

C:\Users\liuhb\Desktop>java -jar java-practice.jar
Hello World

 如果我们不在Manifest.xml中使用Class-Path指定common-lang-2.6.jar,那么程序运行时会报错,找不到类StringUtil.因为jvm不知道该去那里去查找并加载StringUtil这个类。
通过JAR清单class-path访问的类按以下顺序找到:

  1. 通常,JAR清单class-path中引用的类,会被当作当前JAR归档文件的一部分。
  2. 但是,如果JAR清单class-path指向已经搜索过的JAR文件(例如,扩展目录或在类路径中较早列出的JAR文件),则不会再次搜索该JAR文件(此优化可提高效率并防止循环搜索)。 将只搜索在类路径中较早的位置中出现的JAR文件。
  3. 如果将当前JAR归档文件安装到扩展目录,则忽略它定义的任何JAR清单class-path。 扩展所依赖的所有类都会被假定是SDK的一部分,或者已作为扩展安装。

How the javac and javadoc Commands Find Classes

 javac和javadoc命令是如何查找class的呢?
....待更新

Class Loading and Security Policies

...待更新

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值