我正在教我的朋友一些Java,我们在尝试在她的Hello World程序上运行编译器时遇到了问题。代码有一个非常明显的错误(Sysrem.out.println
(,但除此之外是完全有效的Java,但由于某种原因编译器没有报告错误。事情是这样的:
- 当我们在 Windows 命令提示符下运行
javac Hello.java
时,它打印出一个空行,然后是一个新的命令提示符行,就好像操作已经成功一样,但显然没有 - 没有创建类文件,当然代码有错误,所以我们知道它不会成功。 - 当我们运行
javac -verbose Hello.java
时,它打印出了它正在加载的类文件的血腥细节,但仅此而已。虽然它没有以说它编写了一个类文件结束,但它也没有打印出错误。 - 在我们修复错误后,程序编译并运行没有问题,所以似乎javac只是不喜欢打印出编译器错误。
这里可能发生了什么,为什么编译器没有像它应该的那样报告此错误?
完整代码:
public class Hello {
public static void main(String[] args) {
Sysrem.out.println("Hello, world!");
}
}
命令提示符:
C:UsersMyFriendsNameDocuments>javac Hello.java
C:UsersMyFriendsNameDocuments>
这实际上归结为空文件是否是有效的 Java 程序。 令人惊讶的是,它是!
这是CompilationUnit
的语法...这是 JLS 用于 Java 源文件的技术术语:
CompilationUnit:
OrdinaryCompilationUnit
ModularCompilationUnit
OrdinaryCompilationUnit:
[PackageDeclaration] {ImportDeclaration} {TypeDeclaration}
ModularCompilationUnit:
{ImportDeclaration} ModuleDeclaration
(参考:JLS 7.3(
请注意,OrdinaryCompilationUnit
元素允许您拥有一个包含以下内容的源文件:
- 无包声明
- 无导入语句
- 无类型声明
换句话说,空文件或仅包含注释的文件。
简而言之,如果你告诉javac
编译一个空文件,它不会产生任何编译错误......因为它是"有效的"Java源代码文件。
好吧,我发现了这个问题:事实证明,我的朋友在创建文件后从未在她的文件上点击过保存,而且在我假设只是一些不直观设计的预期行为中,javac 不会抱怨被喂入空白文件!
事情是这样的:
- 创建文件
- 编写错误代码但不保存文件
- 尝试编译代码并遇到我的问题中描述的问题
- 更正代码中的错误并保存文件
- 编译和运行代码没有问题