Java packages group related classes and interfaces in a single directory. Java packages are a source code organization facility and a runtime security feature at the same time. A Java package can contain other sub directories called sub packages. A Java package corresponds to a module or namespace in some of other languages.
What is a Java Package anyway?
A Java package corresponds to a directory on your filesystem. It allows you to prevent name clashes and separate code coming from different origins.
How to Create Java Packages
Creating Java packages in your source code is pretty straightforward. All you need to do is create a directory structure that corresponds to your package structure. A package corresponds to a directory and sub package to sub directory. All the source code files in the package must have the package declaration as the first executable statement. To summarize, the steps involved are –
- Create a root directory where all your source code will live. IDEs typically call it src. It’s ususally a sibling of directories such as lib (where external libraries live), test (where your unit tests live) etc. Note that the root directory is not part of your package. For sake of understanding, think that your Java compiler and runtime will stand inside this directory and look at your code. They would see all the directories and subdirectories as packages but the root won’t be a part of it.
- Create directories and sub directories that correspond to packages and subpackages
- Declare package name as the first executable statement in all source code files.
Let’s say you have a package called a and another directory (subpackage) b inside it. Classes and interfaces residing in the directory b will have their package name as a.b . Classes and interfaces in directory a will have package name a.
As another example, let’s say you have classes Politician and GangMember. Since they are closely related (No references required or be cited) you would want to put them together. So, you can put both of them in the same directory called criminals. Then in both these files declare package as criminals ( by saying package criminals; in the first line) and that’s all. Java now recognizes your classes as criminals.Politician and criminals.GangMember .
Packages for Namespaces : Conflict Resolution
Packages can help the compiler and runtime distinguish between classes which have the same but are coming from potentially different sources.
Continuing with our previous example, let’s say there are other people who have modelled Politicians and GangMembers. Since you want to stand on the shoulder of giants, you want to reuse their code (of course, honoring license requirements). This presents a problem because now you end up with two classes by the same name Politician.
Java packages come to the rescue and can create a namespace for each of these Politician classes so that the compiler and runtime can distinguish between them. You can place your source code in package that corresponds to your organization and the other implementation must also do so.
It’s a pretty standard practice to use web address of your organization for package structure. The web address is inverted and used to avoid having large number of directories. This is sometimes referred to as reverse domain name naming strategy.
So, for example you can create package structure com.codingraptor. That means there is a directory com and a subdirectory called codingraptor in it. This codingraptor can have the source code of the Politician. The other implementation will similarly be placed in a different package. Assume that the other package is com.sun . Now the compiler and runtime both can distinguish between com.codingraptor.Politician and com.sun.Politician .
Advantages of Java Packages
- Allow you to organize your source code better. Related files reside nearby.
- Prevent namespace collision and thus allow you to use third-party libraries without the danger of breaking existing code.
- Regulate access through access modifiers. We have seen package private access modifiers.
- Help is segregating source code and unit test code. For example, the developers may create a package a.b in a directory src and put all development classes there. The testers may create a test directory containing the exact same directory structure. The test classes, although in a different source code directory, can still access the package private data structures of the main source class. This is because the package of the development and the test files is the same. For the Java interpreter they are in the same package. Note that, in real life projects the test directory contains unit tests. These unit tests are also created by the same developer who writes the application code.
Naming Conventions and Rules for Packages
- Java package names contain only small letters.
- Use reverse domain name strategy.
- Try to avoid naming your packages after standard Java packages and classes.
- Do not use Java’s keywords and reserved words as package names.
- Avoid naming your packages as java or javax. Java uses these package names for its own standard libraries.
- Even if you name your classes and packages to mimic Java’s standard packages and names, you cannot stand at par with standard Java classes. This is further elaborated in the next section – Packages as a Runtime Security Feature
- Package names cannot have hyphens or other special characters
- Package names cannot begin with a number or special character
- Use underscore ( _ ) if you want to have package names with ‘ – ‘ or keywords. For example, if your domain had been coding-raptor.com , your package name, by convention, would be com.coding_raptor
Packages as a Runtime Security Feature
When JVM is presented a class file, it parses and verifies the contents of class files. A classloader is responsible for loading the class files into JVM. (If you are coming from C or C++, know that classloader is both a loader and linker rolled into one.)
Java classloaders form a hierarchy. The bootstrap classloader loads the Java library files (e.g. would be all files contained in java.lang) . The classes that developers are loaded by the system classloader. Inside JVM the package structure you specify is then qualifed with your classloader.
So, even if you name your classes and packages exactly same as the standard Java library, you cannot draw the same benefits as Java libraries do.
For example, if you name your packages as java.util and then create a class called ArrayList, you cannot accesss package private data structures of Java’s java.util.ArrayList . Your file to JVM looks like
and this is not same as the standard ArrayList. Even if you copy the package structure and file name, you cannot have the same classloader.
JVM is thus successfully able to distinguish between the two. Because of this security feature, you can be sure that the behavior of Java’s standard library cannot be changed by any user.