Package and import are the fundamental concepts in the Java programming language. In this tutorial, I’m going to help you understand and apply these concepts into your daily Java coding. Here’s the content at a glance:

  1. What are packages?
  2. Why are packages?
  3. How to use packages?
  4. Using the import statements
  5. Wildcard imports
  6. Static imports

Are you ready? Let’s go with the packages first.

 

1. What are packages in Java?

In short, packages are directory-based structures that group some related source files together. For example, the java.util package in JDK groups all interfaces and classes in the Collections Framework such as Collection, List, ArrayList, Map, Set, HashMap, etc. The following screenshot shows a part of this package in Windows Explorer program:

java util package

The best source to learn about packages is the Java Tutorials:

Creating and Using Packages (The Java Tutorials)

Consult the above link to study everything about packages in Java. In this tutorial, I focus on emphasizing the key and important points, especially how to run Java files which are under a package using the java command.

 

2. Why are Packages in Java?

Using packages allows us to avoid naming collisions:

Imagine a situation in which two programmers write two classes that have same name, let’s say - Dog. If these two classes are used in a program, how to identify which Dog is which? So packages come to rescue: the first programmer puts his Dogclass under a package called john.animal; and the second programmer puts his Dogunder tom.pets package.

When accessing these classes, we use their fully qualified names: john.animal.Dog and tom.pets.Dog.

In JDK, you can find some classes that have same name but in different packages, e.g. java.util.Date and java.sql.Date.

 

Packages facilitate the encapsulation feature in Java:

Think packages like directories that isolate some classes from the outside world. In Java, we can use access modifiers to restrict access to some classes in a certain package. For example, the default access modifier (when no explicit access modifier is used) makes a class accessible only by others in the same package. Whereas the public access modifier makes a class visible and accessible by all classes regardless of packages.

See related article: Java Access Modifiers Examples: public, protected, private and default

 

Packages allow us to group some related classes together for better organization and management:

For example, the java.util package ontains only interfaces and classes which belong to the Collections framework; The javax.swing package contains only interfaces and classes which are related to Graphical User Interface (GUI) components.

In practice, we tend to organize a complex application into packages for better organization and management, for example:

- com.mycompany.model: contains entity classes.

- com.mycompany.business: contain business classes.

- com.mycompany.gui: contains GUI classes.

etc.

 

3. How to use Packages in Java?

To specify a class under a certain package, we have to do 2 things:

- First, use the package statement to declare the package to which the class belongs. For example:

package com.nam.pets;

public class Dog {

}

Note that the packagestatement must be the only one and placed at the beginning of the source file. In case there are multiple classes in a source file, all classes are under the declared package.

- Second, create a directories structure that follow the package name from right to left. For the package com.nam.pets, we have to create 3 nested directories like this:

 package directory

NOTE: If you are using an IDE such as NetBeans or Eclipse, the IDE creates the package directory structure automatically for you. But you should understand and know how o create packages manually when needed.

 

How to compile a Java file under a package using the javac tool?

Just like normal: javac Dog.java

 

How to run a Java file under a package using the java tool?

This requires an extra step as compared with files that do not under any packages.

- First, change the current directory to the parent directory of the first directory in the package directories structure. For example, if the package name is com.nam.pets, change the current directory to the parent directory of the comdirectory.

- Second, specify the fully qualified name of the class with the java command. For example:

java com.nam.pets.Dog

 

NOTE: When using an IDE, the IDE does this task behind the scene to save time. But you should understand the principle so you will be able to run a Java file under a package manually when needed.

What if we want to use the Dog class from another class which is in another package, e.g. the Trainerclass in com.nam.training package?

In this case, there are two ways:

First, using the fully qualified name of the referenced class. For example:

package com.nam.training;

public class Trainer {
	void teach(com.nam.pets.Dog dog) {
		dog.bark();
	}
}

 This sounds okay. But if the Dog class is used repetitively, then using the fully qualified name makes the code hard to read. Hence we have the second way below.

  

4. Using the import statements in Java

An import statement is used to refer to a type which is outside the package of the current class. For example:

import com.nam.pets.Dog;

This refers to the Dog class in the package com.nam.pets.

The import statements should be placed after the package declaration and before the class declaration. For example:

package com.nam.training;

import com.nam.pets.Dog;

public class Trainer {
	void teach(Dog dog) {
		dog.bark();
	}
}

If the two classes are in the same package, there’s no need to use the import statements. There are two cases in which Java does the importing implicitly for us:

  • All classes in the java.lang package. That mean we can use the String, System, Integer, … classes without importing them.
  • All classes in the same package as the current class.

 

5. Wildcard Imports in Java

It would be tedious if we refer many types from a package by using a separate import statement for each type. For example:

import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;

import java.util.Set;

Here, the wildcard character * makes our life easier, as we can shorten the above import statements into just one import statement like this:

import java.util.*;

NOTE: The wildcard imports do not include types in sub packages. That means java.util.* does not include types in the java.util.concurrent package. Thus we have to import the sub packages explicitly:

import java.util.*;
import java.util.concurrent.*;
import java.awt.*;
import java.awt.event.*;

 

6. Static Imports in Java

Since Java 5, we can use the import statements to refer to static members (fields and methods) of a type (class or interface).

For example, the Math class has several static fields like E and PI and static methods like sin() and cos(). Without using static imports, our code would look like this:

int degree = 38;
double tetha = Math.PI * Math.sin(degree) + 3 * Math.cos(degree);

With a static import:

import static java.lang.Math.*;

Then our code would look more succinct:

int degree = 38;
double tetha = PI * sin(degree) + 3 * cos(degree);

 

The latter looks better, right?

Like regular import statements, we can use the static imports to refer to a single type or a group of types using the wildcard character *. For example:

import static java.lang.Math.PI;
import static java.lang.System.*;

 

That’s the core stuff about import statements in Java. I recommend you to read the Java Tutorials for more details:

                Using Package Members

And here I shared my practical experiences with regard to import statements:

  • Pay attention to the confusion when there are 2 classes having same name but in different packages, e.g. the ArrayList class in the java.util package and the ArrayList class in the java.awt package. In this case, we have to use the fully qualified name of each class.
  • Some IDEs such as NetBeans, place the import statements at the end of source files they generated.
  • When using IDEs, use the useful shortcuts (Ctrl + Shift + O with Eclipse; Ctrl + Shift + I with NetBeans) for organizing import statements automatically, e.g. adding the missing imports, removing the unused ones.
  • Always check and remove the unused imports.

 

Related Tutorials:

 

Other Recommended Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.

Add comment