JAVA class path解惑

  1. 翻译自oralce官网

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

  1. 概要

  The class path is the path that the Java runtime environment searches for classes and other resource files. The class search path (more commonly known by the shorter name, “class path”) can be set using either the -classpath option when calling a JDK tool (the preferred method) or by setting the CLASSPATH environment variable. The -classpath option is preferred because you can set it individually for each application without affecting other applications and without other applications modifying its value.

  class path(类路径)是Java运行时环境搜索类和其他资源文件的路径。 在使用JDK相关工具时可以使用 -classpath 选项(首选推荐)或通过设置 CLASSPATH 环境变量来设置类搜索路径。 首选推荐-classpath选项,因为您可以为每个应用程序分别设置类路径,而不会影响其他应用程序,也无需其他应用程序修改其类路径值。

  指定类路径的方式可以使用如下命令:

C:> sdkTool -classpath classpath1;classpath2...

  或者

C:> set CLASSPATH=classpath1;classpath2...

sdkTool
  命令行工具,例如java,javac,javadoc或apt。 有关清单,请参见JDK工具。

classpath1;classpath2
  .jar,.zip或.class文件的类路径。 每个类路径应以文件名或目录结尾,具体取决于您将类路径设置为:

  • 对于包含.class文件的.jar或.zip文件,类路径以.zip或.jar文件的名称结尾。
  • 对于未命名包中的.class文件,类路径以包含.class文件的目录结尾。
  • 对于命名包中的.class文件,类路径以包含“root”包(完整包名称中的第一个包)的目录结尾。

  多个路径由分号(Windows)/冒号(Linux)分隔。 使用set命令(=等号周围省略空格非常重要)。默认的类路径是当前目录。 设置CLASSPATH变量或使用-classpath命令行选项将覆盖默认值,因此,如果要在搜索路径中包括当前目录,则必须在新设置中包括“.”。既不是目录也不是归档文件(.zip或.jar文件)或*的类路径将被忽略。

  1. 描述

  类路径告诉JDK工具和应用程序在哪里可以找到第三方和用户定义的类(不是Java扩展或Java平台的的类)。 类路径需要找到您使用javac编译器编译过的所有类(它的默认路径是当前目录)。

  JDK,JVM和其他JDK工具按顺序依次搜索Java平台(bootstrap引导)类,任何扩展类和类路径来查找类(有关搜索策略的详细信息,请参见https://docs.oracle.com/javase/8/docs/technotes/tools/findingclasses.html)。
  大多数应用程序的类库都可以利用此机制进行扩展。 仅当您要加载以下类时才需要设置类路径:
(a)不在当前目录或其任何子目录中,并且
(b)不在扩展机制指定的位置。

  您可以在调用JVM或其他JDK工具时使用JDK工具的-classpath选项或使用CLASSPATH环境变量来更改类路径。 与设置CLASSPATH环境变量相比,更推荐使用-classpath选项,因为您可以为每个应用程序分别设置类路径,而不会影响其他应用程序,也无需其他应用程序修改其值。

  类可以存储在目录(文件夹)中或归档文件(.jar .zip)中。 Java平台类存储在rt.jar中。

  如果您的CLASSPATH环境变量设置为不正确的值,或者您的启动文件或脚本设置了错误的路径,则可以使用以下方法取消设置CLASSPATH:

C:> set CLASSPATH=

  该命令仅针对当前命令提示符窗口取消设置CLASSPATH。 您还应该删除或修改启动设置,以确保将来的会话中使用正确的CLASSPATH设置。

  1. 了解类路径通配符

  类路径可以包含基本名称通配符*,这被认为等效于指定目录中所有扩展名为.jar或.JAR的文件的列表。 例如,类路径 foo/* 指定名为foo的目录中的所有JAR文件。 仅由 * 组成的类路径将展开为当前目录中所有jar文件的列表。

  包含 * 的类路径并不会匹配类文件(.class)。 要在单个目录foo中同时匹配类(.class)和JAR文件,请使用 foo;foo/* 或 foo/*;foo。 顺序决定是否在foo中的JAR文件之前加载foo中的类和资源,反之亦然。

  子目录不是递归搜索的。 例如,foo/* 仅在foo中查找JAR文件,而不在foo/bar,foo/baz等中查找。

  在扩展类路径目录中的JAR文件的加载顺序不能被保证,并且可能因平台而异,甚至在同一台计算机上有时也有所不同。 结构良好的应用程序不应依赖于任何特定顺序。 如果需要特定的顺序,则可以在类路径中显式枚举JAR文件。

  通配符的展开工作是在类加载过程的早期(在程序的main方法被调用之前)进行的。 类路径中包含通配符的每个元素都将由(可能为空)通过枚举命名目录中的JAR文件而生成的元素序列替换。 例如,如果目录foo包含a.jar,b.jar和c.jar,则将类路径foo/*展开为foo/a.jar; foo/b.jar; foo/c.jar(加载顺序不能被保证),并且该字符串将是系统属性java.class.path的值。

  CLASSPATH环境变量与-classpath(或-cp)命令行选项没有任何区别。 也就是说,在以上的这些情况下通配符适用性是一样的。 但是,在类路径jar-manifest(MANIFEST.MF)中不支持类路径通配符。

  1. 了解 类路径 和 包名称 的区别

  Java类通常按照包(package)进行组织,这些包(package)对应文件系统中的目录。 但是,与文件系统又有所不同,当指定包名称时,要指定整个包名称(永远不要只包含其中的一部分)。 例如,java.awt.Button的包名称始终为java.awt。

例如,假设您希望Java运行时在utility.myapp包中找到一个名为Cool.class的类。
如果该目录的路径为C:\java\MyClasses\utility\myapp,则应设置类路径为C:\java\MyClasses。

  要运行该应用程序,可以使用以下JVM命令:

C:> java -classpath C:\java\MyClasses utility.myapp.Cool

  当应用程序运行时,JVM使用类路径查找utility.myapp软件包中定义的任何Cool.class类。

请注意,在命令中指定的软件包名称必须是整个包名称。 例如,不能将类路径设置为C:\java\MyClasses\utility 并使用命令java myapp.Cool。 这会找不到该类。

  您可能想知道程序包名称在类定义中是如何存在的。答案是,程序包名称是该类的一部分,除非重新编译该类,否则无法修改。

注意:包规范机制的一个有趣结果是,属于同一包的文件实际上可能存在于不同目录中。 每个类的软件包名称都相同,但是每个文件的路径可能从类路径中的不同目录开始。

  1. 文件夹和档案文件

  如果将类存储在目录(文件夹)中,例如c:\java\MyClasses\utility\myapp,则类路径需要指向包含包名称第一个元素的目录。 (在此例下,类路径就是C:\java\MyClasses,因为程序包名称是utility.myapp。)

  但是,当类存储在存档文件(.zip或.jar文件)中时,类路径是.zip或.jar文件的路径,包括该文件名的路径。 例如,要使用.jar文件中的类库,该命令将如下所示:

C:> java -classpath C:\java\MyClasses\myclasses.jar utility.myapp.Cool
  1. 多个路径指定

  要查找C:\java\MyClasses以及C:\java\OtherClasses目录下的类,那么请将类路径设置为:

C:> java -classpath C:\java\MyClasses;C:\java\OtherClasses ...

  请注意,两条路径用分号(windows)/冒号(linux)分隔。

  1. 路径顺序

  如果指定了多个类路径,顺序很重要。 Java解释器将按照它们在类路径变量中出现的顺序在目录中查找类。 在上面的示例中,Java解释器将首先在目录C:\java\MyClasses中查找所需的类。 只有在该目录中找不到名称正确的类时,解释器才会在C:\java\OtherClasses目录中查找。

  1. Java启动器如何查找类

  Java启动器java启动Java虚拟机。 虚拟机按以下顺序搜索和加载类:

  1. Bootstrap classes - Java平台的类,包括rt.jar和其他几个重要的jar文件中的类。
  2. Extension classes - 使用Java扩展机制的类。 这些文件存在于扩展目录中的.jar文件。
  3. User classes - 开发人员和第三方定义的不利用扩展机制的类。 您可以在命令行上使用-classpath选项(首选)或使用CLASSPATH环境变量来标识这些类的位置。

  实际上,这三个搜索路径被合并形成一个简单的类路径。 这类似于“扁平”类路径,但是具有一些重要差异:

  1. 意外地“隐藏”或忽略引导类是相对困难的。
  2. 通常,您只需要指定用户类的位置即可。 引导类和扩展类是“自动”找到的。
  3. 工具类现在位于单独的归档文件(tools.jar)中,并且只有在用户类路径中包含了这些工具类时才可以使用。
  1. Java启动器如何查找Bootstrap类

  Bootstrap类是实现Java Platform的类。 Bootstrap类位于rt.jar和jre/lib目录中的其他几个jar文件中。 这些归档文件由存储在sun.boot.class.path系统属性中的引导程序类路径的值指定。 此系统属性仅供参考,不应直接修改。
  您不太可能需要重新定义引导类路径。 非标准选项-Xbootclasspath允许您在极少数情况下需要使用一组不同的核心类来执行此操作。
  请注意,实现Java SDK的工具类与引导类是位于单独的归档文件中。 工具类归档文件是SDK的/lib/tools.jar文件。 调用启动器时,开发工具会将此归档文件添加到用户类路径。 但是,此扩展的用户类路径仅用于执行工具。 处理源代码javac和javadoc的工具使用原始类路径。

  1. Java启动器如何查找扩展类

  扩展类是扩展Java平台的类。 扩展目录jre/lib/ext中的每个.jar文件都认定为扩展类,并使用Java扩展框架加载。 在扩展目录中找不到松散的类文件。 它们必须包含在.jar文件(或.zip文件)中。 没有提供用于更改扩展目录位置的选项。

  如果jre/lib/ext目录包含多个.jar文件,并且这些文件包含具有相同名称的类,例如:

smart-extension1_0.jar 包含 类 smart.extension.Smart
smart-extension1_1.jar 包含 类 smart.extension.Smart

  实际加载类将提示未定义。

  1. Java启动器如何查找用户类

  用户类是在Java平台上构建的类。 要查找用户类,启动器会引用用户类路径:包含类文件的目录,JAR存档和ZIP存档的列表。
  类文件的子路径名称反映了类的全限定名称。 例如,如果类com.mypackage.MyClass存储在/myclasses下,则/myclasses必须在用户类路径中,并且类文件的完整路径必须在/myclasses/com/mypackage/MyClass.class中。 如果该类存储在名为myclasses.jar的存档中,则myclasses.jar必须位于用户类路径中,并且该类文件必须作为com/mypackage/MyClass.class存储在存档中。

  用户类路径指定为字符串,在Solaris上用冒号(:)分隔类路径条目,在Microsoft Windows系统上用分号(;)分隔条目。 Java启动器将用户类路径字符串放入java.class.path系统属性中。 该值的可能来源有:

  1. 默认值“.”,表示用户类文件是当前目录中的所有类文件(如果在包中,则位于其下)。
  2. CLASSPATH环境变量的值,它将覆盖默认值。
  3. -cp或-classpath命令行选项的值,它将覆盖默认值和CLASSPATH值。
  4. -jar选项指定的JAR归档文件,它将覆盖所有其他值。 如果使用此选项,则所有用户类都必须来自指定的存档。
  1. Java启动器如何查找 JAR清单class-path 类

  JAR归档文件通常包含“清单”(manifest列出JAR内容的文件)。 清单可以定义一个class-path,它进一步扩展了类路径(但仅在从该JAR加载类时)。 通过JAR清单class-path访问的类按以下顺序找到:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值