Why is javac's -cp option case sensitive, but

2019-07-24 04:50发布

问题:

I've noticed that case sensitivity for javac and java options seem to vary. For instance:

Case sensitive javac command option?

-cp          Yes
-sourcepath  Yes
-d           No

Case sensitive java command option?

-cp          No

As an example of case sensitivity for these four options, take the following folder structure:

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

Main.java, which shows the Sub class being used -

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

Also, take the following batch file, which uses javac and java:

javac -cp bin -sourcepath src -d bin src\Main.java
java -cp bin Main

If I delete all precompiled .class files inside this project, and rename the source code sub folder called subf to SUBF, then when I run the batch file above, I get a compilation error, as it can't find the package called subf. So, javac's -sourcepath option is case sensitive.

(In order for the next test to succeed and run, an existing Sub.class file needs to be moved back in to the bin\subf folder.) If I leave the renamed source code subf folder as SUBF, so that the source code can't be compiled, and rename the bin class folder called subf to SUBF, then when I run the batch file, I get an error (can't find package subf) for compilation, but the executable runs OK. So, javac's -cp option is case sensitive, but java's -cp option isn't. (Please note that as per the title of this SO question, this observation forms the basis of my question.)

Finally, if I rename the source code SUBF folder back to subf, so that the source code can be compiled, but leave the class folder called subf as SUBF, then when I run the batch file, I don't get any errors - the batch file compiles and also runs. This means that javac's -d option is not case sensitive, as it overlooks the fact that the class subf folder has been renamed to SUBF, as the .class file found inside that folder has an up to date datestamp value.

I have zipped up this simple project in to a download. It can be found here (on DropBox).

回答1:

Java is case sensitive when it comes to matching package and class names. Everything Java does here is case sensitive.

However, the file system on Windows is not case sensitive. It is case preserving but not case sensitive. This means that a request for a file named A.class would find a file called a.class if it existed.

This explains why some things that Java does appear to be ignoring case. The javac or java program asks for a directory, and the operating system searches for it by ignoring case.

But you cannot rely on this to always be true. On another operating system that does not ignore case, Java may fail to find files that it would find under Windows.


There was one thing you did that affects the outcome of your commands:

You should pass all the Java file names to the compiler. If you were building with ant, this would have been done for you.

> javac -cp bin -sourcepath src -d bin src\Main.java
src\Main.java:5: package subf does not exist
        subf.Sub.method();

Do it this way and there are no errors:

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