Chapter 1 - Java for Beginners Course

Packages - Organizing the code

The last topic we’ll cover in this chapter relates to the organization of the code and it’s something we make use of in the example project under the "Code in GitHub" section.#

Packages provide a way to organize sets of related classes into the same namespace, similar to what is done to organize files inside folders in a computer. This also helps managing the classes in larger projects where you might have hundreds or thousands of files.

In your IDE, these will be displayed under your project folder, for example, in Eclipse:

Java Packages Example

Other IDEs will display them in a very similar way.

In the example screenshot above, we have 3 different packages:

  1. The default package, which contains all the classes and others that don’t specify a package name. In IntelliJ, they’ll be displayed under the source folder directly, in our case under src/main/java.

  2. io.jcoder.tutorials.ch01.dotoperator: Where we added the example classes related to the dot operator section of chapter 1.

  3. io.jcoder.tutorials.string: Which includes classes related to a tutorial about Strings (the name of the package should give an indication of what the classes are about).

Package declaration

Let’s take a look at the Door class again from our example project (the one from GitHub).

// ...
package io.jcoder.tutorials.ch01.dotoperator;

public class Door {
	//...
}

The package statement, if provided, needs to be the first statement at the top of the file (comments and empty lines are ignored). In this case, we are telling Java that all classes defined in the Door.java file will fall under the io.jcoder.tutorials.ch01.dotoperator package.

Relationship to the folder structure

If you open your project in a Folder Explorer, you’ll see that the folder structure resembles the packages we defined in the code.

Even though the Java specification doesn’t enforce this, this has become the Java industry norm and is part of different Java implementations.

This means that in our project:

  1. We have a source folder, in our case the source folder is src/main/java: Here is where we are storing our Java source code and will be considered the 'root' of our code.

  2. Under src/main/java, you’ll find this folder structure: io/jcoder/tutorials/ch01/dotoperator, and in there you’ll find both the Door.java file and the DoorApp.java file, as both of them define the same package name.

  3. If we had a package called io.jcoder.packageone in our project, we’d expect to find a src/main/java/io/jcoder/packageone folder.

How often do I need to manage this manually?

Nowadays, most IDEs will manage the folder structure for the developer, so very rarely you’ll find yourself going into a Folder Explorer and changing folder names/locations manually.

IDEs have evolved a lot over time and include tools to rename/move/refactor your code as you see fit and they’ll rename the packages inside the files that need to be renamed.

So, no need to worry about having to manage this by hand!

Naming Convention

  1. To avoid clashes between class names from different organizations, it is good practice to include the reverse web domain as the beginning of the package name. In our case, we are using io.jcoder as the top level package.

  2. The rest of the package name is based on what makes most sense for the organization and the project.

  3. It’s standard to only use lower-case names in the packages.

Using a class from a different package

If the code in package io.jcoder.packagetwo needs to access or make use of a class from the package in io.jcoder.packageone, we need to make use of the import statement.

For example:

package io.jcoder.tutorials.packageone;

public class ExampleOne {
	//...
}
package io.jcoder.tutorials.packagetwo;

import io.jcoder.tutorials.packageone.ExampleOne;

public class ExampleTwo {
	private ExampleOne exampleObject;

	//...
}

Here, we are making use of the ExampleOne class from the ExampleTwo class. Hence, we need to include an import io.jcoder.tutorials.packageone.ExampleOne statement to tell Java we need that class.

The io.jcoder.tutorials.packageone.ExampleOne is known as the fully qualified name of the ExampleOne class as it contains its full 'path'.

Using a class from the same package

If the classes are in the same package, you don’t need to use import. For example, in the DoorApp class where we use the Door class, both classes are in the same package. They’ll be imported automatically by the Java compiler.

The other package that is automatically included is the one that contains the fundamental classes from the Java language. This is the java.lang package which you can find in the Java API documentation.

More examples of packages

The Java API contains several packages that provide different sets of functionality.

It’s worth taking a quick look at them to get more familiar with the packages and classes that are offered by the Java language directly. You’ll recognize classes that come directly from Java because they live under packages that start with either java. or javax..

What about Modules and Java 9?

If you’ve been reading about the upcoming features in Java 9, a new concept of Module has been introduced that gives developers more control about what packages get exposed and can be used by other modules.

We won’t be covering this concept in this course, however, we’ll be adding a separate Java 9 Modules tutorial later.