epubjs
Version:
Render ePub documents in the browser, across many devices
371 lines (358 loc) • 60 kB
HTML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Methods</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="Methods"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-5-SECT-2"/>Methods</h1></div></div></div><p>Methods appear inside class bodies. They contain local variable
declarations and other Java statements that are executed when the method
is invoked. Methods may return a value to the caller. They always specify
a return type, which can be a primitive type, a reference type, or the
type <a id="I_indexterm5_id689583" class="indexterm"/><code class="literal">void</code> , which indicates no
returned value. Methods may take arguments, which are values supplied by
the caller of the method.</p><p>Here’s a simple example:</p><a id="I_5_tt241"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">Bird</code> <code class="o">{</code>
<code class="kt">int</code> <code class="n">xPos</code><code class="o">,</code> <code class="n">yPos</code><code class="o">;</code>
<code class="kt">double</code> <code class="nf">fly</code> <code class="o">(</code> <code class="kt">int</code> <code class="n">x</code><code class="o">,</code> <code class="kt">int</code> <code class="n">y</code> <code class="o">)</code> <code class="o">{</code>
<code class="kt">double</code> <code class="n">distance</code> <code class="o">=</code> <code class="n">Math</code><code class="o">.</code><code class="na">sqrt</code><code class="o">(</code> <code class="n">x</code><code class="o">*</code><code class="n">x</code> <code class="o">+</code> <code class="n">y</code><code class="o">*</code><code class="n">y</code> <code class="o">);</code>
<code class="n">flap</code><code class="o">(</code> <code class="n">distance</code> <code class="o">);</code>
<code class="n">xPos</code> <code class="o">=</code> <code class="n">x</code><code class="o">;</code>
<code class="n">yPos</code> <code class="o">=</code> <code class="n">y</code><code class="o">;</code>
<code class="k">return</code> <code class="n">distance</code><code class="o">;</code>
<code class="o">}</code>
<code class="o">...</code>
<code class="o">}</code></pre><p>In this example, the class <code class="literal">Bird</code>
defines a method, <code class="literal">fly()</code>, that takes as
arguments two integers: <code class="literal">x</code> and <code class="literal">y</code>. It returns a <code class="literal">double</code> type value as a result, using the
<a id="I_indexterm5_id689637" class="indexterm"/><code class="literal">return</code> keyword.</p><p>Our method has a fixed number of arguments (two); however, methods
can have <span class="emphasis"><em>variable-length argument lists</em></span>, which allow
the method to specify that it can take any number of arguments and sort
them itself at runtime. We provide more details later in this
chapter.</p><div class="sect2" title="Local Variables"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-5-SECT-2.1"/>Local Variables</h2></div></div></div><p><a id="I_indexterm5_id689663" class="indexterm"/> <a id="I_indexterm5_id689669" class="indexterm"/> <a id="idx10248" class="indexterm"/>Our <code class="literal">fly()</code> method
declares a local variable called <code class="literal">distance</code>, which it uses to compute the
distance flown. A local variable is temporary; it exists only within the
scope (the block) of its method. Local variables are allocated when a
method is invoked; they are normally destroyed when the method returns.
They can’t be referenced from outside the method itself. If the method
is executing concurrently in different threads, each thread has its own
version of the method’s local variables. A method’s arguments also serve
as local variables within the scope of the method; the only difference
is that they are initialized by being passed in from the caller of the
method.</p><p>An object created within a method and assigned to a local variable
may or may not persist after the method has returned. As with all
objects in Java, it depends on whether any references to the object
remain. If an object is created, assigned to a local variable, and never
used anywhere else, that object is no longer referenced when the local
variable disappears from scope, so garbage collection removes the
object. If, however, we assign the object to an instance variable of an
object, pass it as an argument to another method, or pass it back as a
return value, it may be saved by another variable holding its reference.
We’ll discuss object creation and garbage collection in more detail
shortly.<a id="I_indexterm5_id689728" class="indexterm"/></p></div><div class="sect2" title="Shadowing"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-5-SECT-2.2"/>Shadowing</h2></div></div></div><p><a id="idx10233" class="indexterm"/> <a id="idx10250" class="indexterm"/> <a id="idx10258" class="indexterm"/>If a local variable and an instance variable have the same
name, the local variable <span class="emphasis"><em>shadows</em></span> or hides the name
of the instance variable within the scope of the method. In the
following example, the local variables <code class="literal">xPos</code> and <code class="literal">yPos</code> hide the instance variables of the same
name:</p><a id="I_5_tt242"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">Bird</code> <code class="o">{</code>
<code class="kt">int</code> <code class="n">xPos</code><code class="o">,</code> <code class="n">yPos</code><code class="o">;</code>
<code class="kt">int</code> <code class="n">xNest</code><code class="o">,</code> <code class="n">yNest</code><code class="o">;</code>
<code class="o">...</code>
<code class="kt">double</code> <code class="nf">flyToNest</code><code class="o">()</code> <code class="o">{</code>
<code class="kt">int</code> <code class="n">xPos</code> <code class="o">=</code> <code class="n">xNest</code><code class="o">;</code>
<code class="kt">int</code> <code class="n">yPos</code> <code class="o">=</code> <code class="nl">yNest:</code>
<code class="k">return</code> <code class="o">(</code> <code class="n">fly</code><code class="o">(</code> <code class="n">xPos</code><code class="o">,</code> <code class="n">yPos</code> <code class="o">)</code> <code class="o">);</code>
<code class="o">}</code>
<code class="o">...</code>
<code class="o">}</code></pre><p>When we set the values of the local variables in <code class="literal">flyToNest()</code>, it has no effect on the values of
the instance variables.</p><div class="sect3" title="The “this” reference"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-5-SECT-2.2.1"/>The “this” reference</h3></div></div></div><p>You can use the special reference <code class="literal">this</code> any time you need to refer explicitly
to the current object or a member of the current object. Often you
don’t need to use <code class="literal">this</code>, because the
reference to the current object is implicit; such is the case when
using unambiguously named instance variables inside a class. But we
can use <code class="literal">this</code> to refer explicitly to
instance variables in our object, even if they are shadowed. The
following example shows how we can use <code class="literal">this</code> to allow argument names that shadow
instance variable names. This is a fairly common technique because it
saves having to make up alternative names. Here’s how we could
implement our <code class="literal">fly()</code> method with
shadowed variables:</p><a id="I_5_tt243"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">Bird</code> <code class="o">{</code>
<code class="kt">int</code> <code class="n">xPos</code><code class="o">,</code> <code class="n">yPos</code><code class="o">;</code>
<code class="kt">double</code> <code class="nf">fly</code> <code class="o">(</code> <code class="kt">int</code> <code class="n">xPos</code><code class="o">,</code> <code class="kt">int</code> <code class="n">yPos</code> <code class="o">)</code> <code class="o">{</code>
<code class="kt">double</code> <code class="n">distance</code> <code class="o">=</code> <code class="n">Math</code><code class="o">.</code><code class="na">sqrt</code><code class="o">(</code> <code class="n">xPos</code><code class="o">*</code><code class="n">xPos</code> <code class="o">+</code> <code class="n">yPos</code><code class="o">*</code><code class="n">yPos</code> <code class="o">);</code>
<code class="n">flap</code><code class="o">(</code> <code class="n">distance</code> <code class="o">);</code>
<code class="k">this</code><code class="o">.</code><code class="na">xPos</code> <code class="o">=</code> <code class="n">xPos</code><code class="o">;</code> <code class="c1">// instance var = local vra</code>
<code class="k">this</code><code class="o">.</code><code class="na">yPos</code> <code class="o">=</code> <code class="n">yPos</code><code class="o">;</code>
<code class="k">return</code> <code class="n">distance</code><code class="o">;</code>
<code class="o">}</code>
<code class="o">...</code>
<code class="o">}</code></pre><p>In this example, the expression <code class="literal">this.xPos</code> refers to the instance variable
<code class="literal">xPos</code> and assigns it the value of
the local variable <code class="literal">xPos</code>, which
would otherwise hide its name. The only reason we need to use <code class="literal">this</code> in the previous example is because
we’ve used argument names that hide our instance variables, and we
want to refer to the instance variables. You can also use the <code class="literal">this</code> reference any time you want to pass a
reference to “the current” enclosing object to some other method;
we’ll show examples of that later.<a id="I_indexterm5_id689906" class="indexterm"/><a id="I_indexterm5_id689913" class="indexterm"/><a id="I_indexterm5_id689920" class="indexterm"/></p></div></div><div class="sect2" title="Static Methods"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-5-SECT-2.3"/>Static Methods</h2></div></div></div><p><a id="idx10234" class="indexterm"/> <a id="idx10251" class="indexterm"/> <a id="idx10261" class="indexterm"/>Static methods (class methods), like static variables,
belong to the class and not to individual instances of the class. What
does this mean? Well, foremost, a static method lives outside of any
particular class instance. It can be invoked by name, through the class
name, without any objects around. Because it is not bound to a
particular object instance, a static method can directly access only
other static members (static variables and other static methods) of the
class. It can’t directly see any instance variables or call any instance
methods, because to do so we’d have to ask, “on which instance?” Static
methods can be called from instances, syntactically just like instance
methods, but the important thing is that they can also be used
independently.</p><p>Our <code class="literal">fly()</code> method uses a static
method: <a id="I_indexterm5_id689992" class="indexterm"/><code class="literal">Math.sqrt()</code>, which is
defined by the <code class="literal">java.lang.Math</code> class;
we’ll explore this class in detail in <a class="xref" href="ch11.html" title="Chapter 11. Core Utilities">Chapter 11</a>. For now, the important thing to note is
that <a id="I_indexterm5_id690014" class="indexterm"/><code class="literal">Math</code> is the name of a
class and not an instance of a <code class="literal">Math</code>
object. (It so happens that you can’t even make an instance of the
<code class="literal">Math</code> class.) Because static methods
can be invoked wherever the class name is available, class methods are
closer to C-style functions. Static methods are particularly useful for
utility methods that perform work that is useful either independently of
instances or in working on instances. For example, in our <code class="literal">Bird</code> class, we could enumerate all of the
available types of birds that can be created:</p><a id="I_5_tt244"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">Bird</code> <code class="o">{</code>
<code class="o">...</code>
<code class="kd">static</code> <code class="n">String</code> <code class="o">[]</code> <code class="n">getBirdTypes</code><code class="o">()</code> <code class="o">{</code> <code class="o">...</code> <code class="o">}</code>
<code class="o">}</code></pre><p>Here, we’ve defined a static method, <code class="literal">getBirdTypes()</code>, that returns an array of
strings containing bird names. We can use <code class="literal">getBirdTypes()</code> from within an instance of
<code class="literal">Bird</code>, just like an instance method.
However, we can also call it from other classes, using the <code class="literal">Bird</code> class name:</p><a id="I_5_tt245"/><pre class="programlisting"> <code class="n">String</code> <code class="o">[]</code> <code class="n">names</code> <code class="o">=</code> <code class="n">Bird</code><code class="o">.</code><code class="na">getBirdTypes</code><code class="o">();</code></pre><p>Perhaps a special version of the <code class="literal">Bird</code> class constructor accepts the name of a
bird type. We could use this list to decide what kind of bird to
create.</p><p>Static methods also play an important role in various design
patterns, where you limit the use of the <code class="literal">new</code> operator for a class to one method—a
static method called a <span class="emphasis"><em>factory method</em></span>. We’ll talk
more about object construction later, but suffice it to say that it’s
common to see usage like this:<a id="I_indexterm5_id690114" class="indexterm"/><a id="I_indexterm5_id690121" class="indexterm"/><a id="I_indexterm5_id690128" class="indexterm"/></p><a id="I_5_tt246"/><pre class="programlisting"> <code class="n">Bird</code> <code class="n">bird</code> <code class="o">=</code> <code class="n">Bird</code><code class="o">.</code><code class="na">createBird</code><code class="o">(</code> <code class="s">"pigeon"</code> <code class="o">);</code></pre></div><div class="sect2" title="Initializing Local Variables"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-5-SECT-2.4"/>Initializing Local Variables</h2></div></div></div><p><a id="idx10231" class="indexterm"/> <a id="idx10247" class="indexterm"/>In the <code class="literal">flyToNest()</code>
example, we made a point of initializing the local variables <code class="literal">xPos</code> and <code class="literal">yPos</code>. Unlike instance variables, local
variables must be initialized before they can be used. It’s a
compile-time error to try to access a local variable without first
assigning it a value:</p><a id="I_5_tt247"/><pre class="programlisting"> <code class="kt">void</code> <code class="nf">myMethod</code><code class="o">()</code> <code class="o">{</code>
<code class="kt">int</code> <code class="n">foo</code> <code class="o">=</code> <code class="mi">42</code><code class="o">;</code>
<code class="kt">int</code> <code class="n">bar</code><code class="o">;</code>
<code class="n">bar</code> <code class="o">+=</code> <code class="mi">1</code><code class="o">;</code> <code class="c1">// compile-time error, bar uninitialized</code>
<code class="n">bar</code> <code class="o">=</code> <code class="mi">99</code><code class="o">;</code>
<code class="n">bar</code> <code class="o">+=</code> <code class="mi">1</code><code class="o">;</code> <code class="c1">// would be OK here</code>
<code class="o">}</code></pre><p>Notice that this doesn’t imply local variables have to be
initialized when declared, just that the first time they are referenced
must be in an assignment. More subtle possibilities arise when making
assignments inside conditionals:</p><a id="I_5_tt248"/><pre class="programlisting"> <code class="kt">void</code> <code class="n">myMethod</code> <code class="o">{</code>
<code class="kt">int</code> <code class="n">foo</code><code class="o">;</code>
<code class="k">if</code> <code class="o">(</code> <code class="n">someCondition</code> <code class="o">)</code> <code class="o">{</code>
<code class="n">foo</code> <code class="o">=</code> <code class="mi">42</code><code class="o">;</code>
<code class="o">...</code>
<code class="o">}</code>
<code class="n">foo</code> <code class="o">+=</code> <code class="mi">1</code><code class="o">;</code> <code class="c1">// Compile-time error, foo may not be initialized</code>
<code class="o">}</code></pre><p>In this example, <code class="literal">foo</code> is
initialized only if <code class="literal">someCondition</code> is
<code class="literal">true</code>. The compiler doesn’t let you
make this wager, so it flags the use of <code class="literal">foo</code> as an error. We could correct this
situation in several ways. We could initialize the variable to a default
value in advance or move the usage inside the conditional. We could also
make sure the path of execution doesn’t reach the uninitialized variable
through some other means, depending on what makes sense for our
particular application. For example, we could simply make sure that we
assign <code class="literal">foo</code> a value in both the
<code class="literal">if</code> and <code class="literal">else</code> branch. Or we could return from the
method abruptly:</p><a id="I_5_tt249"/><pre class="programlisting"> <code class="kt">int</code> <code class="n">foo</code><code class="o">;</code>
<code class="o">...</code>
<code class="k">if</code> <code class="o">(</code> <code class="n">someCondition</code> <code class="o">)</code> <code class="o">{</code>
<code class="n">foo</code> <code class="o">=</code> <code class="mi">42</code><code class="o">;</code>
<code class="o">...</code>
<code class="o">}</code> <code class="k">else</code>
<code class="k">return</code><code class="o">;</code>
<code class="n">foo</code> <code class="o">+=</code> <code class="mi">1</code><code class="o">;</code></pre><p>In this case, there’s no chance of reaching <code class="literal">foo</code> in an uninitialized state, so the compiler
allows the use of <code class="literal">foo</code> after the
conditional.</p><p>Why is Java so picky about local variables? One of the most common
(and insidious) sources of errors in C or C++ is forgetting to
initialize local variables, so Java tries to help out. If it didn’t,
Java would suffer the same potential irregularities as C or C++.<sup>[<a id="learnjava3-CHP-5-FNOTE-2" href="#ftn.learnjava3-CHP-5-FNOTE-2" class="footnote">13</a>]</sup><a id="I_indexterm5_id690327" class="indexterm"/><a id="I_indexterm5_id690334" class="indexterm"/></p></div><div class="sect2" title="Argument Passing and References"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-5-SECT-2.5"/>Argument Passing and References</h2></div></div></div><p><a id="idx10219" class="indexterm"/> <a id="idx10229" class="indexterm"/> <a id="idx10245" class="indexterm"/>In the beginning of <a class="xref" href="ch04.html" title="Chapter 4. The Java Language">Chapter 4</a>,
we described the distinction between primitive types, which are passed
by value (by copying), and objects, which are passed by reference. Now
that we’ve got a better handle on methods in Java, let’s walk through an
example:</p><a id="I_5_tt250"/><pre class="programlisting"> <code class="kt">void</code> <code class="nf">myMethod</code><code class="o">(</code> <code class="kt">int</code> <code class="n">j</code><code class="o">,</code> <code class="n">SomeKindOfObject</code> <code class="n">o</code> <code class="o">)</code> <code class="o">{</code>
<code class="o">...</code>
<code class="o">}</code>
<code class="c1">// use the method</code>
<code class="kt">int</code> <code class="n">i</code> <code class="o">=</code> <code class="mi">0</code><code class="o">;</code>
<code class="n">SomeKindOfObject</code> <code class="n">obj</code> <code class="o">=</code> <code class="k">new</code> <code class="n">SomeKindOfObject</code><code class="o">();</code>
<code class="n">myMethod</code><code class="o">(</code> <code class="n">i</code><code class="o">,</code> <code class="n">obj</code> <code class="o">);</code></pre><p>The chunk of code calls <code class="literal">myMethod()</code>, passing it two arguments. The
first argument, <code class="literal">i</code>, is passed by
value; when the method is called, the value of <code class="literal">i</code> is copied into the method’s parameter (a
local variable to it) named <code class="literal">j</code>. If
<code class="literal">myMethod()</code> changes the value of
<code class="literal">j</code>, it’s changing only its copy of the
local variable.</p><p>In the same way, a copy of the reference to <code class="literal">obj</code> is placed into the reference variable
<code class="literal">o</code> of <code class="literal">myMethod()</code>. Both references refer to the same
object, so any changes made through either reference affect the actual
(single) object instance. If we change the value of, say, <code class="literal">o.size</code>, the change is visible both as <code class="literal">o.size</code> (inside <code class="literal">myMethod()</code>) or as <code class="literal">obj.size</code> (in the calling method). However, if
<code class="literal">myMethod()</code> changes the reference
<code class="literal">o</code> itself—to point to another
object—it’s affecting only its local variable reference. It doesn’t
affect the caller’s variable <code class="literal">obj</code>,
which still refers to the original object. In this sense, passing the
reference is like passing a pointer in C and unlike passing by reference
in C++.</p><p>What if <code class="literal">myMethod()</code> needs to
modify the calling method’s notion of the <code class="literal">obj</code> reference as well (i.e., make <code class="literal">obj</code> point to a different object)? The easy way
to do that is to wrap <code class="literal">obj</code> inside some
kind of object. For example, we could wrap the object up as the lone
element in an array:</p><a id="I_5_tt251"/><pre class="programlisting"> <code class="n">SomeKindOfObject</code> <code class="o">[]</code> <code class="n">wrapper</code> <code class="o">=</code> <code class="k">new</code> <code class="n">SomeKindOfObject</code> <code class="o">[]</code> <code class="o">{</code> <code class="n">obj</code>
<code class="o">};</code></pre><p>All parties could then refer to the object as <code class="literal">wrapper[0]</code> and would have the ability to
change the reference. This is not aesthetically pleasing, but it does
illustrate that what is needed is the level of indirection.</p><p>Another possibility is to use <code class="literal">this</code> to pass a reference to the calling
object. In that case, the calling object serves as the wrapper for the
reference. Let’s look at a piece of code that could be from an
implementation of a linked list:</p><a id="I_5_tt252"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">Element</code> <code class="o">{</code>
<code class="kd">public</code> <code class="n">Element</code> <code class="n">nextElement</code><code class="o">;</code>
<code class="kt">void</code> <code class="nf">addToList</code><code class="o">(</code> <code class="n">List</code> <code class="n">list</code> <code class="o">)</code> <code class="o">{</code>
<code class="n">list</code><code class="o">.</code><code class="na">addToList</code><code class="o">(</code> <code class="k">this</code> <code class="o">);</code>
<code class="o">}</code>
<code class="o">}</code>
<code class="kd">class</code> <code class="nc">List</code> <code class="o">{</code>
<code class="kt">void</code> <code class="nf">addToList</code><code class="o">(</code> <code class="n">Element</code> <code class="n">element</code> <code class="o">)</code> <code class="o">{</code>
<code class="o">...</code>
<code class="n">element</code><code class="o">.</code><code class="na">nextElement</code> <code class="o">=</code> <code class="n">getNextElement</code><code class="o">();</code>
<code class="o">}</code>
<code class="o">}</code></pre><p>Every element in a linked list contains a pointer to the next
element in the list. In this code, the <code class="literal">Element</code> class represents one element; it
includes a method for adding itself to the list. The <code class="literal">List</code> class itself contains a method for adding
an arbitrary <code class="literal">Element</code> to the list. The
method <code class="literal">addToList()</code> calls <code class="literal">addToList()</code> with the argument <code class="literal">this</code> (which is, of course, an <code class="literal">Element</code>). <code class="literal">addToList()</code> can use the <code class="literal">this</code> reference to modify the <code class="literal">Element</code>’s <code class="literal">nextElement</code> instance variable. The same
technique can be used in conjunction with interfaces to implement
callbacks for arbitrary method invocations.<a id="I_indexterm5_id690638" class="indexterm"/><a id="I_indexterm5_id690645" class="indexterm"/><a id="I_indexterm5_id690652" class="indexterm"/></p></div><div class="sect2" title="Wrappers for Primitive Types"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-5-SECT-2.6"/>Wrappers for Primitive Types</h2></div></div></div><p><a id="idx10236" class="indexterm"/> <a id="idx10253" class="indexterm"/> <a id="idx10257" class="indexterm"/> <a id="idx10264" class="indexterm"/>As we described in <a class="xref" href="ch04.html" title="Chapter 4. The Java Language">Chapter 4</a>,
there is a schism in the Java world between class types (i.e., objects)
and primitive types (i.e., numbers, characters, and Boolean values).
Java accepts this tradeoff simply for efficiency reasons. When you’re
crunching numbers, you want your computations to be lightweight; having
to use objects for primitive types complicates performance
optimizations. For the times you want to treat values as objects, Java
supplies a standard wrapper class for each of the primitive types, as
shown in <a class="xref" href="ch05s02.html#learnjava3-CHP-5-TABLE-1" title="Table 5-1. Primitive type wrappers">Table 5-1</a>.</p><div class="table"><a id="learnjava3-CHP-5-TABLE-1"/><p class="title">Table 5-1. Primitive type wrappers</p><div class="table-contents"><table summary="Primitive type wrappers" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; "><colgroup><col/><col/></colgroup><thead><tr><th style="text-align: left"><p>Primitive</p></th><th style="text-align: left"><p>Wrapper</p></th></tr></thead><tbody><tr><td style="text-align: left"><p> <a id="I_indexterm5_id690780" class="indexterm"/> <code class="literal">void</code>
</p></td><td style="text-align: left"><p> <a id="I_indexterm5_id690797" class="indexterm"/> <code class="literal">java.lang.Void</code>
</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm5_id690814" class="indexterm"/> <code class="literal">boolean</code>
</p></td><td style="text-align: left"><p> <a id="I_indexterm5_id690831" class="indexterm"/> <code class="literal">java.lang.Boolean</code> </p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm5_id690849" class="indexterm"/> <code class="literal">char</code>
</p></td><td style="text-align: left"><p> <a id="I_indexterm5_id690868" class="indexterm"/> <code class="literal">java.lang.Character</code> </p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm5_id690886" class="indexterm"/> <code class="literal">byte</code>
</p></td><td style="text-align: left"><p> <a id="I_indexterm5_id690905" class="indexterm"/> <code class="literal">java.lang.Byte</code>
</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm5_id690923" class="indexterm"/> <code class="literal">short</code>
</p></td><td style="text-align: left"><p> <a id="I_indexterm5_id690941" class="indexterm"/> <code class="literal">java.lang.Short</code> </p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm5_id690959" class="indexterm"/> <code class="literal">int</code>
</p></td><td style="text-align: left"><p> <a id="I_indexterm5_id690978" class="indexterm"/> <code class="literal">java.lang.Integer</code> </p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm5_id690996" class="indexterm"/> <code class="literal">long</code>
</p></td><td style="text-align: left"><p> <a id="I_indexterm5_id691015" class="indexterm"/> <code class="literal">java.lang.Long</code>
</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm5_id691032" class="indexterm"/> <code class="literal">float</code>
</p></td><td style="text-align: left"><p> <a id="I_indexterm5_id691049" class="indexterm"/> <code class="literal">java.lang.Float</code> </p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm5_id691067" class="indexterm"/> <code class="literal">double</code>
</p></td><td style="text-align: left"><p> <a id="I_indexterm5_id691086" class="indexterm"/> <code class="literal">java.lang.Double</code> </p></td></tr></tbody></table></div></div><p>An instance of a wrapper class encapsulates a single value of its
corresponding type. It’s an immutable object that serves as a container
to hold the value and let us retrieve it later. You can construct a
wrapper object from a primitive value or from a <code class="literal">String</code> representation of the value. The
following statements are equivalent:</p><a id="I_5_tt253"/><pre class="programlisting"> <code class="n">Float</code> <code class="n">pi</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Float</code><code class="o">(</code> <code class="mf">3.14</code> <code class="o">);</code>
<code class="n">Float</code> <code class="n">pi</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Float</code><code class="o">(</code> <code class="s">"3.14"</code> <code class="o">);</code></pre><p>The wrapper constructors throw a <a id="I_indexterm5_id691122" class="indexterm"/><code class="literal">NumberFormatException</code>
when there is an error in parsing a string.</p><p>Each of the numeric type wrappers implements the <a id="I_indexterm5_id691136" class="indexterm"/><code class="literal">java.lang.Number</code>
interface, which provides “value” methods access to its value in all the
primitive forms. You can retrieve scalar values with the methods
<code class="literal">doubleValue()</code>, <code class="literal">floatValue()</code>, <code class="literal">longValue()</code>, <code class="literal">intValue()</code>, <code class="literal">shortValue()</code>, and <code class="literal">byteValue()</code>:</p><a id="I_5_tt254"/><pre class="programlisting"> <code class="n">Double</code> <code class="n">size</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Double</code> <code class="o">(</code> <code class="mf">32.76</code> <code class="o">);</code>
<code class="kt">double</code> <code class="n">d</code> <code class="o">=</code> <code class="n">size</code><code class="o">.</code><code class="na">doubleValue</code><code class="o">();</code> <code class="c1">// 32.76</code>
<code class="kt">float</code> <code class="n">f</code> <code class="o">=</code> <code class="n">size</code><code class="o">.</code><code class="na">floatValue</code><code class="o">();</code> <code class="c1">// 32.76</code>
<code class="kt">long</code> <code class="n">l</code> <code class="o">=</code> <code class="n">size</code><code class="o">.</code><code class="na">longValue</code><code class="o">();</code> <code class="c1">// 32</code>
<code class="kt">int</code> <code class="n">i</code> <code class="o">=</code> <code class="n">size</code><code class="o">.</code><code class="na">intValue</code><code class="o">();</code> <code class="c1">// 32</code></pre><p>This code is equivalent to casting the primitive <code class="literal">double</code> value to the various types.</p><p>The most common need for a wrapper is when you want to pass a
primitive value to a method that requires an object. For example, in
<a class="xref" href="ch11.html" title="Chapter 11. Core Utilities">Chapter 11</a>, we’ll look at the Java Collections
API, a sophisticated set of classes for dealing with object groups, such
as lists, sets, and maps. All the Collections APIs work on object types,
so primitives must be wrapped when stored in them. We’ll see in the next
section that Java makes this wrapping process automatic. For now,
however, let’s do it ourselves. As we’ll see, a <code class="literal">List</code> is an extensible collection of <code class="literal">Object</code>s. We can use wrappers to hold numbers
in a <code class="literal">List</code> (along with other
objects):</p><a id="I_5_tt255"/><pre class="programlisting"> <code class="c1">// Simple Java code</code>
<code class="n">List</code> <code class="n">myNumbers</code> <code class="o">=</code> <code class="k">new</code> <code class="n">ArrayList</code><code class="o">();</code>
<code class="n">Integer</code> <code class="n">thirtyThree</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Integer</code><code class="o">(</code> <code class="mi">33</code> <code class="o">);</code>
<code class="n">myNumbers</code><code class="o">.</code><code class="na">add</code><code class="o">(</code> <code class="n">thirtyThree</code> <code class="o">);</code></pre><p>Here, we have created an <code class="literal">Integer</code> wrapper object so that we can insert
the number into the <code class="literal">List</code>, using the
<code class="literal">add()</code> method, which accepts an
object. Later, when we are extracting elements from the <code class="literal">List</code>, we can recover the <code class="literal">int</code> value as follows:</p><a id="I_5_tt256"/><pre class="programlisting"> <code class="c1">// Simple Java code</code>
<code class="n">Integer</code> <code class="n">theNumber</code> <code class="o">=</code> <code class="o">(</code><code class="n">Integer</code><code class="o">)</code><code class="n">myNumbers</code><code class="o">.</code><code class="na">get</code><code class="o">(</code><code class="mi">0</code><code class="o">);</code>
<code class="kt">int</code> <code class="n">n</code> <code class="o">=</code> <code class="n">theNumber</code><code class="o">.</code><code class="na">intValue</code><code class="o">();</code> <code class="c1">// 33</code></pre><p>As we alluded to earlier, allowing Java to do this for us makes
the code more concise and safer. The usage of the wrapper class is
mostly hidden from us by the compiler, but it is still being used
internally:<a id="I_indexterm5_id691283" class="indexterm"/></p><a id="I_5_tt257"/><pre class="programlisting"> <code class="c1">// Java code using autoboxing and generics</code>
<code class="n">List</code><code class="o"><</code><code class="n">Integer</code><code class="o">></code> <code class="n">myNumbers</code> <code class="o">=</code> <code class="k">new</code> <code class="n">ArrayList</code><code class="o"><</code><code class="n">Integer</code><code class="o">>();</code>
<code class="n">myNumbers</code><code class="o">.</code><code class="na">add</code><code class="o">(</code> <code class="mi">33</code> <code class="o">);</code>
<code class="kt">int</code> <code class="n">n</code> <code class="o">=</code> <code class="n">myNumbers</code><code class="o">.</code><code class="na">get</code><code class="o">(</code> <code class="mi">0</code> <code class="o">);</code></pre><p>This example will make more sense as you read the next section on
<span class="emphasis"><em>autoboxing</em></span> and <span class="emphasis"><em>unboxing</em></span> of
primitive values.<a id="I_indexterm5_id691311" class="indexterm"/><a id="I_indexterm5_id691318" class="indexterm"/><a id="I_indexterm5_id691325" class="indexterm"/></p></div><div class="sect2" title="Autoboxing and Unboxing of Primitives"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-5-SECT-2.7"/>Autoboxing and Unboxing of Primitives</h2></div></div></div><p><a id="idx10220" class="indexterm"/> <a id="idx10221" class="indexterm"/> <a id="idx10230" class="indexterm"/> <a id="idx10246" class="indexterm"/> <a id="idx10256" class="indexterm"/> <a id="idx10262" class="indexterm"/>The Java compiler automatically wraps primitives in their
wrapper types and unwraps them where appropriate. This process is called
autoboxing and unboxing the primitive. It happens when primitives are
used as arguments and return values in methods and on simple assignment
to variables. For example:</p><a id="I_5_tt258"/><pre class="programlisting"> <code class="c1">// Simple assignments</code>
<code class="n">Integer</code> <code class="n">integer</code> <code class="o">=</code> <code class="mi">5</code><code class="o">;</code>
<code class="kt">int</code> <code class="n">i</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Integer</code><code class="o">(</code><code class="mi">5</code><code class="o">);</code>
<code class="c1">// Method arguments and return types</code>
<code class="n">Double</code> <code class="nf">multiply</code><code class="o">(</code> <code class="n">Double</code> <code class="n">a</code><code class="o">,</code> <code class="n">Double</code> <code class="n">b</code> <code class="o">)</code> <code class="o">{</code>
<code class="k">return</code> <code class="n">a</code><code class="o">.</code><code class="na">doubleValue</code><code class="o">()</code> <code class="o">*</code> <code class="n">b</code><code class="o">.</code><code class="na">doubleValue</code><code class="o">();</code>
<code class="o">}</code>
<code class="kt">double</code> <code class="n">d</code> <code class="o">=</code> <code class="n">multiply</code><code class="o">(</code> <code class="mf">5.0</code><code class="o">,</code> <code class="mf">5.0</code> <code class="o">);</code></pre><p>In the first case, Java simply wrapped the value 5 into an
<code class="literal">Integer</code> for us. In the second case,
it unwrapped our <code class="literal">Integer</code> object to
its primitive value. Next, we have a method that multiplies two <code class="literal">Double</code> wrapper objects and returns the result
as a <code class="literal">Double</code> wrapper. This example
actually has three cases of boxing and one case of unboxing. First, the
two double primitive values are boxed to <code class="literal">Double</code> types in order to call the method.
Next, the return statement of the method is actually being called on a
primitive double value, which the compiler turns into a <code class="literal">Double</code> before it leaves the method. Finally,
the compiler unboxes the return value on assignment to the primitive
double variable <code class="literal">d</code>.</p><div class="sect3" title="Performance implications of boxing"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-5-SECT-2.7.1"/>Performance implications of boxing</h3></div></div></div><p><a id="I_indexterm5_id691479" class="indexterm"/>Gauging performance is tricky. For the vast majority of
applications, the time it takes to perform tasks like creating a small
object or calling a method is miniscule compared to other factors,
such as I/O, user interaction, or the actual logic of the application.
As a general rule, it’s not wise to worry too much about these
detailed performance issues until the application is mature (no
premature optimization). However, we can anticipate that allowing Java
to box and unbox primitives in performance-critical areas will not be
as fast as using primitives directly. One aspect of this to consider
is how many new objects are being created and reclaimed by the garbage
collector. While in general Java may be forced to create a new object
for each boxed primitive, there are optimizations for a small range of
values. Java guarantees that the Boolean values <code class="literal">true</code> and <code class="literal">false</code>, as well as “small” valued numeric
types ranging from 0 to 127 for bytes and chars and from –128 to 127
for shorts and integers, are <a id="I_indexterm5_id691511" class="indexterm"/><span class="emphasis"><em>interned</em></span>. Saying that they are
interned means that instead of creating a new object each time, Java
reuses the same object on subsequent boxings. This is safe because
primitive wrappers are immutable and cannot be changed.</p><a id="I_5_tt259"/><pre class="programlisting"> <code class="n">Integer</code> <code class="n">i</code> <code class="o">=</code> <code class="mi">4</code><code class="o">;</code>
<code class="n">Integer</code> <code class="n">j</code> <code class="o">=</code> <code class="mi">4</code><code class="o">;</code>
<code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">(</code> <code class="n">i</code> <code class="o">==</code> <code class="n">j</code> <code class="o">);</code> <code class="c1">// This object equality is true only for small</code>
<code class="c1">// values.</code></pre><p>The effect of this, as shown in this code snippet, is that for
small identical values the boxed primitives are actually the same
object. Java also attempts to intern string values in Java classes.
We’ll talk about that in <a class="xref" href="ch10.html" title="Chapter 10. Working with Text">Chapter 10</a>.<a id="I_indexterm5_id691542" class="indexterm"/><a id="I_indexterm5_id691549" class="indexterm"/><a id="I_indexterm5_id691556" class="indexterm"/><a id="I_indexterm5_id691564" class="indexterm"/><a id="I_indexterm5_id691571" class="indexterm"/><a id="I_indexterm5_id691578" class="indexterm"/></p></div></div><div class="sect2" title="Variable-Length Argument Lists"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-5-SECT-2.8"/>Variable-Length Argument Lists</h2></div></div></div><p><a id="idx10235" class="indexterm"/> <a id="idx10252" class="indexterm"/>As we mentioned earlier, Java methods may have
<span class="emphasis"><em>variable-length argument lists</em></span> or “varargs” that
allow them to take any number of arguments when invoked. The most common
example usage of varargs is for the <a id="I_indexterm5_id691626" class="indexterm"/><code class="literal">printf()</code> style printing
method, which allows any number of tags to be embedded in a string and
takes an argument for each tag to be printed. For example:</p><a id="I_5_tt260"/><pre class="programlisting"> <code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">printf</code><code class="o">(</code><code class="s">"My name is %s and my age is %s\n"</code><code class="o">,</code> <code class="s">"Bob"</code><code class="o">,</code> <code class="mi">21</code> <code class="o">);</code>
<code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">printf</code><code class="o">(</code><code class="s">"Get the %s out of %s before I %s\n"</code><code class="o">,</code> <code class="n">item</code><code class="o">,</code> <code class="n">place</code><code class="o">,</code>
<code class="n">action</code> <code class="o">);</code></pre><p>Varargs allow the <code class="literal">printf()</code>
method to accept any number of items to print (from zero to dozens, as
awkward as that would be).</p><p>A method accepting a variable argument list is equivalent to a
method accepting an array of some type of object. The difference is that
the compiler makes the method call accept individual, comma-separated
values, and then packs them into the array for us. The syntax for
declaring the varargs method uses ellipses (<code class="literal">...</code>) where the square brackets of an array
might go. For example:</p><a id="I_5_tt261"/><pre class="programlisting"> <code class="kt">void</code> <code class="nf">printObjects</code><code class="o">(</code> <code class="n">Object</code> <code class="o">...</code> <code class="n">list</code> <code class="o">)</code> <code class="o">{</code>
<code class="c1">// list is an Object []</code>
<code class="k">for</code><code class="o">(</code> <code class="n">Object</code> <code class="n">o</code> <code class="o">:</code> <code class="n">list</code> <code class="o">)</code>
<code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">(</code> <code class="n">o</code> <code class="o">);</code>
<code class="o">}</code></pre><p>Inside the <code class="literal">printObjects()</code>
method, the variable <code class="literal">list</code> is actually
an <code class="literal">Object []</code> type. We could find out
how many arguments were passed to us by asking the array for its length
in the usual way:</p><a id="I_5_tt262"/><pre class="programlisting"> <code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">(</code> <code class="s">"Number of arguments:"</code> <code class="o">+</code> <code class="n">list</code><code class="o">.</code><code class="na">length</code> <code class="o">);</code></pre><p>If the caller passed no arguments, the array will be empty.</p><p>In the case of our <code class="literal">printObjects()</code> method, we could pass a mix of
primitive values as well as object types because the compiler would
automatically box the primitives to their wrapper types for us before
placing them into the <code class="literal">Object
[]</code>.</p><p>The variable argument list does not have to be of type <code class="literal">Object</code>. It can be of any type, including
primitive types. For example:</p><a id="I_5_tt263"/><pre class="programlisting"> <code class="n">printInts</code><code class="o">(</code> <code class="kt">int</code> <code class="o">...</code> <code class="n">list</code> <code class="o">)</code> <code class="o">{</code>
<code class="c1">// list is an int []</code>
<code class="o">}</code>
<code class="c1">// usage</code>
<code class="n">printInts</code><code class="o">(</code> <code class="mi">1</code><code class="o">,</code> <code class="mi">2</code><code class="o">,</code> <code class="mi">3</code><code class="o">,</code> <code class="mi">4</code> <code class="o">);</code>
<code class="n">printStrings</code><code class="o">(</code> <code class="n">String</code> <code class="o">...</code> <code class="n">list</code> <code class="o">)</code> <code class="o">{</code>
<code class="c1">// list is a String []</code>
<code class="o">}</code>
<code class="c1">// usage</code>
<code class="n">printStrings</code><code class="o">(</code> <code class="s">"foo"</code><code class="o">,</code> <code class="s">"bar"</code><code class="o">,</code> <code class="s">"gee"</code> <code cl