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

📄 tij319.htm

📁 这也是我们java老师给我们的thinking in java的一些资料
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<li>Object lifetime is never an issue in Java.</li>
<li>There is no language support (e.g., &#147;const&#148;) to prevent objects
from being modified and stop the negative effects of aliasing. You can&#146;t
simply use the <b>final </b>keyword in the argument list; that simply prevents
you from rebinding the reference to a different
object.</li></ul><p>If you&#146;re only reading information from an object and not modifying it, passing a reference 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&#146;s necessary to be able to treat the object as if it were &#147;local&#148; 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.<sup><a name="fnB116" href="#fn116">[116]</a></sup> Java does not, but it allows you to produce this effect. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendA_2708" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h3>
<a name="_Toc24775992"></a><a name="Heading24594"></a>Pass by value</h3>
<p>This brings up the terminology issue, which always seems good for an argument. The term is &#147;pass by value,&#148; 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&#146;re passing, but the real question is how you think about what you&#146;re passing. When it comes to the meaning of &#147;pass by value,&#148; there are two fairly distinct camps: <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]A0099" title="Send BackTalk Comment">Feedback</a></font><br></p>
<ol>
<li><a name="Index2153"></a>Java passes everything by value. When you&#146;re
passing primitives into a method, you get a distinct copy of the primitive. When
you&#146;re passing a reference into a method, you get a copy of the reference.
Ergo, everything is pass by value. Of course, the assumption is that
you&#146;re always thinking (and caring) that references 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&#146;re working with a reference. That is, it seems
to allow you to think of the reference as &#147;the object,&#148; since it
implicitly dereferences it whenever you make a method call. <font size="-2"><a
href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendA_2709" title="Send BackTalk
Comment">Feedback</a></font></li>
<li>Java passes primitives by value (no argument there), but objects are passed
by reference. This is the world view that the reference is an alias for the
object, so you <i>don&#146;t</i> think about passing references, but instead
say &#147;I&#146;m passing the object.&#148; Since you don&#146;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 at one time, one of the &#147;reserved but not implemented&#148;
keywords was <b>byvalue</b> (This will probably never be implemented). <font
size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendA_2710"
title="Send BackTalk
Comment">Feedback</a></font></li></ol><p>Having given both camps a good airing, and after saying &#147;It depends on how you think of a reference,&#148; I will attempt to sidestep the issue. In the end, it isn&#146;t <i>that</i> important&#151;what is important is that you understand that passing a reference allows the caller&#146;s object to be changed unexpectedly. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendA_2711" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h3>
<a name="_Toc375545425"></a><a name="_Toc24775993"></a><a name="Heading24599"></a>Cloning
objects</h3>
<p>The most likely reason for making a local copy of an object is if you&#146;re going to modify that object and you don&#146;t want to modify the caller&#146;s object. If you decide that you want to make a local copy, one approach is to use the <b>clone(&#160;)</b> method to perform the operation. This is a method that&#146;s defined as <b>protected </b>in the base class <b>Object</b>, and that you must override as <b>public </b>in any derived classes that you want to clone. For example, the standard library class <b>ArrayList</b> overrides <b>clone(&#160;)</b>, so we can call <b>clone(&#160;)</b> for <b>ArrayList</b>: <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]A0100" title="Send BackTalk Comment">Feedback</a></font><br></p>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: appendixa: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> com.bruceeckel.simpletest.*;
<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>private</font> <font color=#0000ff>static</font> Test monitor = <font color=#0000ff>new</font> Test();
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    ArrayList v = <font color=#0000ff>new</font> ArrayList();
    <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; 10; i++ )
      v.add(<font color=#0000ff>new</font> Int(i));
    System.out.println(<font color=#004488>"v: "</font> + v);
    ArrayList v2 = (ArrayList)v.clone();
    <font color=#009900>// Increment all v2's elements:</font>
    <font color=#0000ff>for</font>(Iterator e = v2.iterator();
        e.hasNext(); )
      ((Int)e.next()).increment();
    <font color=#009900>// See if it changed v's elements:</font>
    System.out.println(<font color=#004488>"v: "</font> + v);
    monitor.expect(<font color=#0000ff>new</font> String[] {
      <font color=#004488>"v: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"</font>,
      <font color=#004488>"v: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"</font>
    });
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<p>The <b>clone(&#160;)</b> method produces an <b>Object</b>, which must then be recast to the proper type. This example shows how <b>ArrayList</b>&#146;s<b> clone(&#160;)</b> method <i>does not</i> automatically try to clone each of the objects that the <b>ArrayList</b> contains&#151;the old <b>ArrayList</b> and the cloned <b>ArrayList</b> are aliased to the same objects. This is often called a <a name="Index2154"></a><a name="Index2155"></a><i>shallow copy,</i> since it&#146;s copying only the &#147;surface&#148; portion of an object. The actual object consists of this &#147;surface,&#148; plus all the objects that the references are pointing to, plus all the objects <i>those </i>objects are pointing to, etc. This is often referred to as the &#147;web of objects.&#148; Copying the entire mess is called a <a name="Index2156"></a><a name="Index2157"></a><a name="Index2158"></a><a name="Index2159"></a><i>deep copy. </i><font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendA_2712" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>You can see the effect of the shallow copy in the output, where the actions performed on <b>v2 </b>affect <b>v</b>:<br></p>

<BLOCKQUOTE><FONT SIZE = "+1"><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></BLOCKQUOTE><p><br></p>
<p>Not trying to <b>clone(&#160;) </b>the objects contained in the <b>ArrayList </b>is probably a fair assumption, because there&#146;s no guarantee that those objects <i>are</i> cloneable.<sup><a name="fnB117" href="#fn117">[117]</a></sup> <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendA_2713" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h3>
<a name="_Toc375545426"></a><a name="_Toc24775994"></a><a name="Heading24642"></a>Adding
cloneability to a class</h3>
<p>Even though the clone method is defined in the base-of-all-classes <b>Object</b>, cloning is <i>not </i>automatically available in every class.<sup><a name="fnB118" href="#fn118">[118]</a></sup> This would seem to be counterintuitive to the idea that base-class methods are always available in derived classes. Cloning in Java does indeed go against this idea; if you want it to exist for a class, you must specifically add code to make cloning work. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendA_2714" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h4>
<a name="Heading24653"></a>Using a trick with <b>protected</b></h4>
<p>To prevent default cloneability in every class you create, the <a name="Index2160"></a><a name="Index2161"></a><b>clone(&#160;)</b> method is <b>protected</b> in the base class <b>Object</b>. Not only does this mean that it&#146;s not available by default to the client programmer who is simply using the class (not subclassing it), but it also means that you cannot call <b>clone(&#160;)</b> via a reference to the base class. (Although that might seem to be useful in some situations, such as to polymorphically clone a bunch of <b>Object</b>s.) It is, in effect, a way to give you, at compile time, the information that your object is not cloneable&#151;and oddly enough, most classes in the standard Java library are not cloneable. Thus, if you say:<br></p>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>    Integer x = <font color=#0000ff>new</font> Integer(1);
    x = x.clone();</PRE></FONT></BLOCKQUOTE><p><br></p>
<p>You will get, at compile time, an error message that says <b>clone(&#160;) </b>is not accessible (since <b>Integer</b> doesn&#146;t override it and it defaults to the <b>protected</b> version). <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendA_2715" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>If, however, you&#146;re in a method of a class <i>derived</i> from <b>Object </b>(as all classes are), then you have permission to call <b>Object.clone(&#160;) </b>because it&#146;s <a name="Index2162"></a><b>protected </b>and you&#146;re an inheritor. The base class <b>clone(&#160;) </b>has useful functionality; it performs the actual bitwise duplication <i>of the derived-class object</i>, thus acting as the common cloning operation. However, you then need to make <i>your</i> clone operation <b>public</b> for it to be accessible. So, two key issues when you clone are: <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendA_2716" title="Send BackTalk Comment">Feedback</a></font><br></p>
<ul>
<li><a name="Index2163"></a>Call <b>super.clone(&#160;) </b></li>
<li>Make your clone
<b>public</b></li></ul><p>You&#146;ll probably want to override <b>clone(&#160;) </b>in any further derived classes; otherwise, your (now <b>public</b>) <b>clone(&#160;)</b> will be used, and that might not do the right thing (although, since <b>Object.clone(&#160;)</b> makes a copy of the actual object, it might). The <b>protected</b> trick works only once: the first time you inherit from a class that has no cloneability and you want to make a class that&#146;s cloneable. In any classes inherited from your class, the <b>clone(&#160;) </b>method is available since it&#146;s not possible in Java to reduce the access of a method during derivation. That is, once a class is cloneable, everything derived from it is cloneable unless you use provided mechanisms (described later) to &#147;turn off&#148; cloning. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendA_2717" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h4>
<a name="Heading24663"></a>Implementing the <b>Cloneable</b> interface</h4>
<p>There&#146;s one more thing you need to do to complete the cloneability of an object: implement the <a name="Index2164"></a><b>Cloneable</b> <b>interface</b>. This <a name="Index2165"></a><b>interface</b> is a bit strange, because it&#146;s empty!<br></p>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>interface</font> Cloneable {}</PRE></FONT></BLOCKQUOTE><p><br></p>
<p>The reason for implementing this empty <b>interface</b> is obviously not because you are going to upcast to <b>Cloneable</b> and call one of its methods. The use of <b>interface</b> in this way is called a <i>tagging interface</i> because it acts as a kind of flag, wired into the type of the class. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendA_2718" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>There are two reasons for the existence of the <b>Cloneable</b> <b>interface</b>. First, you might have an upcast reference to a base type and not know whether it&#146;s possible to clone that object. In this case, you can use the <b>instanceof</b> keyword (described in Chapter 10) to find out whether the reference is connected to an object that can be cloned: <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]A0101" title="Send BackTalk Comment">Feedback</a></font><br></p>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>if</font>(myReference <font color=#0000ff>instanceof</font> Cloneable) <font color=#009900>// ...</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<p>The second reason is that mixed into this design for cloneability was the thought that maybe you didn&#146;t want all types of objects to be cloneable. So <b>Object.clone(&#160;)</b> verifies that a class implements the <b>Cloneable</b> interface. If not, it throws a <b>CloneNotSupportedException</b> exception. So in general, you&#146;re forced to <b>implement Cloneable</b> as part of support for cloning. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendA_2719" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h3>
<a name="_Toc375545427"></a><a name="_Toc24775995"></a><a name="Heading24672"></a>Successful
cloning</h3>
<p>Once you understand the details of implementing the <b>clone(&#160;)</b> method, you&#146;re able to create classes that can be easily duplicated to provide a local copy:<br></p>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: appendixa:LocalCopy.java</font>
<font color=#009900>// Creating local copies with clone().</font>
<font color=#0000ff>import</font> com.bruceeckel.simpletest.*;
<font color=#0000ff>import</font> java.util.*;

<font color=#0000ff>class</font> MyObject <font color=#0000ff>implements</font> Cloneable {
  <font color=#0000ff>private</font> <font color=#0000ff>int</font> n;
  <font color=#0000ff>public</font> MyObject(<font color=#0000ff>int</font> n) { <font color=#0000ff>this</font>.n = n; }
  <font color=#0000ff>public</font> Object clone() {
    Object o = <font color=#0000ff>null</font>;
    <font color=#0000ff>try</font> {
      o = <font color=#0000ff>super</font>.clone();
    } <font color=#0000ff>catch</font>(CloneNotSupportedException e) {
      System.err.println(<font color=#004488>"MyObject can't clone"</font>);
    }
    <font color=#0000ff>return</font> o;
  }
  <font color=#0000ff>public</font> <font color=#0000ff>int</font> getValue() { <font color=#0000ff>return</font> n; }
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> setValue(<font color=#0000ff>int</font> n) { <font color=#0000ff>this</font>.n = n; }
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> increment() { n++; }
  <font color=#0000ff>public</font> String toString() { <font color=#0000ff>return</font> Integer.toString(n); }
}

<font color=#0000ff>public</font> <font color=#0000ff>class</font> LocalCopy {
  <font color=#0000ff>private</font> <font color=#0000ff>static</font> Test monitor = <font color=#0000ff>new</font> Test();
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> MyObject g(MyObject v) {
    <font color=#009900>// Passing a reference, modifies outside object:</font>

⌨️ 快捷键说明

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