为什么javac';s-cp选项区分大小写,但java';s-cp选项不是吗?

为什么javac';s-cp选项区分大小写,但java';s-cp选项不是吗?,java,classpath,javac,case-sensitive,Java,Classpath,Javac,Case Sensitive,我注意到javac和java选项的大小写敏感度似乎有所不同。例如: 区分大小写的javac命令选项 -cp Yes -sourcepath Yes -d No -cp No 区分大小写java命令选项 -cp Yes -sourcepath Yes -d No -cp No 作为这四个选项区分大小写的示例,请采用以下文件夹结构: project \ src \ Main.j

我注意到
javac
java
选项的大小写敏感度似乎有所不同。例如:

区分大小写的
javac
命令选项

-cp          Yes
-sourcepath  Yes
-d           No
-cp          No
区分大小写
java
命令选项

-cp          Yes
-sourcepath  Yes
-d           No
-cp          No
作为这四个选项区分大小写的示例,请采用以下文件夹结构:

project \ src \ Main.java
              \ subf \ Sub.java
        \ bin \ Main.class
              \ subf \ Sub.class
java,显示正在使用的子类-

class Main {
    public static void main(String[] args) {
        subf.Sub.method();
    }
}
另外,取下面的批处理文件,它使用
javac
java

javac -cp bin -sourcepath src -d bin src\Main.java
java -cp bin Main
如果我删除此项目中所有预编译的
.class
文件,并将名为
subf
的源代码子文件夹重命名为
subf
,那么当我运行上面的批处理文件时,我会得到一个编译错误,因为它找不到名为
subf
的包。因此,
javac
-sourcepath
选项区分大小写

(为了使下一个测试成功并运行,需要将现有的
Sub.class
文件移回
bin\subf
文件夹。)如果我将重命名的源代码
subf
文件夹保留为
subf
,则无法编译源代码,并将名为
subf
的bin类文件夹重命名为
subf
,然后当我运行批处理文件时,我得到一个错误(
找不到包subf
)进行编译,但可执行文件运行正常。因此,
javac
-cp
选项区分大小写,但
java
-cp
选项不区分大小写。(请注意,根据本SO问题的标题,这一观察构成了我问题的基础。)

最后,如果我将源代码
SUBF
文件夹重命名回
SUBF
,以便可以编译源代码,但将名为
SUBF
的类文件夹保留为
SUBF
,那么当我运行批处理文件时,我不会得到任何错误-批处理文件编译并运行。这意味着
javac
-d
选项不区分大小写,因为它忽略了class
subf
文件夹已重命名为
subf
,因为在该文件夹中找到的
.class
文件具有最新的日期戳值


我已经将这个简单的项目压缩到下载中。可以在DropBox上找到它。

Java在匹配包名和类名时区分大小写Java在这里所做的一切都区分大小写

但是,Windows上的文件系统不区分大小写。它不区分大小写。这意味着对名为
a.class
的文件的请求将找到名为
a.class
的文件(如果存在)

这解释了为什么Java确实忽略了一些情况。
javac
java
程序请求一个目录,操作系统通过忽略大小写来搜索它

但你不能指望这永远是真的。在另一个不忽略大小写的操作系统上,Java可能无法找到它在Windows下可以找到的文件


您所做的一件事会影响命令的结果:

您应该将所有Java文件名传递给编译器。如果您是使用
ant
构建的,这将为您完成

> javac -cp bin -sourcepath src -d bin src\Main.java
src\Main.java:5: package subf does not exist
        subf.Sub.method();
按此方式操作,不会出现错误:

> javac -cp bin -sourcepath src -d bin src\Main.java src\SUBF\Sub.java

谢谢然而,我仍然很好奇为什么与
javac
java
一起使用的
-cp
选项会导致我在问题中描述的“相反的结果”。我认为答案是,java会要求操作系统列出文件/文件夹名称。名称以正确的大小写报告给Java。然后Java将记住这些名称,当它与所需的包名进行字符串比较时,它将不匹配,因此它报告包不存在的错误。