412

我刚刚读到这一行:

format() 方法做的第一件事是从名为 output.vm 的类路径中加载 Velocity 模板

请解释在这种情况下类路径的含义,以及我应该如何设置类路径。

4

10 回答 10

682

在 Java 中编程时,您可以通过在源文件的顶部放置类似这样的内容来使其他类对您正在编写的类可用:

import org.javaguy.coolframework.MyClass;

或者有时你会说:

import org.javaguy.coolframework.*;

所以稍后在你的程序中当你说:

MyClass mine = new MyClass();

Java 虚拟机将知道在哪里可以找到您编译的类。

让 VM 浏览您机器上的每个文件夹是不切实际的,因此您必须为 VM 提供要查看的位置列表。这是通过将文件夹和 jar 文件放在类路径中来完成的。

在讨论如何设置类路径之前,让我们先谈谈 .class 文件、包和 .jar 文件。

首先,假设 MyClass 是您作为项目的一部分构建的,它位于项目中名为output. .class 文件将位于output/org/javaguy/coolframework/MyClass.class(以及该包中的所有其他文件)。为了访问该文件,您的路径只需要包含文件夹“输出”,而不是整个包结构,因为您的导入语句将所有这些信息提供给 VM。

现在让我们假设您将 CoolFramework 捆绑到一个 .jar 文件中,并将该 CoolFramework.jar 放入您项目的 lib 目录中。您现在需要放入lib/CoolFramework.jar您的类路径。VM 将在 jar 文件中查找该org/javaguy/coolframework部件,并找到您的类。

因此,类路径包含:

  • JAR 文件,以及
  • 包层次结构顶部的路径。

你如何设置你的类路径?

每个人似乎学习的第一种方式是使用环境变量。在 unix 机器上,你可以这样说:

export CLASSPATH=/home/myaccount/myproject/lib/CoolFramework.jar:/home/myaccount/myproject/output/

在 Windows 机器上,您必须转到您的环境设置并添加或修改已经存在的值。

第二种方式是-cp在启动Java时使用参数,像这样:

java -cp "/home/myaccount/myproject/lib/CoolFramework.jar:/home/myaccount/myproject/output/"  MyMainClass

第三种方式是第三种方式,通常使用计算类路径并通过参数将其传递给 Java 的文件来.sh完成。.bat-cp

以上所有内容都有一个“陷阱”。在大多数系统(Linux、Mac OS、UNIX 等)上,冒号字符 (':') 是类路径分隔符。在 windowsm 中,分隔符是分号 (';')

那么最好的方法是什么?

通过环境变量全局设置东西是不好的,通常与全局变量不好的原因相同。你改变了CLASSPATH环境变量,让一个程序工作,你最终破坏了另一个程序。

-cp是要走的路。CLASSPATH我通常会尽可能确保我的环境变量是一个空字符串,这样我就可以避免全局类路径问题(但是,当全局类路径为空时,有些工具会不高兴 - 我知道两个常见的,百万美元许可的 J2EE 和 Java 服务器的命令行工具存在此类问题)。

于 2010-03-07T15:27:57.117 回答
93

将其视为 Java 对 PATH 环境变量的回答——操作系统在 PATH 上搜索 EXE,Java 在类路径上搜索类和包。

于 2010-03-07T14:10:42.233 回答
17

类路径是 Java 虚拟机在 Java 程序中查找用户定义的类、包和资源的路径。

在此上下文中,该format()方法从该路径加载模板文件。

于 2010-03-07T14:08:49.230 回答
15

类路径是 Java 世界中的基本概念之一,Java 程序,尤其是初学者经常误解或根本不理解它。

简单地说,这classpath只是set of pathsjava 编译器和 JVM 必须找到需要的类来编译或执行其他类的地方。

让我们从一个例子开始,假设我们有一个Main.java文件C:\Users\HP\Desktop\org\example,它位于

package org.example;

public class Main {
    public static void main(String[] args) {
    
            System.out.println("Hello world");
            
    }
}

现在,假设我们在C:\目录下并且我们想要编译我们的类,这很简单,只需运行:

javac .\Users\HP\Desktop\org\example\Main.java


现在对于难题,我们在同一个文件夹中C:\,我们想要运行编译的类。

尽管您可能会想到答案,但正确的答案是:

java -cp .\Users\HP\Desktop org.example.Main 

我将首先解释为什么我们想要 ro tun 的类的名称org.exmaple.Main不是MainMain.class.\users\hp\desktop\org\example\Main.class!这就是在包下声明的类的工作方式。

现在,我们将类的名称提供给 JVM(在本例中为 java 命令),但是它(JVM)如何知道在哪里可以找到 Main 类的 .class 文件?这classpath就是进入图片的地方。使用-cpflag(-classpath 的快捷方式),我们告诉 JVM 我们的 Main.class 文件将位于C:\users\hp\Desktop.. 事实上,不是真的,我们告诉它just go to the Desktop directory, and, because of the name of the class org.example.Main, the JVM is smart and it will go from Desktop to org directory, and from org to example directory, searching for Main.class file,它会找到它并杀死它,我的意思是,它会运行它:D。

现在让我们假设在 Main 类中我们想要使用另一个名为org.apache.commons.lang3.StringUtils的类,后者位于一个名为commons-lang3-3.10.jarthats inside的 jar 文件中C:\Users\HP\Downloads。所以 Main.java 现在看起来像这样:

package org.example;

import org.apache.commons.lang3.StringUtils;

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world");
        System.out.println(StringUtils.equals("java", "java")); //true
    }   
}


如果我们总是在里面,如何编译 Main.java C:\?答案是:

javac -cp .\Users\HP\Downloads\commons-lang3-3.10.jar .\Users\HP\Desktop\org\example\Main.java
  • .\Users\HP\Desktop\org\example\Main.java是因为我们的 .java 文件在文件系统中。

  • -cp .\Users\HP\Downloads\commons-lang3-3.10.jar因为java编译器(这里是javac)需要知道org.apache.commons.lang3.StringUtils类的位置,所以我们提供了jar文件的路径,然后编译器就会进入jar文件里面尝试在目录中查找文件 StringUtils.class org\apache\commons\lang3


如果我们想运行 Main.class 文件,我们将执行:

java -cp ".\Users\HP\Desktop\;.\Users\HP\Downloads\commons-lang3-3.10.jar" org.example.Main
  • org.example.Main是类的名称。

  • ".\Users\HP\Desktop\;.\Users\HP\Downloads\commons-lang3-3.10.jar"是 Main 和 StringUtils 类的路径(在 Windows 中由 ; 分隔)。

于 2021-08-21T23:57:33.653 回答
5

这个上下文中的类路径正是它在一般上下文中的样子:VM 知道它可以在任何地方找到要加载的类,以及资源(例如你的例子中的 output.vm)。

我知道 Velocity 期望在“无包”中的任何地方找到一个名为 output.vm 的文件。这可以是 JAR、常规文件夹、... 应用程序类路径中任何位置的根。

于 2010-03-07T14:08:42.633 回答
2

类路径是系统的环境变量。此变量的设置用于向 java 编译器提供任何包层次结构的根。

于 2014-12-15T14:20:39.453 回答
2

设置 CLASSPATH 系统变量

要显示当前的 CLASSPATH 变量,请在 Windows 和 UNIX(Bourne shell)中使用以下命令: 在 Windows 中: C:\> set CLASSPATH 在 UNIX 中: % echo $CLASSPATH

要删除 CLASSPATH 变量的当前内容,请使用以下命令: 在 Windows 中: C:\> set CLASSPATH= 在 UNIX 中: % unset CLASSPATH; export CLASSPATH

要设置 CLASSPATH 变量,请使用以下命令(例如): 在 Windows 中: C:\> set CLASSPATH=C:\users\george\java\classes 在 UNIX 中: % CLASSPATH=/home/george/java/classes; export CLASSPATH

于 2017-01-13T10:47:37.427 回答
1

CLASSPATH 是Java 编译器和运行时定位Java 程序中使用的Java 包所需的环境变量(即所有进程可用的操作系统的全局变量)。(为什么不调用 PACKAGEPATH?)这类似于另一个环境变量 PATH,CMD shell 使用它来查找可执行程序。

CLASSPATH 可以通过以下方式之一设置:

CLASSPATH can be set permanently in the environment: In Windows, choose control panel ⇒ System ⇒ Advanced ⇒ Environment Variables ⇒ choose "System Variables" (for all the users) or "User Variables" (only the currently login user) ⇒ choose "Edit" (if CLASSPATH already exists) or "New" ⇒ Enter "CLASSPATH" as the variable name ⇒ Enter the required directories and JAR files (separated by semicolons) as the value (e.g., ".;c:\javaproject\classes;d:\tomcat\lib\servlet-api.jar"). Take note that you need to include the current working directory (denoted by '.') in the CLASSPATH.

To check the current setting of the CLASSPATH, issue the following command:

> SET CLASSPATH

CLASSPATH can be set temporarily for that particular CMD shell session by issuing the following command:

> SET CLASSPATH=.;c:\javaproject\classes;d:\tomcat\lib\servlet-api.jar

Instead of using the CLASSPATH environment variable, you can also use the command-line option -classpath or -cp of the javac and java commands, for example,

> java –classpath c:\javaproject\classes com.abc.project1.subproject2.MyClass3
于 2015-08-20T07:08:45.907 回答
0

可以直接调用类的静态成员,而无需创建对象实例。由于 main 方法是静态的,Java 虚拟机可以在不创建包含 main 方法的类的任何实例的情况下调用它,这是程序的起点。

于 2018-09-26T10:52:29.620 回答
0

对于 linux 用户,总结和补充其他人在这里所说的内容,您应该知道以下内容:

  1. $CLASSPATH 是 Java 用来查看多个目录以查找脚本所需的所有不同类的工具(除非您使用 -cp 覆盖明确告知它)。使用 -cp 需要您手动跟踪所有目录,并在每次运行程序时复制粘贴该行(不推荐 IMO)。

  2. 冒号 (":") 字符分隔不同的目录。只有一个 $CLASSPATH 并且其中包含所有目录。因此,当您运行“export CLASSPATH=....”时,您希望包含当前值“$CLASSPATH”以附加到它。例如:

    export CLASSPATH=.
    export CLASSPATH=$CLASSPATH:/usr/share/java/mysql-connector-java-5.1.12.jar
    

    在上面的第一行中,您只用一个简单的“点”开始 CLASSPATH,它是您当前工作目录的路径。这样,每当您运行 java 时,它都会在当前工作目录(您所在的目录)中查找类。在上面的第二行中,$CLASSPATH 获取您之前输入的值 (.) 并将路径附加到 mysql 驱动程序。现在,java 将为您的类查找驱动程序和。

  3. echo $CLASSPATH
    

    非常方便,它返回的内容应该读起来像所有目录和 .jar 文件的冒号分隔列表,您希望 java 查找它需要的类。

  4. Tomcat 不使用 CLASSPATH。在此处阅读如何处理: https ://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

于 2020-01-20T18:07:46.787 回答