1.3. Java packages

[1.4] Import other Java packages to make them accessible in your code

This exam covers importing packages into other classes. But with more than a decade and a half of experience, I’ve learned that before starting to import other packages into your own code, it’s important to understand what packages are, the difference between classes that are defined in a package and the classes that aren’t defined in a package, and why you need to import packages in your code.

In this section, you’ll learn what Java packages are and how to create them. You’ll use the import statement, which enables you to use simple names for classes and interfaces defined in separate packages.

1.3.1. The need for packages

Why do you think we need packages? First, answer this question: do you remember having known more than one Amit, Paul, Anu, or John in your life? Harry knows more than one Paul (six, to be precise), whom he categorizes as managers, friends, and cousins. These are subcategorized by their location and relation, as shown in figure 1.10.

Figure 1.10. Harry knows six Pauls!

Similarly, you can use a package to group together a related set of classes and interfaces (I won’t discuss enums here because they aren’t covered on this exam). Packages also provide access protection and namespace management. You can create separate packages to define classes for separate projects, such as Android games and online healthcare systems. Further, you can create subpackages within these packages, such as separate subpackages for GUIs, database access, networking, and so on.

Note

In real-life projects, you’ll rarely work with a package-less class or interface. Almost all organizations that develop software have strict package-naming rules, which are often documented.

All classes and interfaces are defined in a package. If you don’t include an explicit package statement in a class or an interface, it’s part of a default package.

1.3.2. Defining classes in a package using the package statement

You can indicate that a class or an interface is defined in a package by using the package statement as the first statement in code. Here’s an example:

The class in the preceding code defines an ExamQuestion class in the certification package. You can define an interface, MultipleChoice, in a similar manner:

package certification;
interface MultipleChoice {

    void choice1();
    void choice2();
}

Figure 1.11 shows a UML class diagram depicting the relationship of the package certification to the class ExamQuestion and the interface MultipleChoice.

Figure 1.11. A UML class diagram showing the relationship shared by package certification, class ExamQuestion, and interface MultipleChoice

The name of the package in the previous examples is certification. You may use such names for small projects that contain only a few classes and interfaces, but it’s common for organizations to use subpackages to define all their classes. For example, if the folks at Oracle were to define a class to store exam questions for a Java Associate exam, they might use the package name com.oracle.javacert.associate. Figure 1.12 shows its UML representation, together with the corresponding class definition.

Figure 1.12. A subpackage and its corresponding class definition

A package is made of multiple sections that go from the more-generic (left) to the more-specific (right). The package name com.oracle.javacert.associate follows a package-naming convention recommended by Oracle and shown in table 1.2.

Table 1.2. Package-naming conventions used in the package name com.oracle.javacert.associate

Package or subpackage name

Its meaning

com Commercial. A couple of the commonly used three-letter package abbreviations are
  • gov—for government bodies
  • edu—for educational institutions
oracle Name of the organization
javacert Further categorization of the project at Oracle
associate Further subcategorization of Java certification
Rules to remember

Here are a few of important rules about packages:

  • Per Java naming conventions, package names should all be in lowercase.
  • The package and subpackage names are separated using a dot (.).
  • Package names follow the rules defined for valid identifiers in Java.
  • For classes and interfaces defined in a package, the package statement is the first statement in a Java source file (a .java file). The exception is that comments can appear before or after a package statement.
  • There can be a maximum of one package statement per Java source code file (.java file).
  • All the classes and interfaces defined in a Java source code file are defined in the same package. They can’t be defined in separate packages.
Note

A fully qualified name for a class or interface is formed by prefixing its package name with its name (separated by a dot). The fully qualified name of the class ExamQuestion is certification.ExamQuestion in figure 1.11 and com.oracle.javacert.associate.ExamQuestion in figure 1.12.

Directory structure and package hierarchy

The hierarchy of classes and interfaces defined in packages must match the hierarchy of the directories in which these classes and interfaces are defined in the code. For example, the class ExamQuestion in the certification package should be defined in a directory with the name “certification.” The name of the directory “certification” and its location are governed by the rules shown in figure 1.13.

Figure 1.13. Matching directory structure and package hierarchy

For the package example shown in figure 1.13, note that there isn’t any constraint on the location of the base directory in which the directory structure is defined, as shown in figure 1.14.

Figure 1.14. There’s no constraint on the location of the base directory to define directories corresponding to package hierarchy.

Setting the classpath for packaged classes

To enable the Java Runtime Environment (JRE) to find your classes, add the base directory that contains your packaged Java code to the classpath.

For example, to enable the JRE to locate the certification.ExamQuestion class from the previous examples, add the directory C:MyCode to the classpath. To enable the JRE to locate the class com.oracle.javacert.associate.ExamQuestion, add the directory C:ProjectCode to the classpath.

Note

You needn’t bother setting the classpath if you’re working with an IDE. But I strongly encourage you to learn how to work with a simple text editor and how to set a classpath. This can be helpful with your projects at work. The exam expects you to spot code with compilation errors, which isn’t easy to do if you didn’t learn how to do it without an IDE (IDEs usually include code autocorrection or autocompletion features).

1.3.3. Using simple names with import statements

The import statement enables you to use simple names instead of using fully qualified names for classes and interfaces defined in separate packages.

Let’s work with a real-life example. Imagine your home and your office. LivingRoom and Kitchen within your home can refer to each other without mentioning that they exist within the same home. Similarly, in an office, a Cubicle and a ConferenceHall can reference each other without explicitly mentioning that they exist within the same office. But Home and Office can’t access each other’s rooms or cubicles without stating that they exist in a separate home or office. This situation is represented in figure 1.15.

Figure 1.15. To refer to each other’s members, Home and Office should specify that they exist in separate places.

To refer to the LivingRoom in Cubicle, you must specify its complete location, as shown in the left part of the figure 1.16. As you can see in this figure, repeated references to the location of LivingRoom make the description of LivingRoom look tedious and redundant. To avoid this, you can display a notice in Cubicle that all occurrences of LivingRoom refer to LivingRoom in Home and thereafter use its simple name. Home and Office are like Java packages, and this notice is the equivalent of the import statement. Figure 1.16 shows the difference in using fully qualified names and simple names for LivingRoom in Cubicle.

Figure 1.16. LivingRoom can be accessed in Cubicle by using its fully qualified name. It can also be accessed using its simple name if you also use the import statement.

Let’s implement the preceding example in code, where classes LivingRoom and Kitchen are defined in the package home and classes Cubicle and ConferenceHall are defined in the package office. Class Cubicle uses (is associated to) class LivingRoom in the package home, as shown in figure 1.17.

Figure 1.17. A UML representation of classes LivingRoom and Cubicle, defined in separate packages, with their associations

Class Cubicle can refer to class LivingRoom without using an import statement:

Class Cubicle can use the simple name for class LivingRoom by using the import statement:

Note

The import statement doesn’t embed the contents of the imported class in your class, which means that importing more classes doesn’t increase the size of your own class.

1.3.4. Using packaged classes without using the import statement

It’s possible to use a packaged class or interface without using the import statement, by using its fully qualified name:

But using a fully qualified class name can clutter your code if you create multiple variables of interfaces and classes defined in other packages. Don’t use this approach in real projects.

Exam Tip

You don’t need an explicit import statement to use members from the java.lang package. Classes and interfaces in this package are automatically imported in all other Java classes, interfaces, or enums.

For the exam, it’s important to note that you can’t use the import statement to access multiple classes or interfaces with the same names from different packages. For example, the Java API defines class Date in two commonly used packages: java.util and java.sql. To define variables of these classes in a class, use their fully qualified names with the variable declaration:

An attempt to use an import statement to import both these classes in the same class will not compile:

An alternate approach (which works well in real projects) is to use the import definition with the class or interface that you use more often and fully reference the one that you use just from time to time:

1.3.5. Importing a single member versus all members of a package

You can import either a single member or all members (classes and interfaces) of a package using the import statement. First, revisit the UML notation of the certification package, as shown in figure 1.18.

Figure 1.18. A UML representation of the certification package

Examine the following code for the class AnnualExam:

By using the wildcard character, an asterisk (*), you can import all the public members, classes, and interfaces of a package. Compare the previous class definition with the following definition of the class AnnualExam:

Note

When overused, using an asterisk to import all members of a package has a drawback. It may be harder to figure out which imported class or interface comes from which package.

When you work with an IDE, it may automatically add import statements for classes and interfaces that you reference in your code.

1.3.6. The import statement doesn’t import the whole package tree

You can’t import classes from a subpackage by using an asterisk in the import statement. For example, the UML notation in figure 1.19 depicts the package com.oracle.javacert with the class Schedule and two subpackages, associate and webdeveloper. Package associate contains class ExamQuestion, and package webdeveloper contains class MarkSheet.

Figure 1.19. A UML representation of package com.oracle.javacert and its subpackages

The following import statement will import only the class Schedule. It won’t import the classes ExamQuestion and MarkSheet:

Similarly, the following import statement will import all the classes from the packages associate and webdeveloper:

1.3.7. Importing classes from the default package

What happens if you don’t include a package statement in your classes or interfaces? In that case, they become part of a default, no-name package. This default package is automatically imported in the Java classes and interfaces defined within the same directory on your system.

For example, the classes Person and Office, which aren’t defined in an explicit package, can use each other if they’re defined in the same directory:

A class from a default package can’t be used in any named packaged class, regardless of whether they’re defined within the same directory or not.

Exam Tip

Members of a named package can’t access classes and interfaces defined in the default package.

1.3.8. Static imports

You can import an individual static member of a class or all its static members by using the import static statement. Although accessible using an instance, the static members are better accessed by prefixing their name with the class or interface names. By using static import, you can drop the prefix and just use the name of the static variable or method. In the following code, class ExamQuestion defines a public static variable marks and a public static method print:

The marks variable can be accessed in the class AnnualExam using the import static statement. The order of the keywords import and static can’t be reversed:

Exam Tip

This feature is called static imports, but the syntax is import static.

To access all public and static members of class ExamQuestion in class AnnualExam without importing each of them individually, you can use an asterisk with the import static statement:

Because the variable marks and method print are defined as public members, they’re accessible to the class AnnualExam. By using the import static statement, you don’t have to prefix them with their class name.

Note

On real projects, avoid overusing static imports; otherwise, the code might become a bit confusing about which imported component comes from which class.

The accessibility of a class, an interface, and their methods and variables is determined by their access modifiers, which are covered in the next section.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.128.145