Java 类驻留在不同于包指定的目录中-为什么?

Java 类驻留在不同于包指定的目录中-为什么?,java,package,javac,Java,Package,Javac,以下陈述似乎起到了令人不安的作用: robert@neghvar:~/tmp> cat org/foo/Bar.java public class Bar { } robert@neghvar:~/tmp> javac org/foo/Bar.java robert@neghvar:~/tmp> javap org.foo.Bar Compiled from "Bar.java" public class org.something.Bar extends java.l

以下陈述似乎起到了令人不安的作用:

robert@neghvar:~/tmp> cat org/foo/Bar.java 
public class Bar {

}

robert@neghvar:~/tmp> javac org/foo/Bar.java 
robert@neghvar:~/tmp> javap org.foo.Bar
Compiled from "Bar.java"
public class org.something.Bar extends java.lang.Object{
    public org.something.Bar();
}

尽管Bar类文件位于
org/foo
目录中,并且声明了
org.something
包,但编译器没有抱怨。我的印象是java强制要求在包名之后建立目录层次结构。我弄错了吗?如果是这样的话,混淆包名的后果是什么?

这纯粹是惯例。编译器将使用包名


尽管如此,打破这一惯例通常不是一个好主意。这将导致不一致(生成的类将位于包后面的目录中)和一些混乱

源目录结构不需要遵循包命名(尽管它几乎总是按照惯例)

我认为Sun/oraclejavac、javap、java等工具(以及我所知道的所有其他java实现)是强制执行每个包名的子目录组件规则(以及默认类加载器)的工具。我找不到任何权威性的东西,但它似乎不是Java语言规范的要求:


回答得好,也感谢您的研究。但是,似乎没有实现需要它——我的示例是用Oracle的
javac
javap
完成的。所谓“需要”,我的意思是这些工具生成组织的包,并在运行时需要它。(javac/javap程序不需要它作为源文件。)关键是语言(和JVM)规范不需要子目录组织,但所有标准java工具实现都需要子目录组织。它们还需要在编译时编译依赖类。如果编译了其他依赖于Bar的类,而Bar没有被编译,那么如果Bar.java不在正确的位置,编译就会失败。