Package name is different than the folder structur

2019-01-17 20:45发布

问题:

I am using Notepad++ to write my Java code and Command Prompt to compile and run it. Following is my sample Java code,

    package abraKadabra;

    public class SuperClass{
       protected int anInstance;

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

However, this file is in the following folder structure :

"usingprotected\superPkg" (usingProtected is a folder somewhere in the hierarchy in C:)

So, my package name here should be something like usingProtected.superPkg instead of abraKadabra as I wrote it.

But, when I compile this Java code from command prompt, it compiles fine with no error or warnings. Why is it so? Shouldn't the package name adhere to the folder structure? And if it should, how would it adhere?

For e.g. if my package name is usingProtected.superPkg, will the compiler check in the reverse order. The present working directory should be superPkg, then the parent directory should be usingProtected and its done. Is it how it checks the folder structure with package name?

回答1:

The Java language specification doesn't force files to be in a certain directory. It optionally allows the compiler to require that public classes are in files with the same name of the class, but I don't think there's anything similar for packages. Section 7.2.1 talks about possible storage options in a file system, but it doesn't say anything about enforcing source code structure, as far as I can see.

However, it's best practice - and a pretty much universally accepted convention - to reflect the package structure in the source directory structure... and javac will use this to try to find source files which aren't explicitly specified to be compiled.

Note that if you're compiling from the command line, by default each class will appear in the same location as the corresponding source file, but if you use the "-d" option (e.g. "-d bin") the compiler will build an appropriate output directory structure for you, rooted in the specified directory.



回答2:

After experimenting a bit, I got the way how to use package name and run Java class files from command prompt.

Suppose following is my Java source file:-

    package mySample;


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

This file is in directory "D:\Code N Code\CommandLine".

Now, when compile the source code (by going to the above directory from cmd) using following command:-

    javac -d . Sample.java

This automatically creates "mySample" folder in my current directory. So, my class file Sample.class is present in directory "D:\Code N Code\CommandLine\mySample". Compiler created this new folder "mySample" from the package name that I gave in my source code.

So if I had given my package name to be "package com.mySample", compiler would create two directories and place my class file in "D:\Code N Code\CommandLine\com\mySample".

Now, I am still in the present working directory i.e. in "D:\Code N Code\CommandLine". And to run my class file, I give the following command:

    java mySample.Sample

So, I give the complete hierarchy of package and then the class name. The Java Interpreter will search the current directory for "mySample" directory and in that for "Sample.class". It gets it right and runs it successfully. :)

Now, when I asked that why it compiles my wrong package source code, it would compile the code successfully though, but it gives NoClassDefFoundError when I run my class file. So above method can be used to use package names from command line.



回答3:

If you're compiling a single class, javac doesn't need to look elsewhere for it. It'll just compile the file as is and put the resulting .class into the same folder. However, you generally won't be able to use the class til you put it into an "abraKadabra" directory in one of the directories in the class path.

If your class uses another class in the package, though, you might have problems compiling it where it is, for the same reason (javac wants to find the class and make sure it has the methods and such that your class uses).



回答4:

Java compiler does not check the directory structure when it compiles source files. As you mentioned, suppose you have a source file that starts with the directive

package abraKadabra;

You can compile the file even if it is not contained in a subdirectory .../abraKadabra . The source file will compile without errors if it doesn’t depend on other packages. However, the resulting program will not run (unless also including package name in execution). The virtual machine won’t find the resulting classes when you try to run the program.