epubjs
Version:
Render ePub documents in the browser, across many devices
395 lines (390 loc) • 45.5 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Inner Classes</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="Inner Classes"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-6-SECT-6"/>Inner Classes</h1></div></div></div><p><a id="I_indexterm6_id699797" class="indexterm"/> All of the classes we’ve seen so far in this book have been
<span class="emphasis"><em>top-level</em></span>, “freestanding” classes declared at the
file and package level. But classes in Java can actually be declared at
any level of scope, within any set of curly braces (i.e., almost anywhere
that you could put any other Java statement). These <span class="emphasis"><em>inner
classes</em></span> belong to another class or method as a variable would
and may have their visibility limited to its scope in the same way. Inner
classes are a useful and aesthetically pleasing facility for structuring
code. Their cousins, <span class="emphasis"><em>anonymous inner classes</em></span>, are an
even more powerful shorthand that make it seem as if you can create new
kinds of objects dynamically within Java’s statically typed environment.
In Java, anonymous inner classes play part of the role of <a id="I_indexterm6_id699828" class="indexterm"/><span class="emphasis"><em>closures</em></span> in other languages, giving the
effect of handling state and behavior independently of classes.</p><p>However, as we delve into their inner workings, we’ll see that inner
classes are not quite as aesthetically pleasing or dynamic as they seem.
Inner classes are pure syntactic sugar; they are not supported by the VM
and are instead mapped to regular Java classes by the compiler. As a
programmer, you may never need be aware of this; you can simply rely on
inner classes like any other language construct. However, you should know
a little about how inner classes work to better understand the compiled
code and a few potential side effects.</p><p>Inner classes are essentially nested classes, for example:</p><a id="I_6_tt334"/><pre class="programlisting"> <code class="n">Class</code> <code class="n">Animal</code> <code class="o">{</code>
<code class="n">Class</code> <code class="n">Brain</code> <code class="o">{</code>
<code class="o">...</code>
<code class="o">}</code>
<code class="o">}</code></pre><p>Here, the class <code class="literal">Brain</code> is an inner
class: it is a class declared inside the scope of class <code class="literal">Animal</code>. Although the details of what that means
require a bit of explanation, we’ll start by saying that Java tries to
make the meaning, as much as possible, the same as for the other members
(methods and variables) living at that level of scope. For example, let’s
add a method to the <code class="literal">Animal</code>
class:</p><a id="I_6_tt335"/><pre class="programlisting"> <code class="n">Class</code> <code class="n">Animal</code> <code class="o">{</code>
<code class="n">Class</code> <code class="n">Brain</code> <code class="o">{</code>
<code class="o">...</code>
<code class="o">}</code>
<code class="kt">void</code> <code class="nf">performBehavior</code><code class="o">()</code> <code class="o">{</code> <code class="o">...</code> <code class="o">}</code>
<code class="o">}</code></pre><p>Both the inner class <code class="literal">Brain</code> and the method <code class="literal">performBehavior()</code> are within the scope of
<code class="literal">Animal</code>. Therefore, anywhere within
<code class="literal">Animal</code>, we can refer to <code class="literal">Brain</code> and <code class="literal">performBehavior()</code> directly, by name. Within
<code class="literal">Animal</code>, we can call the constructor for
<code class="literal">Brain</code> (<code class="literal">new
Brain()</code>) to get a <code class="literal">Brain</code>
object or invoke <code class="literal">performBehavior()</code> to
carry out that method’s function. But neither <code class="literal">Brain</code> nor <code class="literal">performBehavior()</code> are generally accessible
outside of the class <code class="literal">Animal</code> without
some additional qualification.</p><p>Within the body of the inner <code class="literal">Brain</code> class and the body of the <code class="literal">performBehavior()</code> method, we have direct access
to all the other methods and variables of the <code class="literal">Animal</code> class. So, just as the <code class="literal">performBehavior()</code> method could work with the
<code class="literal">Brain</code> class and create instances of
<code class="literal">Brain</code>, methods within the <code class="literal">Brain</code> class can invoke the <code class="literal">performBehavior()</code> method of <code class="literal">Animal</code> as well as work with any other methods
and variables declared in <code class="literal">Animal</code>. The
<code class="literal">Brain</code> class “sees” all of the methods
and variables of the <code class="literal">Animal</code> class
directly in its scope.</p><p>That last bit has important consequences. From within <code class="literal">Brain</code>, we can invoke the method <code class="literal">performBehavior()</code>; that is, from within an
instance of <code class="literal">Brain</code>, we can invoke the
<code class="literal">performBehavior()</code> method of an instance
of <code class="literal">Animal</code>. Well, which instance of
<code class="literal">Animal</code>? If we have several <code class="literal">Animal</code> objects around (say, a few <code class="literal">Cat</code>s and <code class="literal">Dog</code>s), we need to know whose <code class="literal">performBehavior()</code> method we are calling. What
does it mean for a class definition to be “inside” another class
definition? The answer is that a <code class="literal">Brain</code>
object always lives within a single instance of <code class="literal">Animal</code>: the one that it was told about when it
was created. We’ll call the object that contains any instance of <code class="literal">Brain</code> its <span class="emphasis"><em>enclosing
instance</em></span>.</p><p>A <code class="literal">Brain</code> object cannot live
outside of an enclosing instance of an <code class="literal">Animal</code> object. Anywhere you see an instance of
<code class="literal">Brain</code>, it will be tethered to an
instance of <code class="literal">Animal</code>. Although it is
possible to construct a <code class="literal">Brain</code> object
from elsewhere (i.e., another class), <code class="literal">Brain</code> always requires an enclosing instance of
<code class="literal">Animal</code> to “hold” it. We’ll also say now
that if <code class="literal">Brain</code> is to be referred to from
outside of <code class="literal">Animal</code>, it acts something
like an <code class="literal">Animal.Brain</code> class. And just as
with the <code class="literal">performBehavior()</code> method,
modifiers can be applied to restrict its visibility. All of the usual
visibility modifiers apply, and inner classes can also be declared
<code class="literal">static</code>, as we’ll discuss later.</p><p>We’ve said that within the <code class="literal">Animal</code>
class, we can construct a <code class="literal">Brain</code> in the
ordinary way, using <code class="literal">new Brain()</code>, for
example. Although we’d probably never find a need to do it, we can also
construct an instance of <code class="literal">Brain</code> from
outside the class by referencing an instance of <code class="literal">Animal</code>. To do this requires that the inner class
<code class="literal">Brain</code> be accessible and that we use a
special form of the <a id="I_indexterm6_id700237" class="indexterm"/><code class="literal">new</code> operator designed
just for inner classes:</p><a id="I_6_tt336"/><pre class="programlisting"> <code class="n">Animal</code> <code class="n">monkey</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Animal</code><code class="o">();</code>
<code class="n">Animal</code><code class="o">.</code><code class="na">Brain</code> <code class="n">monkeyBrain</code> <code class="o">=</code> <code class="n">monkey</code><code class="o">.</code><code class="na">new</code> <code class="n">Brain</code><code class="o">();</code></pre><p>Here, the <code class="literal">Animal</code> instance
<code class="literal">monkey</code> is used to qualify the <code class="literal">new</code> operator on <code class="literal">Brain</code>. Again, this is not a very common thing to
do and you can probably just forget that we said anything about it. Static
inner classes are more useful. We’ll talk about them a bit later.</p><div class="sect2" title="Inner Classes as Adapters"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-6-SECT-6.1"/>Inner Classes as Adapters</h2></div></div></div><p><a id="idx10278" class="indexterm"/> <a id="idx10310" class="indexterm"/>A particularly important use of inner classes is to make
<span class="emphasis"><em>adapter classes</em></span>. An adapter class is a “helper”
class that ties one class to another in a very specific way. Using
adapter classes, you can write your classes more naturally, without
having to anticipate every conceivable user’s needs in advance. Instead,
you provide adapter classes that marry your class to a particular
interface. As an example, let’s say that we have an <code class="literal">Employee</code><code class="literal">List</code> object:</p><a id="I_6_tt337"/><pre class="programlisting"> <code class="kd">public</code> <code class="kd">class</code> <code class="nc">EmployeeList</code> <code class="o">{</code>
<code class="kd">private</code> <code class="n">Employee</code> <code class="o">[]</code> <code class="n">employees</code> <code class="o">=</code> <code class="o">...</code> <code class="o">;</code>
<code class="o">...</code>
<code class="o">}</code></pre><p><code class="literal">EmployeeList</code> holds information
about a set of employees. Let’s say that we would like to have <code class="literal">EmployeeList</code> provide its elements via an
iterator. An iterator is a simple, standard interface to a sequence of
objects. The <code class="literal">java.util.Iterator</code>
interface has several methods:</p><a id="I_6_tt338"/><pre class="programlisting"> <code class="kd">public</code> <code class="kd">interface</code> <code class="nc">Iterator</code> <code class="o">{</code>
<code class="kt">boolean</code> <code class="nf">hasNext</code><code class="o">();</code>
<code class="n">Object</code> <code class="nf">next</code><code class="o">();</code>
<code class="kt">void</code> <code class="nf">remove</code><code class="o">();</code>
<code class="o">}</code></pre><p>It lets us step through its elements, asking for the next one and
testing to see if more remain. The iterator is a good candidate for an
adapter class because it is an interface that our <code class="literal">EmployeeList</code> can’t readily implement itself.
Why can’t the list implement the iterator directly? Because an iterator
is a “one-way,” disposable view of our data. It isn’t intended to be
reset and used again. It may also be necessary for there to be multiple
iterators walking through the list at different points. We must,
therefore, keep the iterator implementation separate from the <code class="literal">EmployeeList</code> itself. This is crying out for a
simple class to provide the iterator capability. But what should that
class look like?</p><p>Before we knew about inner classes, our only recourse would have
been to make a new “top-level” class. We would probably feel obliged to
call it <code class="literal">EmployeeListIterator</code>:</p><a id="I_6_tt339"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">EmployeeListIterator</code> <code class="kd">implements</code> <code class="n">Iterator</code> <code class="o">{</code>
<code class="c1">// lots of knowledge about EmployeeList</code>
<code class="o">...</code>
<code class="o">}</code></pre><p>Here we have a comment representing the machinery that the
<code class="literal">EmployeeListIterator</code> requires. Think
for just a second about what you’d have to do to implement that
machinery. The resulting class would be completely coupled to the
<code class="literal">EmployeeList</code> and unusable in other
situations. Worse, in order to to function, it must have access to the
inner workings of <code class="literal">EmployeeList</code>. We
would have to allow <code class="literal">EmployeeListIterator</code> access to the private
array in <code class="literal">EmployeeList</code>, exposing this
data more widely than it should be. This is less than ideal.</p><p>This sounds like a job for inner classes. We already said that
<code class="literal">EmployeeListIterator</code> was useless
without an <code class="literal">EmployeeList</code>; this sounds
a lot like the “lives inside” relationship we described earlier.
Furthermore, an inner class lets us avoid the encapsulation problem
because it can access all the members of its enclosing instance.
Therefore, if we use an inner class to implement the iterator, the array
<code class="literal">employees</code> can remain <code class="literal">private</code>, invisible outside the <code class="literal">EmployeeList</code>. So let’s just shove that helper
class inside the scope of our <code class="literal">EmployeeList</code>:</p><a id="I_6_tt340"/><pre class="programlisting"> <code class="kd">public</code> <code class="kd">class</code> <code class="nc">EmployeeList</code> <code class="o">{</code>
<code class="kd">private</code> <code class="n">Employee</code> <code class="o">[]</code> <code class="n">employees</code> <code class="o">=</code> <code class="o">...</code> <code class="o">;</code>
<code class="o">...</code>
<code class="kd">class</code> <code class="nc">Iterator</code> <code class="kd">implements</code> <code class="n">java</code><code class="o">.</code><code class="na">util</code><code class="o">.</code><code class="na">Iterator</code> <code class="o">{</code>
<code class="kt">int</code> <code class="n">element</code> <code class="o">=</code> <code class="mi">0</code><code class="o">;</code>
<code class="kt">boolean</code> <code class="nf">hasNext</code><code class="o">()</code> <code class="o">{</code>
<code class="k">return</code> <code class="n">element</code> <code class="o"><</code> <code class="n">employees</code><code class="o">.</code><code class="na">length</code> <code class="o">;</code>
<code class="o">}</code>
<code class="n">Object</code> <code class="nf">next</code><code class="o">()</code> <code class="o">{</code>
<code class="k">if</code> <code class="o">(</code> <code class="n">hasNext</code><code class="o">()</code> <code class="o">)</code>
<code class="k">return</code> <code class="n">employees</code><code class="o">[</code> <code class="n">element</code><code class="o">++</code> <code class="o">];</code>
<code class="k">else</code>
<code class="k">throw</code> <code class="k">new</code> <code class="nf">NoSuchElementException</code><code class="o">();</code>
<code class="o">}</code>
<code class="kt">void</code> <code class="nf">remove</code><code class="o">()</code> <code class="o">{</code>
<code class="k">throw</code> <code class="k">new</code> <code class="nf">UnsupportedOperationException</code><code class="o">();</code>
<code class="o">}</code>
<code class="o">}</code>
<code class="o">}</code></pre><p>Now <code class="literal">EmployeeList</code> can provide a
method like the following to let other classes work with the
list:</p><a id="I_6_tt341"/><pre class="programlisting"> <code class="n">Iterator</code> <code class="nf">getIterator</code><code class="o">()</code> <code class="o">{</code>
<code class="k">return</code> <code class="k">new</code> <code class="nf">Iterator</code><code class="o">();</code>
<code class="o">}</code></pre><p>One effect of the move is that we are free to be a little more
familiar in the naming of our iterator class. Since it is no longer a
top-level class, we can give it a name that is appropriate only within
the <code class="literal">EmployeeList</code>. In this case, we’ve
named it <code class="literal">Iterator</code> to emphasize what
it does, but we don’t need a name like <code class="literal">EmployeeIterator</code> that shows the relationship
to the <code class="literal">EmployeeList</code> class because
that’s implicit. We’ve also filled in the guts of the <code class="literal">Iterator</code> class. As you can see, now that it is
inside the scope of <code class="literal">EmployeeList</code>,
<code class="literal">Iterator</code> has direct access to its
private members, so it can directly access the <code class="literal">employees</code> array. This greatly simplifies the
code and maintains compile-time safety.</p><p>Before we move on, we should note that inner classes can have
constructors, variables, and initializers, even though we didn’t need
one in this example. They are, in all respects, real classes.<a id="I_indexterm6_id700605" class="indexterm"/><a id="I_indexterm6_id700612" class="indexterm"/></p></div><div class="sect2" title="Inner Classes Within Methods"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-6-SECT-6.2"/>Inner Classes Within Methods</h2></div></div></div><p><a id="idx10311" class="indexterm"/>Inner classes may also be declared for “local” use within
the body of a method. Returning to the <code class="literal">Animal</code> class, we can put <code class="literal">Brain</code> inside the <code class="literal">performBehavior()</code> method if we decide that the
class is useful only inside that method:</p><a id="I_6_tt342"/><pre class="programlisting"> <code class="n">Class</code> <code class="n">Animal</code> <code class="o">{</code>
<code class="kt">void</code> <code class="nf">performBehavior</code><code class="o">()</code> <code class="o">{</code>
<code class="n">Class</code> <code class="n">Brain</code> <code class="o">{</code>
<code class="o">...</code>
<code class="o">}</code>
<code class="o">}</code>
<code class="o">}</code></pre><p>In this situation, the rules governing what <code class="literal">Brain</code> can see are the same as in our earlier
example. The body of <code class="literal">Brain</code> can see
anything in the scope of <code class="literal">performBehavior()</code> and above it (in the body of
<code class="literal">Animal</code>). This includes local
variables of <code class="literal">performBehavior()</code> and
its arguments. But because of the fleeting nature of a method
invocation, there are a few limitations and additional restrictions, as
described in the following sections. If you are thinking that inner
classes within methods sounds arcane, bear with us until we talk about
anonymous inner classes, which are tremendously useful.</p><div class="sect3" title="Limitations on inner classes in methods"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-6-SECT-6.2.1"/>Limitations on inner classes in methods</h3></div></div></div><p><a id="idx10280" class="indexterm"/> <a id="idx10289" class="indexterm"/> <code class="literal">performBehavior()</code> is
a method, and method invocations have limited lifetimes. When they
exit, their local variables normally disappear into the abyss.
However, an instance of <code class="literal">Brain</code> (like
any object created in the method) lives on as long as it is
referenced. Java must make sure that any local variables used by
instances of <code class="literal">Brain</code> created within
an invocation of <code class="literal">performBehavior()</code>
also live on. Furthermore, all the instances of <code class="literal">Brain</code> that we make within a single
invocation of <code class="literal">performBehavior()</code>
must see the same local variables. To accomplish this, the compiler
must be allowed to make copies of local variables. Thus, their values
cannot change once an inner class has seen them. This means that any
of the method’s local variables or arguments that are referenced by
the inner class must be declared <a id="I_indexterm6_id700783" class="indexterm"/><code class="literal">final</code>. The <code class="literal">final</code> modifier means that they are constant
once assigned. This is a little confusing and easy to forget, but the
compiler will graciously remind you. For example:</p><a id="I_6_tt343"/><pre class="programlisting"> <code class="kt">void</code> <code class="nf">performBehavior</code><code class="o">(</code> <code class="kd">final</code> <code class="kt">boolean</code> <code class="n">nocturnal</code> <code class="o">)</code>
<code class="o">{</code>
<code class="kd">class</code> <code class="nc">Brain</code> <code class="o">{</code>
<code class="kt">void</code> <code class="nf">sleep</code><code class="o">()</code> <code class="o">{</code>
<code class="k">if</code> <code class="o">(</code> <code class="n">nocturnal</code> <code class="o">)</code> <code class="o">{</code> <code class="o">...</code> <code class="o">}</code>
<code class="o">}</code>
<code class="o">}</code>
<code class="o">}</code></pre><p>In this code snippet, the argument <code class="literal">nocturnal</code> to the <code class="literal">performBehavior()</code> method must be marked
<code class="literal">final</code> so that it can be referenced
within the inner class <code class="literal">Brain</code>. This
is just a technical limitation of how inner classes are implemented,
ensuring that it’s OK for the <code class="literal">Brain</code>
class to keep a copy of the value.<a id="I_indexterm6_id700847" class="indexterm"/><a id="I_indexterm6_id700854" class="indexterm"/></p></div><div class="sect3" title="Static inner classes"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-6-SECT-6.2.2"/>Static inner classes</h3></div></div></div><p><a id="idx10282" class="indexterm"/> <a id="idx10292" class="indexterm"/> <a id="I_indexterm6_id700898" class="indexterm"/>We mentioned earlier that the inner class <code class="literal">Brain</code> of the class <code class="literal">Animal</code> can, in some ways, be considered an
<code class="literal">Animal.Brain</code> class—that is, it is
possible to work with a <code class="literal">Brain</code> from
outside the <code class="literal">Animal</code> class, using
just such a qualified name: <code class="literal">Animal.Brain</code>. But as we described, given
that our <code class="literal">Animal.Brain</code> class always
requires an instance of an <code class="literal">Animal</code>
as its enclosing instance, it’s not as common to work with them
directly in this way.</p><p>However, there is another situation in which we want to use
inner classes by name. An inner class that lives within the body of a
top-level class (not within a method or another inner class) can be
declared <a id="I_indexterm6_id700957" class="indexterm"/><code class="literal">static</code>. For
example:</p><a id="I_6_tt344"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">Animal</code> <code class="o">{</code>
<code class="kd">static</code> <code class="kd">class</code> <code class="nc">MigrationPattern</code> <code class="o">{</code>
<code class="o">...</code>
<code class="o">}</code>
<code class="o">...</code>
<code class="o">}</code></pre><p>A static inner class such as this acts just like a new top-level
class called <code class="literal">Animal.MigrationPattern</code>. We can use it just
like any other class, without regard to any enclosing instances.
Although this may seem strange, it is not inconsistent because a
static member never has an object instance associated with it. The
requirement that the inner class be defined directly inside a
top-level class ensures that an enclosing instance won’t be needed. If
we have permission, we can create an instance of the class using the
qualified name:</p><a id="I_6_tt345"/><pre class="programlisting"> <code class="n">Animal</code><code class="o">.</code><code class="na">MigrationPattern</code> <code class="n">stlToSanFrancisco</code> <code class="o">=</code>
<code class="k">new</code> <code class="n">Animal</code><code class="o">.</code><code class="na">MigrationPattern</code><code class="o">();</code></pre><p>As you see, the effect is that <code class="literal">Animal</code> acts something like a minipackage,
holding the <code class="literal">MigrationPattern</code> class.
Here, we have used the fully qualified name, but we could also import
it like any other class:</p><a id="I_6_tt346"/><pre class="programlisting"> <code class="kn">import</code> <code class="nn">Animal.MigrationPattern</code><code class="o">;</code></pre><p>This statement enables us to refer to the class simply as
<code class="literal">MigrationPattern</code>. We can use all
the standard visibility modifiers on inner classes, so a static inner
class can have <a id="I_indexterm6_id701039" class="indexterm"/><code class="literal">private</code>, <a id="I_indexterm6_id701054" class="indexterm"/><code class="literal">protected</code>, <code class="literal">default</code>, or <a id="I_indexterm6_id701074" class="indexterm"/><code class="literal">public</code>
visibility.</p><p>Here’s another example. The Java 2D API uses static inner
classes to implement specialized shape classes (i.e., the <code class="literal">java.awt.geom.Rectangle2D</code> class has two
inner classes, <code class="literal">Float</code> and <code class="literal">Double</code>, that implement two different
precisions). These shape classes are actually very simple subclasses;
it would have been sad to have to multiply the number of top-level
classes in that package by three to accommodate all of them. With
inner classes, we can bundle them with their respective
classes:<a id="I_indexterm6_id701113" class="indexterm"/><a id="I_indexterm6_id701120" class="indexterm"/></p><a id="I_6_tt347"/><pre class="programlisting"> <code class="n">Rectangle2D</code><code class="o">.</code><code class="na">Float</code> <code class="n">rect</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Rectangle2D</code><code class="o">.</code><code class="na">Float</code><code class="o">();</code></pre></div><div class="sect3" title="Anonymous inner classes"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-6-SECT-6.2.3"/>Anonymous inner classes</h3></div></div></div><p><a id="idx10266" class="indexterm"/> <a id="idx10279" class="indexterm"/> <a id="idx10288" class="indexterm"/>Now we get to the best part. As a general rule, the more
deeply encapsulated and limited in scope our classes are, the more
freedom we have in naming them. We saw this in our earlier iterator
example. This is not just a purely aesthetic issue. Naming is an
important part of writing readable, maintainable code. We generally
want to use the most concise, meaningful names possible. A corollary
to this is that we prefer to avoid doling out names for purely
ephemeral objects that are going to be used only once.</p><p>Anonymous inner classes are an extension of the syntax of the
<a id="I_indexterm6_id701191" class="indexterm"/><code class="literal">new</code> operation. When
you create an anonymous inner class, you combine a class declaration
with the allocation of an instance of that class, effectively creating
a “one-time only” class and a class instance in one operation. After
the <code class="literal">new</code> keyword, you specify either
the name of a class or an interface, followed by a class body. The
class body becomes an inner class, which either extends the specified
class or, in the case of an interface, is expected to implement the
interface. A single instance of the class is created and returned as
the value.</p><p>For example, we could do away with the declaration of the
<code class="literal">Iterator</code> class in the <code class="literal">EmployeeList</code> example by using an anonymous
inner class in the <code class="literal">getIterator()</code>
method:</p><a id="I_6_tt348"/><pre class="programlisting"> <code class="n">Iterator</code> <code class="nf">getIterator</code><code class="o">()</code>
<code class="o">{</code>
<code class="k">return</code> <code class="k">new</code> <code class="nf">Iterator</code><code class="o">()</code> <code class="o">{</code>
<code class="kt">int</code> <code class="n">element</code> <code class="o">=</code> <code class="mi">0</code><code class="o">;</code>
<code class="kt">boolean</code> <code class="nf">hasNext</code><code class="o">()</code> <code class="o">{</code>
<code class="k">return</code> <code class="n">element</code> <code class="o"><</code> <code class="n">employees</code><code class="o">.</code><code class="na">length</code> <code class="o">;</code>
<code class="o">}</code>
<code class="n">Object</code> <code class="nf">next</code><code class="o">()</code> <code class="o">{</code>
<code class="k">if</code> <code class="o">(</code> <code class="n">hasNext</code><code class="o">()</code> <code class="o">)</code>
<code class="k">return</code> <code class="n">employees</code><code class="o">[</code> <code class="n">element</code><code class="o">++</code> <code class="o">];</code>
<code class="k">else</code>
<code class="k">throw</code> <code class="k">new</code> <code class="nf">NoSuchElementException</code><code class="o">();</code>
<code class="o">}</code>
<code class="kt">void</code> <code class="nf">remove</code><code class="o">()</code> <code class="o">{</code>
<code class="k">throw</code> <code class="k">new</code> <code class="nf">UnsupportedOperationException</code><code class="o">();</code>
<code class="o">}</code>
<code class="o">};</code>
<code class="o">}</code></pre><p>Here, we have simply moved the guts of <code class="literal">Iterator</code> into the body of an anonymous inner
class. The call to <code class="literal">new</code> implicitly
creates a class that implements the <code class="literal">Iterator</code> interface and returns an instance
of the class as its result. Note the extent of the curly braces and
the semicolon at the end. The <code class="literal">getIterator()</code> method contains a single
statement, the <code class="literal">return</code>
statement.</p><p>The previous example is a bit extreme and certainly does not
improve readability. Inner classes are best used when you want to
implement a few lines of code, but the verbiage and conspicuousness of
declaring a separate class detracts from the task at hand. Here’s a
better example. Suppose that we want to start a new thread to execute
the <code class="literal">performBehavior()</code> method of our
<code class="literal">Animal</code>:</p><a id="I_6_tt349"/><pre class="programlisting"> <code class="k">new</code> <code class="nf">Thread</code><code class="o">()</code> <code class="o">{</code>
<code class="kd">public</code> <code class="kt">void</code> <code class="nf">run</code><code class="o">()</code> <code class="o">{</code> <code class="n">performBehavior</code><code class="o">();</code> <code class="o">}</code>
<code class="o">}.</code><code class="na">start</code><code class="o">();</code></pre><p>Here, we have gone over to the terse side. We’ve allocated and
started a new <code class="literal">Thread</code>, using an
anonymous inner class that extends the <code class="literal">Thread</code> class and invokes our <code class="literal">performBehavior()</code> method in its <code class="literal">run()</code> method. The effect is similar to using
a method pointer in some other language. However, the inner class
allows the compiler to check type consistency, which would be more
difficult (or impossible) with a true method pointer. At the same
time, our anonymous adapter class with its three lines of code is much
more efficient and readable than creating a new, top-level adapter
class named <code class="literal">AnimalBehaviorThreadAdapter</code>.</p><p>While we’re getting a bit ahead of the story, anonymous adapter
classes are a perfect fit for event handling (which we cover fully in
<a class="xref" href="ch16.html" title="Chapter 16. Swing">Chapter 16</a>). Skipping a lot of explanation,
let’s say you want the method <code class="literal">handleClicks()</code> to be called whenever the
user clicks the mouse. You would write code such as:</p><a id="I_6_tt350"/><pre class="programlisting"> <code class="n">addMouseListener</code><code class="o">(</code> <code class="k">new</code> <code class="n">MouseInputAdapter</code><code class="o">()</code> <code class="o">{</code>
<code class="kd">public</code> <code class="kt">void</code> <code class="nf">mouseClicked</code><code class="o">(</code><code class="n">MouseEvent</code> <code class="n">e</code><code class="o">)</code> <code class="o">{</code> <code class="n">handleClicks</code><code class="o">(</code><code class="n">e</code><code class="o">);</code> <code class="o">}</code>
<code class="o">}</code> <code class="o">);</code></pre><p>In this case, the anonymous class extends the <a id="I_indexterm6_id701382" class="indexterm"/><code class="literal">MouseInputAdapter</code>
class by overriding its <a id="I_indexterm6_id701393" class="indexterm"/><code class="literal">mouseClicked()</code> method
to call our method. A lot is going on in a very small space, but the
result is clean, readable code. You assign method names that are
meaningful to you while allowing Java to do its job of type
checking.<a id="I_indexterm6_id701406" class="indexterm"/><a id="I_indexterm6_id701413" class="indexterm"/><a id="I_indexterm6_id701420" class="indexterm"/></p></div><div class="sect3" title="Scoping of the “this” reference"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-6-SECT-6.2.4"/>Scoping of the “this” reference</h3></div></div></div><p><a id="idx10281" class="indexterm"/> <a id="idx10290" class="indexterm"/> <a id="idx10340" class="indexterm"/>Sometimes an inner class may want to get a handle on its
“parent” enclosing instance. It might want to pass a reference to its
parent or to refer to one of the parent’s variables or methods that
has been hidden by one of its own. For example:</p><a id="I_6_tt351"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">Animal</code> <code class="o">{</code>
<code class="kt">int</code> <code class="n">size</code><code class="o">;</code>
<code class="kd">class</code> <code class="nc">Brain</code> <code class="o">{</code>
<code class="kt">int</code> <code class="n">size</code><code class="o">;</code>
<code class="o">}</code>
<code class="o">}</code></pre><p>Here, as far as <code class="literal">Brain</code> is
concerned, the variable <code class="literal">size</code> in
<code class="literal">Animal</code> is shadowed by its own
version.</p><p>Normally, an object refers to itself using the special <code class="literal">this</code> reference (implicitly or explicitly).
But what is the meaning of <code class="literal">this</code> for
an object with one or more enclosing instances? The answer is that an
inner class has multiple <code class="literal">this</code>
references. You can specify which <code class="literal">this</code> you want by prefixing it with the name
of the class. For instance (no pun intended), we can get a reference
to our <code class="literal">Animal</code> from within <code class="literal">Brain</code>, like so:</p><a id="I_6_tt352"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">Brain</code> <code class="o">{</code>
<code class="n">Animal</code> <code class="n">ourAnimal</code> <code class="o">=</code> <code class="n">Animal</code><code class="o">.</code><code class="na">this</code><code class="o">;</code>
<code class="o">...</code>
<code class="o">}</code></pre><p>Similarly, we could refer to the <code class="literal">size</code> variable in <code class="literal">Animal</code>:<a id="I_indexterm6_id701569" class="indexterm"/><a id="I_indexterm6_id701576" class="indexterm"/><a id="I_indexterm6_id701583" class="indexterm"/></p><a id="I_6_tt353"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">Brain</code> <code class="o">{</code>
<code class="kt">int</code> <code class="n">animalSize</code> <code class="o">=</code> <code class="n">Animal</code><code class="o">.</code><code class="na">this</code><code class="o">.</code><code class="na">size</code><code class="o">;</code>
<code class="o">...</code>
<code class="o">}</code></pre></div><div class="sect3" title="How do inner classes really work?"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-6-SECT-6.2.5"/>How do inner classes really work?</h3></div></div></div><p><a id="idx10283" class="indexterm"/> <a id="idx10293" class="indexterm"/>Finally, let’s get our hands dirty and take a look at
what’s really going on when we use an inner class. We’ve said that the
compiler is doing all the things that we had hoped to forget about.
Let’s see what’s actually happening. Try compiling this trivial
example:</p><a id="I_6_tt354"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">Animal</code> <code class="o">{</code>
<code class="kd">class</code> <code class="nc">Brain</code> <code class="o">{</code>
<code class="o">}</code>
<code class="o">}</code></pre><p>What you’ll find is that the compiler generates two
<span class="emphasis"><em>.class</em></span> files: <span class="emphasis"><em>Animal.class</em></span>
and <span class="emphasis"><em>Animal$Brain.class</em></span>.</p><p><a id="I_indexterm6_id701664" class="indexterm"/> <a id="I_indexterm6_id701671" class="indexterm"/>The second file is the class file for our inner class.
Yes, as we feared, inner classes are really just compiler magic. The
compiler has created the inner class for us as a normal, top-level
class and named it by combining the class names with a dollar sign.
The dollar sign is a valid character in class names, but is intended
for use only by automated tools. (Please don’t start naming your
classes with dollar signs.) Had our class been more deeply nested, the
intervening inner class names would have been attached in the same way
to generate a unique top-level name.</p><p>Now take a look at the class with the JDK’s <code class="literal">javap</code> utility. Starting in Java 5.0, you can
refer to the inner class as <code class="literal">Animal.Brain</code>, but in earlier versions of
Java, you may have to call the class by its real name, <code class="literal">Animal$Brain</code>:</p><a id="I_6_tt355"/><pre class="programlisting"> <code class="o">%</code> <strong class="userinput"><code><code class="n">javap</code> <code class="err">'</code><code class="n">Animal$Brain</code><code class="err">'</code></code></strong>
<code class="kd">class</code> <code class="nc">Animal</code><code class="n">$Brain</code> <code class="kd">extends</code> <code class="n">java</code><code class="o">.</code><code class="na">lang</code><code class="o">.</code><code class="na">Object</code> <code class="o">{</code>
<code class="n">Animal$Brain</code><code class="o">(</code><code class="n">Animal</code><code class="o">);</code>
<code class="o">}</code></pre><p>On a Windows system, it’s not necessary to quote the argument,
as we did on this Unix command line.</p><p>You’ll see that the compiler has given our inner class a
constructor that takes a reference to an <code class="literal">Animal</code> as an argument. This is how the real
inner class gets the reference to its enclosing instance.</p><p>The worst thing about these additional class files is that you
need to know they are there. Utilities such as <em class="filename">jar</em> don’t automatically find them; when
you’re invoking such a utility, you need to specify these files
explicitly or use a wildcard to find them:<a id="I_indexterm6_id701748" class="indexterm"/></p><a id="I_6_tt356"/><pre class="programlisting"> <code class="o">%</code> <strong class="userinput"><code><code class="n">jar</code> <code class="n">cvf</code> <code class="n">animal</code><code class="o">.</code><code class="na">jar</code> <code class="n">Animal</code><code class="o">*</code><code class="kd">class</code></code></strong></pre></div><div class="sect3" title="Security implications"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-6-SECT-6.2.6"/>Security implications</h3></div></div></div><p><a id="I_indexterm6_id701775" class="indexterm"/> <a id="idx10291" class="indexterm"/>Given what we just saw—that the inner class really does
exist as an automatically generated top-level class—how does it get
access to private variables? The answer, unfortunately, is that the
compiler is forced to break the encapsulation of your object and
insert accessor methods so that the inner class can reach them. The
accessor methods are given package-level access, so your object is
still safe within its package walls, but it is conceivable that this
difference could be meaningful if people were allowed to create new
classes within your package.</p><p>The visibility modifiers on inner classes also have some
problems. Current implementations of the VM do not implement the
notion of a <code class="literal">private</code> or <code class="literal">protected</code> class within a package, so giving
your inner class anything other than <code class="literal">public</code> or default visibility is only a
compile-time guarantee. It is difficult to conceive of how these
security issues could be abused, but it is interesting to note that
Java is straining a bit to stay within its original design.<sup>[<a id="learnjava3-CHP-6-FNOTE-5" href="#ftn.learnjava3-CHP-6-FNOTE-5" class="footnote">19</a>]</sup><a id="I_indexterm6_id701834" class="indexterm"/><a id="I_indexterm6_id701841" class="indexterm"/></p></div></div><div class="footnotes"><br/><hr/><div class="footnote"><p><sup>[<a id="ftn.learnjava3-CHP-6-FNOTE-5" href="#learnjava3-CHP-6-FNOTE-5" class="para">19</a>] </sup>Inner classes were added to Java in version 1.1.</p></div></div></div></body></html>