包名称与文件夹结构不同,但 Java 代码仍会编译

2022-09-01 09:27:05

我正在使用Notepad ++编写我的Java代码和命令提示符来编译和运行它。以下是我的示例 Java 代码,

    package abraKadabra;

    public class SuperClass{
       protected int anInstance;

       public static void main(String [] abc){
           System.out.println("Hello");
       }
    }

但是,此文件位于以下文件夹结构中:

“usingprotected\superPkg”(usingProtected 是 C:中层次结构中某个位置的文件夹)

所以,我在这里的软件包名称应该像使用Protected.superPkg而不是我写的abraKadabra一样。

但是,当我从命令提示符编译此Java代码时,它编译良好,没有错误或警告。为什么会这样?包名称是否应遵循文件夹结构?如果它应该,它将如何坚持?

例如,如果我的软件包名称使用Protected.superPkg,编译器会以相反的顺序检查。当前工作目录应为 superPkg,则父目录应使用受保护且已完成。它是如何使用包名称检查文件夹结构的吗?


答案 1

Java 语言规范不会强制文件位于某个目录中。它可以选择允许编译器要求公共类位于具有与类同名的文件中,但我不认为包有任何类似的东西。第7.2.1节讨论了文件系统中可能的存储选项,但据我所知,它没有说明如何强制执行源代码结构。

但是,最佳做法 - 并且几乎普遍接受的约定 - 在源目录结构中反映包结构...javac使用它来尝试查找未明确指定要编译的源文件。

请注意,如果从命令行编译,默认情况下,每个类将显示在与相应源文件相同的位置,但是如果您使用“-d”选项(例如“-d bin”),编译器将为您构建适当的输出目录结构,植根于指定的目录。


答案 2

经过一些实验,我得到了如何使用包名称并从命令提示符运行Java类文件的方法。

假设下面是我的 Java 源文件:-

    package mySample;


    public abstract class Sample{
        public static void main(String... a){
           System.out.println("Hello ambiguity");
        }
    }

此文件位于目录“D:\Code N Code\CommandLine”中。

现在,当使用以下命令编译源代码(通过从cmd转到上面的目录)时:-

    javac -d . Sample.java

这会自动在我的当前目录中创建“mySample”文件夹。因此,我的类文件 Sample.class 存在于目录 “D:\Code N Code\CommandLine\mySample” 中。编译器从我在源代码中给出的包名称创建了这个新文件夹“mySample”。

因此,如果我将我的包名称设置为“package com.mySample”,编译器将创建两个目录并将我的类文件放在“D:\Code N Code\CommandLine\com\mySample”中。

现在,我仍然在当前的工作目录中,即在“D:\Code N Code\CommandLine”中。为了运行我的类文件,我给出以下命令:

    java mySample.Sample

因此,我给出了包的完整层次结构,然后给出了类名。Java解释器将在当前目录中搜索“mySample”目录,并在其中搜索“Sample.class”。它做对了,并成功运行了它。:)

现在,当我问为什么它编译了我的错误包源代码时,它会成功编译代码,但是当我运行我的类文件时,它会给出NoClassDefFoundError。因此,上述方法可用于从命令行使用包名称。


推荐