使用 bash shell 中的相对路径调用 java 文件

Call java file using relative path in bash shell

bash
/Desktop/Lab 3$ cd Stemmer
/Desktop/Lab 3/Stemmer$ java Stemmer
/Desktop/Lab 3/Stemmer$ cd ..
/Desktop/Lab 3$ java Stemmer/Stemmer
Error: Could not find or load main class Stemmer.Stemmer
Caused by: java.lang.NoClassDefFoundError: Stemmer (wrong name: Stemmer/Stemmer)
/Desktop/Lab 3$ 

为什么我指定相对路径时 java 运行 Stemmer 没有?

我在目录的时候好像有运行这个程序,但是我想要java到运行Stemmer就像我在目录的时候一样它所在的目录。

有人能解释一下这里发生了什么吗。

当您运行一个Java程序时,您指定class名称包括完全指定的,不是文件路径。这意味着您用点而不是斜线分隔包“路径”。如果您编译了一个名为 Stemmer.java 的文件,该文件位于名为 Stemmer 的文件夹中,并且第一行为 package Stemmer,那么您会执行

java Stemmer.Stemmer

有 2 个主要选项:

您正在尝试在 java

中编写应用程序

然后您需要一个 IDE 来开发它,并需要一个构建系统来生成 jar 文件形式的可分发文件。没有必要也没有理由尝试 运行 这个 'on the command line' 你现在的样子。您需要包和项目定义。

您现在只是在玩,在单个源文件中编写一些基本代码。

然后 运行 源文件。我认为这是 java11 中引入的功能。在此之前,这种写作模式(在源文件中塞入一些行并 运行 马上)并不是 java 本身擅长的,只有 IDE 才能做到这一点。

从 java11:

开始
java Stemmer/Stemmer.java

效果很好,不需要(重新)编译任何东西。 java 会处理的。

说明

当您运行一个Java程序时,您指定class名称包括完全指定的,不是文件路径。

您之前阅读过这个答案,然后完全忽略它并尝试 java Stemmer.Stemmer 这显然不起作用。

你的class的名字是Stemmer,在未命名的包中。于是,要运行呢,java Stemmer是怎么做到的。它不是文件名。 Stemmer.Stemmer 不是 java-ese for '运行 子目录 Stemmer 中的 class 文件 Stemmer,并且 'package' 不是java-ese for 'directory on the filesystem'.

Stemmer class 的 class 路径根目录是它自己的目录,因为您没有使用任何包。默认 classpath 是当前目录。 不可能 运行 Stemmer class 文件的根目录不在 class 路径上,所以如果 /Desktop/Lab 3/Stemmer 不是在cp上,你不能这样做。那么让我们解决这个问题:

java -cp '/Desktop/Lab 3/Stemmer' Stemmer

这样就可以了。

更一般地说,使用未命名的包是一个坏主意,尝试 运行 原始 class 文件同样是一个坏主意 - 使用 IDE 进行开发,并且构建系统构建项目。

编写 'real' 项目(检查源代码管理,最终部署到某个地方或作为产品发送给其他用户)时,这些规则和注意事项都非常有意义。但是,如果只是胡闹,那就太麻烦了,而且有点可笑。这就是为什么(现在)您可以只指定 路径 到 java 源文件的原因,这似乎是您想要做的。所以,这样做吧。