epubjs
Version:
Render ePub documents in the browser, across many devices
147 lines (141 loc) • 18.1 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Packages and Compilation Units</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="sect1" title="Packages and Compilation Units"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-6-SECT-3"/>Packages and Compilation Units</h1></div></div></div><p>A <a id="I_indexterm6_id698048" class="indexterm"/><span class="emphasis"><em>package</em></span> is a name for a group of
related classes and interfaces. In <a class="xref" href="ch03.html" title="Chapter 3. Tools of the Trade">Chapter 3</a>, we
discussed how Java uses package names to locate classes during compilation
and at runtime. In this sense, packages are somewhat like libraries; they
organize and manage sets of classes. Packages provide more than just
source-code-level organization. They create an additional level of scope
for their classes and the variables and methods within them. We’ll talk
about the visibility of classes later in this section. In the next
section, we discuss the effect that packages have on access to variables
and methods among classes.</p><div class="sect2" title="Compilation Units"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-6-SECT-3.1"/>Compilation Units</h2></div></div></div><p><a id="idx10273" class="indexterm"/> <a id="idx10309" class="indexterm"/>The source code for Java classes is organized into
<span class="emphasis"><em>compilation units</em></span>. A simple compilation unit
contains a single class definition and is named for that class. The
definition of a class named <code class="literal">MyClass</code>,
for instance, could appear in a file named
<span class="emphasis"><em>MyClass.java</em></span>. For most of us, a compilation unit is
just a file with a <a id="I_indexterm6_id698119" class="indexterm"/><span class="emphasis"><em>.java</em></span> extension, but theoretically in
an IDE, it could be an arbitrary entity. For brevity, we’ll refer to a
compilation unit simply as a file.</p><p>The division of classes into their own files is important because
the Java compiler assumes much of the responsibility of a <a id="I_indexterm6_id698135" class="indexterm"/><span class="emphasis"><em>make</em></span> or <span class="emphasis"><em>build</em></span>
utility. The compiler relies on the names of source files to find and
compile dependent classes. It’s possible to put more than one class
definition into a single file, but there are some restrictions that
we’ll discuss shortly.</p><p>A class is declared to belong to a particular package with the
<a id="I_indexterm6_id698154" class="indexterm"/><code class="literal">package</code> statement. The
<code class="literal">package</code> statement must appear as the
first statement in a file. There can be only one <code class="literal">package</code> statement, and it applies to the
entire file:</p><a id="I_6_tt319"/><pre class="programlisting"> <code class="kn">package</code> <code class="n">mytools</code><code class="o">.</code><code class="na">text</code><code class="o">;</code>
<code class="kd">class</code> <code class="nc">TextComponent</code> <code class="o">{</code>
<code class="o">...</code>
<code class="o">}</code></pre><p>In this example, the class <code class="literal">TextComponent</code> is placed in the package
<code class="literal">mytools.text</code>.<a id="I_indexterm6_id698201" class="indexterm"/><a id="I_indexterm6_id698208" class="indexterm"/></p></div><div class="sect2" title="Package Names"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-6-SECT-3.2"/>Package Names</h2></div></div></div><p><a id="I_indexterm6_id698221" class="indexterm"/> <a id="I_indexterm6_id698228" class="indexterm"/> <a id="idx10316" class="indexterm"/>Package names are hierarchical in nature, using a
dot-separated naming convention. By default, package name components
correspond to directory names and serve as a unique path for the
compiler and runtime systems to locate Java source files and classes.
However, other than for locating files, package names in Java do not
create real relationships between packages. There is really no such
thing as a “subpackage.” The package
namespace is actually flat, not hierarchical. Packages under a
particular part of a package hierarchy are related only by convention.
For example, if we create another package called <code class="literal">mytools.text.poetry</code> (presumably for text
classes that are specialized in some way to work with poetry), those
classes won’t be part of the <code class="literal">mytools.text</code> package; they won’t have the
access privileges of package members. In this sense, the package-naming
convention can be misleading. One minor deviation from this notion is
that assertions, which we described in <a class="xref" href="ch04.html" title="Chapter 4. The Java Language">Chapter 4</a>, can be turned on or off for a package and
all packages “under” it. But that is really just a convenience and not
represented in the code structure.<a id="I_indexterm6_id698291" class="indexterm"/></p></div><div class="sect2" title="Class Visibility"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-6-SECT-3.3"/>Class Visibility</h2></div></div></div><p><a id="I_indexterm6_id698305" class="indexterm"/> <a id="I_indexterm6_id698313" class="indexterm"/>By default, a class is accessible only to other classes
within its package. This means that our <code class="literal">TextComponent</code> class is available only to other
classes in the <code class="literal">mytools.text</code> package.
To be used outside of its package, a class must be declared as <code class="literal">public</code>:</p><a id="I_6_tt320"/><pre class="programlisting"> <code class="kn">package</code> <code class="n">mytools</code><code class="o">.</code><code class="na">text</code><code class="o">;</code>
<code class="kd">public</code> <code class="kd">class</code> <code class="nc">TextEditor</code> <code class="o">{</code>
<code class="o">...</code>
<code class="o">}</code></pre><p>The class <code class="literal">TextEditor</code> can now be
referenced anywhere. A Java source code file can have only a single
<code class="literal">public</code> class defined within it and
the file must be named for that class.</p><p>By hiding unimportant or extraneous classes, a package builds a
<span class="emphasis"><em>subsystem</em></span> that has a well-defined interface to the
rest of the world. Public classes provide a <a id="I_indexterm6_id698372" class="indexterm"/><span class="emphasis"><em>facade</em></span> for the operation of the
system. The details of its inner workings can remain hidden, as shown in
<a class="xref" href="ch06s03.html#learnjava3-CHP-6-FIG-6" title="Figure 6-6. Packages and class visibility">Figure 6-6</a>. In this sense, packages can
hide classes in the way classes hide private members. Nonpublic classes
within a package are sometimes called <span class="emphasis"><em>package
private</em></span> for this reason.</p><div class="figure"><a id="learnjava3-CHP-6-FIG-6"/><div class="figure-contents"><div class="mediaobject"><a id="I_6_tt321"/><img src="httpatomoreillycomsourceoreillyimages1707624.png" alt="Packages and class visibility"/></div></div><p class="title">Figure 6-6. Packages and class visibility</p></div><p><a class="xref" href="ch06s03.html#learnjava3-CHP-6-FIG-6" title="Figure 6-6. Packages and class visibility">Figure 6-6</a> shows part of the
hypothetical <code class="literal">mytools.text</code> package.
The classes <code class="literal">Text</code><code class="literal">Area</code> and <code class="literal">TextEditor</code> are declared <code class="literal">public</code> so that they can be used elsewhere in
an application. The class <code class="literal">TextComponent</code> is part of the implementation of
<code class="literal">TextArea</code> and is not accessible from
outside of the package.</p></div><div class="sect2" title="Importing Classes"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-6-SECT-3.4"/>Importing Classes</h2></div></div></div><p><a id="I_indexterm6_id698465" class="indexterm"/> <a id="idx10315" class="indexterm"/>Classes within a package can refer to each other by their
simple names. However, to locate a class in another package, we have to
be more specific. Continuing with the previous example, an application
can refer directly to our editor class by its <span class="emphasis"><em>fully qualified
name</em></span> of <code class="literal">mytools.text.TextEditor</code>. But we’d quickly grow
tired of typing such long class names, so Java gives us the <code class="literal">import</code> statement. One or more <code class="literal">import</code> statements can appear at the top of a
compilation unit, after the <code class="literal">package</code>
statement. The <code class="literal">import</code> statements list
the fully qualified names of classes and packages to be used within the
file.</p><p>Like a <code class="literal">package</code> statement, an
<code class="literal">import</code> statement applies to the
entire compilation unit. Here’s how you might use an <code class="literal">import</code> statement:</p><a id="I_6_tt322"/><pre class="programlisting"> <code class="kn">package</code> <code class="n">somewhere</code><code class="o">.</code><code class="na">else</code><code class="o">;</code>
<code class="kn">import</code> <code class="nn">mytools.text.TextEditor</code><code class="o">;</code>
<code class="kd">class</code> <code class="nc">MyClass</code> <code class="o">{</code>
<code class="n">TextEditor</code> <code class="n">editBoy</code><code class="o">;</code>
<code class="o">...</code>
<code class="o">}</code></pre><p>As shown in this example, once a class is imported, it can be
referenced by its simple name throughout the code. It is also possible
to import all the classes in a package using the <a id="I_indexterm6_id698556" class="indexterm"/><a id="I_indexterm6_id698564" class="indexterm"/><code class="literal">*</code> wildcard
notation:</p><a id="I_6_tt323"/><pre class="programlisting"> <code class="kn">import</code> <code class="nn">mytools.text.*</code><code class="o">;</code></pre><p>Now we can refer to all <code class="literal">public</code>
classes in the <code class="literal">mytools.text</code> package
by their simple names.</p><p>Obviously, there can be a problem with importing classes that have
conflicting names. The compiler prevents you from explicitly importing
two classes with the same name and gives you an error if you try to use
an ambiguous class that could come from two packages imported with the
package <code class="literal">import</code> notation. In this
case, you just have to fall back to using fully qualified names to refer
to those classes. You can either use the fully qualified name directly,
or you can add an additional, single class <code class="literal">import</code> statement that disambiguates the class
name. It doesn’t matter whether this comes before or after the package
import.</p><p>Other than the potential for naming conflicts, there’s no penalty
for importing many classes. Java doesn’t carry extra baggage into the
compiled class files. In other words, Java class files don’t contain
information about the imports; they only reference classes actually used
in them.</p><div class="note" title="Note"><h3 class="title">Note</h3><p>One note about conventions: in an effort to keep our examples
short, we’ll sometimes import entire packages (.*) even when we use
only a class or two from it. In practice, it’s usually better to be
specific when possible and list individual, fully qualified class
imports if there are only a few of them. Some people (especially those
using IDEs that do it for them) avoid using package imports entirely,
choosing to list every imported class individually. Usually, a
compromise is your best bet. If you are going to use more than two or
three classes from a package, consider the package import.</p></div><div class="sect3" title="The unnamed package"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-6-SECT-3.4.1"/>The unnamed package</h3></div></div></div><p><a id="I_indexterm6_id698644" class="indexterm"/> <a id="I_indexterm6_id698654" class="indexterm"/> <a id="idx10342" class="indexterm"/>A class that is defined in a compilation unit that
doesn’t specify a package falls into the large, amorphous unnamed
package. Classes in this nameless package can refer to each other by
their simple names. Their path at compile time and runtime is
considered to be the current directory, so packageless classes are
useful for experimentation and testing (and for brevity in examples in
books about Java).<a id="I_indexterm6_id698681" class="indexterm"/></p></div><div class="sect3" title="Static imports"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-6-SECT-3.4.2"/>Static imports</h3></div></div></div><p><a id="I_indexterm6_id698695" class="indexterm"/> <a id="I_indexterm6_id698706" class="indexterm"/> <a id="I_indexterm6_id698716" class="indexterm"/>A <span class="emphasis"><em>static import</em></span> is a variation of
the <a id="I_indexterm6_id698726" class="indexterm"/><code class="literal">import</code> statement that
allows you to import static members of a class into the namespace of
your file so that you don’t have to qualify them when you use them.
The best example of this is in working with the <code class="literal">java.lang.Math</code> class. With static import, we
can get an illusion of built-in math “functions” and constants like
so:</p><a id="I_6_tt324"/><pre class="programlisting"> <code class="kn">import</code> <code class="nn">static</code> <code class="n">java</code><code class="o">.</code><code class="na">lang</code><code class="o">.</code><code class="na">Math</code><code class="o">.*;</code>
<code class="c1">// usage</code>
<code class="kt">double</code> <code class="n">circumference</code> <code class="o">=</code> <code class="mi">2</code> <code class="o">*</code> <code class="n">PI</code> <code class="o">*</code> <code class="n">radius</code><code class="o">;</code>
<code class="kt">double</code> <code class="n">length</code> <code class="o">=</code> <code class="n">sin</code><code class="o">(</code> <code class="n">theta</code> <code class="o">)</code> <code class="o">*</code> <code class="n">side</code><code class="o">;</code>
<code class="kt">int</code> <code class="n">bigger</code> <code class="o">=</code> <code class="n">max</code><code class="o">(</code> <code class="n">a</code><code class="o">,</code> <code class="n">b</code> <code class="o">);</code>
<code class="kt">int</code> <code class="n">positive</code> <code class="o">=</code> <code class="n">abs</code><code class="o">(</code> <code class="n">num</code> <code class="o">);</code></pre><p>This example imports all of the static members of the <code class="literal">java.lang.Math</code> class. We can also import
individual members by name:</p><a id="I_6_tt325"/><pre class="programlisting"> <code class="kn">import</code> <code class="nn">static</code> <code class="n">java</code><code class="o">.</code><code class="na">awt</code><code class="o">.</code><code class="na">Color</code><code class="o">.</code><code class="na">RED</code><code class="o">;</code>
<code class="kn">import</code> <code class="nn">static</code> <code class="n">java</code><code class="o">.</code><code class="na">awt</code><code class="o">.</code><code class="na">Color</code><code class="o">.</code><code class="na">WHITE</code><code class="o">;</code>
<code class="kn">import</code> <code class="nn">static</code> <code class="n">java</code><code class="o">.</code><code class="na">awt</code><code class="o">.</code><code class="na">Color</code><code class="o">.</code><code class="na">BLUE</code><code class="o">;</code>
<code class="c1">// usage</code>
<code class="n">setField</code><code class="o">(</code> <code class="n">BLUE</code> <code class="o">);</code>
<code class="n">setStripe</code><code class="o">(</code> <code class="n">RED</code> <code class="o">);</code>
<code class="n">setStripe</code><code class="o">(</code> <code class="n">WHITE</code> <code class="o">);</code></pre><p>To be precise, these static imports are importing a name, not a
specific member, into the namespace of our file. For example,
importing the name “foo” would bring in any constants named <code class="literal">foo</code> as well as any methods named <code class="literal">foo()</code> in the class.</p><p>Static imports are compelling and make code more succinct. Their
usage, however, goes somewhat against the concepts of object-oriented
programming. Static imports are best for utilities and other global
convenience methods that do not require much context.<a id="I_indexterm6_id698800" class="indexterm"/></p></div></div></div></body></html>