Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do java source files require package declarations?

I think I am failing to understand java package structure, it seemed redundant to me that java files have a package declaration within, and then are also required to be present in a directory that matches the package name. For example, if I have a MyClass.java file:

package com.example;

public class MyClass {
    public static void main(String[] args) {
        System.out.println("Hello, World");
    }
}

Then I would be required to have this file located in com/example, relative to the base directory, and I would execute java com.example.MyClass from the base directory to run it.

Why wouldn't the compiler be able to infer the package name by looking at the directory structure? For example, if I compiled the file from the base directory javac com\example\MyClass.java, I am not understanding why the MyClass.java wouldn't implicity belong to the com.example package.

I understand there is a default package, but it still seems that the package declaration in the source file is redundant information?

like image 490
yas Avatar asked May 22 '15 13:05

yas


People also ask

Why does Java need a package?

Java Packages & API A package in Java is used to group related classes. Think of it as a folder in a file directory. We use packages to avoid name conflicts, and to write a better maintainable code.

Is package declaration mandatory in Java?

It's mandatory that class files reside on the same package or directory as declared in their source file using package keyword, failure to do will result in java.

Does every Java file need a package?

You never need to put a class in a package. However, it is almost always a good idea. This is something that Netbeans aggressively tries to encourage you to do. For small projects, using the default package (that is, a file without a package statement) is OK.

What is source package in Java?

Source packages contain your Java class, interface, enumeration, and annotation type files. That is, anything with a . java extension. This package contains your application logic.


4 Answers

As you (implicitly) acknowledged, you are not required to declare the name of a package in the case if the default package. Let us put that quibble aside ...

The reason for this seeming redundancy is that without a package declaration, the meaning of Java1 source code would be ambiguous. For example, a source file whose pathname was "/home/steve/project/src/com/example/Main.java" could have 7 different fully qualified names, depending on how you compiled the code. Most likely, only one of those will be the "correct" one. But you wouldn't be able to tell which FQN is correct by looking at (just) the one source file.


It should also be noted that the Java language specification does not require you to organize the source code tree according to the packages. That is a requirement of a (large) family of Java compilers, but a conformant compiler could be written that did not require this. For example:

  • The source code could be held in a database.
  • The source code could be held in a file tree with random file names2.

In such eventualities, the package declaration would not be duplicative of file pathnames, or (necessarily) of anything. However, unless there was some redundancy, finding the correct source "file" for a class would be expensive for the compiler ... and problematic for the programmer.

Considerations like the above are the practical reason that most Java tool chains rely on file tree structure to locate source and compiled classes.


1 - By this, I mean hypothetical dialect of Java which didn't require package declarations.
2 - The compiler would need to scan the file tree to find all Java files, and parse them to work out which file defined which class. Possible, but not very practical.

like image 143
Stephen C Avatar answered Oct 17 '22 10:10

Stephen C


Turn the question on its head:

Assume that the package statement is the important thing - It represents the namespace of the class and belongs in the class file.

So now the question is - Why do classes have to be in folders that match their package?

The answer is that it makes finding them much easier - it is just a good way to organize them.

Does that help?

like image 10
Phil Anderson Avatar answered Oct 17 '22 11:10

Phil Anderson


You have to keep in mind that packages do not just indicate the folder structure. The folder structure is the convention Java adopted to match the package names, just like the convention that the class name must match the filename.

A package is required to disambiguate a class from other classes with the same name. For instance java.util.Date is different from java.sql.Date. The package also gives access to methods or members which are package-private, to other classes in the same package.

You have to see it the other way round. The class has all the information about itself, the class name and the package name. Then when the program needs it, and the class is not loaded yet, the JVM knows where to look for it by looking at the folder structure that matches the package name and the class with the filename matching its class name.

like image 3
jbx Avatar answered Oct 17 '22 12:10

jbx


In fact there's no such obligation at all.

Oracle JDKs javac (and I believe most other implementations too) will happily compile your HelloWorld class, no matter what directory it is in and what package you declare in the source file.

Where the directory structure comes into the picture is when you compile multiple source files that refer to each other. At this point the compiler must be able to look them up somehow. But all it has in the source code is the fully qualified name of the referred class (which may not even have been compiled yet).

At runtime the story is similar: when a class needs to be loaded, its fully qualified name is the starting point. Now the class loader's job is to find a .class file (or an entry in a ZIP file, or any other imaginable source) based on the FQN alone, and again the simplest thing in a hierarchical file system is to translate the package name into a directory structure.

The only difference is that at runtime your "standalone" class too has to be loaded by the VM, therefore it needs to be looked up, therefore it should be in the correct folder structure (because that's how the bootstrap class loader works).

like image 1
biziclop Avatar answered Oct 17 '22 12:10

biziclop