packages in Java

A package is a collection of similar classes, interfaces, enumerations and other packages. A package in Java translates to a file-system directory/folder on the implementation level. Packages can be classified into two categories:

  • Built-in packages : They are part of java API. Example :  java.lang, java.io etc.
  • User-defined packages : They are created by users based on their needs.

It is a common convention to use all small cap letters for the package names to differentiate it from class names.


1. Built-in Packages

These are packages that are part of java API. Java provides a number of standard packages to accompolish commonly used tasks. Some of them are:

  • java.util : Contains classes that implement data structures like tree, hash table etc.
  • java.lang : Contains commonly used classes.
  • java.io : Contains classes for input/output operations.
  • java.math : Contains classes for multiprecision arithmetics.
  • java.applet : Contains classes for creating applets.

To use these packages you first need to import them into the current scope by using import statement, only then you can use the classes, interfaces and enumerations defined in that package. Let’s see an example where we will use ArrayList class in java.util package to declare a variable length array.

Output :

Note that we didn’t specify the length of the ArrayList anywhere. The ArrayList class automatically adjusts its size.


2. User Defined packages

We can define our own classes and bundle them into a package. When we need to use those classes in a new program, we can simply import them. This method saves a lot of time and coding effort.

2.1 Defining a package

To define a package you need to use the package statement. This should be the first statement in your program. In the example below, we declare a myMath package and define a Formulae class. Name this file Formulae.java and keep it into a folder named myMath i.e the name of the package. You will see later why we did that.

To use this package, first we import it as shown in the example below. Name this class Demo.java and save it.

Output :


3. Organization of packages

  • Java uses filesystem directory/folder to store classes in a package. i.e all classes defined in a package are stored in one folder having the same name as that of package.
  • Packages are stored in hierarchical manner and they are explicitly imported (except java.lang) into new class definitions before they can be used.

The above example can be visualized as:

package hierarchy in Java


4. Compiling a java package

Compiling a java project is easy. Suppose you have the above package hierarchy and you are in the base directory(src) of your project. If you are using an IDE then you know what to do but if you are compiling from command line just type:

It compiles Demo.java and it also compiles all the packages imported in this file. The compiled calsses are put in appropriate folders parrallel to package name.

To keep the compiled classes into separate directory named javaClasses use:

All the class files are kept in javaClasses directory. The directory structure inside jacaClasses folder matches the package hierarchy.


5. Sub-packages

Packages inside a package are known as sub-packages. To define sub-packages in a file we use dot(.) operator. Sub-package name follows package name.

So above statement in a file means that pkg2 is a sub-package defined in pkg1. As you know that all java packages translate to filesystem directory, the sub-package pkg2 represents a directory inside pkg1 directory. You can nest the packages to any depth you want(except for Operating System restrictions) like:

All translate to directories one inside the other.

Let’s take an example. Save this file into a folder named solids inside another folder myMath.

Save the following file into base directory with name Demo4.java

Compile both the files and save the class files into respective directories. Output looks like:

 


6. Accessing Packages

There are two ways to import classes defined in any package.

  • import packageName.* : Imports everything inside that package.
  • import packageName.ClassName : Imports only the class/interface whose name has been provided.

Suppose you have a package pkg1 and a sub-package pkg2 inside  pkg1. The package pkg1 contains classes A, B, C and the sub-package pkg2 contains classes X, Y, Z.

  • import pkg1.* : imports all classes in pkg1(A, B, C) and none of the classes in sub-package pkg2.
  • import pkg1.pkg2.* : imports all classes in sub-package pkg2(X, Y, Z) and none of the classes in pkg1.

6.1 Import statement is optional

Import statement is optional. We can use the fully qualified class name instead of importing any class. Like the example below

can be re-written as

Output : both programs produce the same output

If you have to access the class inside a package only a few times then it is ok to use the fully qualified class name but it becomes tedious if you have to use them for a large number of times. So in that case it is better to import the classes.


6.2 Handling name conflicts:

Two wildcard import(import pkgname.*) statements may import classes with same name. Java stays silent until you try to use the classes with name conflicts. As soon as you try to use them, compilation error is thrown.  To fix it, you have to use the fully qualified class names instead.

Let’s take an example. Both java.util and java.sql have Date class. If you import both with wildcard import then both Date classes are imported. But to use either of these, you have to use the fully qualified class name.

Output :


7. Advantages of Packages

  • Code Reuse : Once a class has been defined, it can be imported and used into any program you want. You don’t have to define that class again. For example: java provides Scanner class in java.util package for taking input from the user. You can simpy import this class and use it, you don’t need to write a new class to take user input.
  • Better Code Organisation : Often a project consists of hundreds of classes. So it is a good idea to bundle similar or related classes and interfaces into one group. Such projects are easy to extend, maintain and debug.
  • Avoids Name Conflicts : Java requires that all classes have unique names. But sometimes two classes may have the same name. All you have to do is to put them in two different packages. For example both java.sql and java.util packages have a class named Date.
  • Encapsulation : Packages are both naming and visibility control mechanism. We can define classes inside a package that are not accessible to code outside that package. Access modifiers together with packages help us encapsulate our classes the way we want.

8. Finding packages and CLASSPATH

There is one important question we haven’t answered yet. Since Java represents packages by directories, how does the Java run-time system know where to look for packages that you have created and included in your program. It turns out that it happens in three steps:

  1. First Java uses the current working directory as the starting point to look for the included package. So if the package is in a sub-directory of the current directory, it will be found.
  2. Second, Java uses the CLASSPATH environment variable. So you can specify the directory path or paths by setting the CLASSPATH environment variable.
  3. Third, you can specify the path to your classes by using -classpath option with java.

8.1 Example

Consider the following package:

If you want your program to find the package then you must do at least one of these:

  • Either you execute the program from a directory immediately above myMath
  • Or set the  CLASSPATH environment variable to include path to myMath
  • Or when you run the program, use -classpath to specify the path to myMath

When last two options are used, the class path must not include myMath itself. It must only specify the path to myMath. For example, in  windows environment if the path to myMath package is :

then the class path to myMath is :

Note that .class files must be put into the appropriate directories specified by the package statement.


8.2 Working with CLASSPATH environment variable

To display the current CLASSPATH variable, use these commands in Windows and UNIX (Bourne shell):

To delete the current contents of the CLASSPATH variable, use these commands:

To set the CLASSPATH variable, use these commands (for example):

Visit oracle documentation for more details.


9. Points to Remember

  • The package java.lang is imported by default by the compiler.
  • The classes that you want to access from outside the package must be declared public.
  • If package statement is being used, it must be the first statement in a file.
  • A package can have more than one file and all files in a package must have the same package statement as the first line.
  • When the package name is not defined, java puts the class into the default package(it has no name). Default package is represented by the base / root directory of the project.
  • If import statement is being used it must follow the package statement(if any) and before any classes are declared.
  • A file can have any number of import statements and you can import any number of classes you want.