⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tij0127.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<html><body>

<table width="100%"><tr>
<td>
<a href="http://www.bruceeckel.com/javabook.html">Bruce Eckel's Thinking in Java</a>
</td>
<td align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0126.html">Prev</a> | <a href="tij0128.html">Next</a>
</td>
</tr></table>
<hr>

<H2 ALIGN=LEFT>
Making
local copies
</H2>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">To
review: all argument passing in Java is performed by passing handles. That is,
when you pass &#8220;an object,&#8221; you&#8217;re really passing only a
handle to an object that lives outside the method, so if you perform any
modifications with that handle, you modify the outside object. In addition:
</FONT><P></DIV>
<UL>
<LI><FONT FACE="Symbol" SIZE=3 COLOR="Black">	</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Aliasing
happens automatically during argument passing.
</FONT><LI><FONT FACE="Symbol" SIZE=3 COLOR="Black">	</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">There
are no local objects, only local handles.
</FONT><LI><FONT FACE="Symbol" SIZE=3 COLOR="Black">	</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Handles
have scopes, objects do not.
</FONT><LI><FONT FACE="Symbol" SIZE=3 COLOR="Black">	</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Object
lifetime is never an issue in Java.
</FONT><LI><FONT FACE="Symbol" SIZE=3 COLOR="Black">	</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">There
is no language support (e.g. const) to prevent objects from being modified (to
prevent negative effects of aliasing).
</FONT></UL><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">If
you&#8217;re only reading information from an object and not modifying it,
passing a handle is the most efficient form of argument passing. This is nice;
the default way of doing things is also the most efficient. However, sometimes
it&#8217;s necessary to be able to treat the object as if it were
&#8220;local&#8221; so that changes you make affect only a local copy and do
not modify the outside object. Many programming languages support the ability
to automatically make a local copy of the outside object, inside the method.
</FONT><A NAME="fnB49" HREF="#fn49">[49]</A><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
Java does not, but it allows you to produce this effect.
</FONT><a name="_Toc408018657"></a><P></DIV>
<A NAME="Heading368"></A><H3 ALIGN=LEFT>
Pass
by value
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
brings up the terminology issue, which always seems good for an argument. The
term is &#8220;<A NAME="Index1447"></A>pass
by value,&#8221; and the meaning depends on how you perceive the operation of
the program. The general meaning is that you get a local copy of whatever
you&#8217;re passing, but the real question is how you think about what
you&#8217;re passing. When it comes to the meaning of &#8220;pass by
value,&#8221; there are two fairly distinct camps:
</FONT><P></DIV>
<OL>
<LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">	Java
passes everything by value. When you&#8217;re passing primitives into a method,
you get a distinct copy of the primitive. When you&#8217;re passing a handle
into a method, you get a copy of the handle. Ergo, everything is pass by value.
Of course, the assumption is that you&#8217;re always thinking (and caring)
that handles are being passed, but it seems like the Java design has gone a
long way toward allowing you to ignore (most of the time) that you&#8217;re
working with a handle. That is, it seems to allow you to think of the handle as
&#8220;the object,&#8221; since it implicitly dereferences it whenever you make
a method call.
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">	Java
passes primitives by value (no argument there), but objects are passed by
reference. This is the world view that the handle is an alias for the object,
so you 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>don&#8217;t</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
think about passing handles, but instead say &#8220;I&#8217;m passing the
object.&#8221; Since you don&#8217;t get a local copy of the object when you
pass it into a method, objects are clearly not passed by value. There appears
to be some support for this view within Sun, since one of the &#8220;reserved
but not implemented&#8221; keywords is 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>byvalue</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
(There&#8217;s no knowing, however, whether that keyword will ever see the
light of day.)
</FONT></OL><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Having
given both camps a good airing and after saying &#8220;It depends on how you
think of a handle,&#8221; I will attempt to sidestep the issue for the rest of
the book. In the end, it isn&#8217;t 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>that</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
important &#8211; what is important is that you understand that passing a
handle allows the caller&#8217;s object to be changed unexpectedly.
</FONT><a name="_Toc375545425"></a><a name="_Toc408018658"></a><P></DIV>
<A NAME="Heading369"></A><H3 ALIGN=LEFT>
Cloning
objects
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
most likely reason for making a local copy of an object is if you&#8217;re
going to modify that object and you don&#8217;t want to modify the
caller&#8217;s object. If you decide that you want to make a local copy, you
simply use the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>clone(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method to perform the operation. This is a method that&#8217;s defined as 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>protected
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">in
the base class 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Object</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and which you must override as 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">in
any derived classes that you want to clone. For example, the standard library
class 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
overrides 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>clone(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
so we can call 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>clone(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
for 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: Cloning.java</font>
<font color="#009900">// The clone() operation works for only a few</font>
<font color="#009900">// items in the standard Java library.</font>
<font color="#0000ff">import</font> java.util.*;

<font color="#0000ff">class</font> Int {
  <font color="#0000ff">private</font> <font color="#0000ff">int</font> i;
  <font color="#0000ff">public</font> Int(<font color="#0000ff">int</font> ii) { i = ii; }
  <font color="#0000ff">public</font> <font color="#0000ff">void</font> increment() { i++; }
  <font color="#0000ff">public</font> String toString() { 
    <font color="#0000ff">return</font> Integer.toString(i); 
  }
}

<font color="#0000ff">public</font> <font color="#0000ff">class</font> Cloning {
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
    Vector v = <font color="#0000ff">new</font> Vector();
    <font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 0; i &lt; 10; i++ )
      v.addElement(<font color="#0000ff">new</font> Int(i));
    System.out.println("v: " + v);
    Vector v2 = (Vector)v.clone();
    <font color="#009900">// Increment all v2's elements:</font>
    <font color="#0000ff">for</font>(Enumeration e = v2.elements();
        e.hasMoreElements(); )
      ((Int)e.nextElement()).increment();
    <font color="#009900">// See if it changed v's elements:</font>
    System.out.println("v: " + v);
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>clone(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method produces an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Object</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which must then be recast to the proper type. This example shows how 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">&#8217;s</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>
clone(&#160;)
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>does
not
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
automatically try to clone each of the objects that the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
contains &#8211; the old 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and the cloned 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
are aliased to the same objects. This is often called a <A NAME="Index1448"></A><A NAME="Index1449"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>shallow
copy
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
since it&#8217;s copying only the &#8220;surface&#8221; portion of an object.
The actual object consists of this &#8220;surface&#8221; plus all the objects
that the handles are pointing to, plus all the objects 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>those
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">objects
are pointing to, etc. This is often referred to as the &#8220;<A NAME="Index1450"></A><A NAME="Index1451"></A>web
of objects.&#8221; Copying the entire mess is called a <A NAME="Index1452"></A><A NAME="Index1453"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>deep
copy
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
can see the effect of the shallow copy in the output, where the actions
performed on 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>v2
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">affect
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>v</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:</FONT><P></DIV>

<font color="#990000"><PRE>v: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
v: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] </PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Not
trying to 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>clone(&#160;)
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">the
objects contained in the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">is
probably a fair assumption because there&#8217;s no guarantee that those objects 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>are</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
cloneable.
</FONT><A NAME="fnB50" HREF="#fn50">[50]</A><a name="_Toc375545426"></a><a name="_Toc408018659"></a><P></DIV>
<A NAME="Heading370"></A><H3 ALIGN=LEFT>
Adding
cloneability to a class
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Even
though the clone method is defined in the base-of-all-classes 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Object</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
cloning is 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>not
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">automatically
available in every class.
</FONT><A NAME="fnB51" HREF="#fn51">[51]</A><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
This would seem to be counterintuitive to the idea that base-class methods are

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -