【问题标题】:Why is javac's -cp option case sensitive, but java's -cp option not?为什么 javac -cp 选项区分大小写,而 java -cp 选项不区分大小写?
【发布时间】:2014-05-15 16:18:49
【问题描述】:

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

区分大小写的javac 命令选项?

-cp          Yes
-sourcepath  Yes
-d           No

区分大小写的java 命令选项?

-cp          No

作为这四个选项区分大小写的示例,采用以下文件夹结构:

project \ src \ Main.java
              \ subf \ Sub.java
        \ bin \ Main.class
              \ subf \ Sub.class

Main.java,显示正在使用的 Sub 类 -

class Main {
    public static void main(String[] args) {
        subf.Sub.method();
    }
}

另外,使用以下批处理文件,它使用javacjava

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,然后当我运行批处理文件时,编译时出现错误(can't find package subf),但可执行文件运行正常。所以,javac-cp 选项区分大小写,但 java-cp 选项不区分大小写。 (请注意,根据此 SO 问题的标题,此观察构成了我的问题的基础。)

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

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

【问题讨论】:

    标签: java classpath javac case-sensitive


    【解决方案1】:

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

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

    这解释了为什么 Java 确实有些事情似乎忽略了大小写。 javacjava 程序要求一个目录,操作系统通过忽略大小写来搜索它。

    但是你不能依赖它来永远正确。在另一个不忽略大小写的操作系统上,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
    

    【讨论】:

    • 谢谢。但是,我仍然很好奇为什么与 javacjava 使用相同的 -cp 选项会导致我在问题中描述的“相反的结果”。
    • 我认为答案是,Java 会要求操作系统列出文件/文件夹名称。名称以正确的大小写报告给 Java。然后Java会记住这些名字,当它和想要的包名做一个字符串比较的时候,会不匹配,所以报这个包不存在的错误。
    猜你喜欢
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-10
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    相关资源
    最近更新 更多