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

📄 tij0127.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 5 页
字号:
always available in derived classes. Cloning in Java goes against this idea; if
you want it to exist for a class, you must specifically add code to make
cloning work.
</FONT><P></DIV>
<A NAME="Heading371"></A><H4 ALIGN=LEFT>
Using
a trick with protected
</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">To
prevent default clonability in every class you create, the <A NAME="Index1454"></A><A NAME="Index1455"></A></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 is 
</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">.
Not only does this mean that it&#8217;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 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>clone(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
via a handle to the base class. (Although that might seem to be useful in some
situations, such as to polymorphically clone a bunch of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Object</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s.)
It is in effect a way to give you, at compile time, the information that your
object is not cloneable &#8211; and oddly enough most classes in the standard
Java library are not cloneable. Thus, if you say:
</FONT><P></DIV>

<font color="#990000"><PRE>    Integer x = <font color="#0000ff">new</font> Integer(1);
    x = x.clone(); </PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
will get, at compile time, an error message that says 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>clone(&#160;)
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">is
not accessible (since 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Integer</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
doesn&#8217;t override it and it defaults to the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>protected</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
version). 
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">If,
however, you&#8217;re in a class derived from 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Object
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">(as
all classes are), then you have permission to call 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Object.clone(&#160;)
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">because
it&#8217;s <A NAME="Index1456"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>protected
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">and
you&#8217;re an inheritor. The base class 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>clone(&#160;)
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">has
useful functionality &#8211; it performs the actual bitwise duplication 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>of
the derived-class object
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
thus acting as the common cloning operation. However, you then need to make 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>your</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
clone operation 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
for it to be accessible. So two key issues when you clone are: virtually always
call <A NAME="Index1457"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>super.clone(&#160;)
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">and
make your clone 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></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&#8217;ll
probably want to override 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>clone(&#160;)
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">in
any further derived classes, otherwise your (now 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">)
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>clone(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
will be used, and that might not do the right thing (although, since 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Object.clone(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
makes a copy of the actual object, it might). The 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>protected</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
trick works only once, the first time you inherit from a class that has no
clonability and you want to make a class that&#8217;s cloneable. In any classes
inherited from your class 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
is available since it&#8217;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 &#8220;turn off&#8221; cloning.
</FONT><P></DIV>
<A NAME="Heading372"></A><H4 ALIGN=LEFT>
Implementing
the Cloneable interface
</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">There&#8217;s
one more thing you need to do to complete the clonability of an object:
implement the <A NAME="Index1458"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Cloneable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
This <A NAME="Index1459"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is a bit strange because it&#8217;s empty!
</FONT><P></DIV><DIV ALIGN=LEFT><TT><FONT FACE="Courier New" SIZE=3 COLOR="Black">interface
Cloneable {}
</FONT></TT><P></DIV><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
reason for implementing this empty 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is obviously not because you are going to upcast to 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Cloneable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and call one of its methods. The use of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
here is considered by some to be a &#8220;hack&#8221; because it&#8217;s using
a feature for something other than its original intent. Implementing the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Cloneable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
acts as a kind of a flag, wired into the type of the class. 
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">There
are two reasons for the existence of the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Cloneable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
First, you might have an upcast handle to a base type and not know whether
it&#8217;s possible to clone that object. In this case, you can use the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>instanceof</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
keyword (described in Chapter 11) to find out whether the handle is connected
to an object that can be cloned:
</FONT><P></DIV><DIV ALIGN=LEFT><TT><FONT FACE="Courier New" SIZE=3 COLOR="Black">if(myHandle
instanceof Cloneable) // ...
</FONT></TT><P></DIV><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
second reason is that mixed into this design for clonability was the thought
that maybe you didn&#8217;t want all types of objects to be cloneable. So 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Object.clone(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
verifies that a class implements the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Cloneable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
interface. If not, it throws a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>CloneNotSupportedException</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
exception. So in general, you&#8217;re forced to 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>implement
Cloneable
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
as part of support for cloning.
</FONT><a name="_Toc375545427"></a><a name="_Toc408018660"></a><P></DIV>
<A NAME="Heading373"></A><H3 ALIGN=LEFT>
Successful
cloning
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Once
you understand the details of implementing 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, you&#8217;re able to create classes that can be easily duplicated to
provide a local copy:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: LocalCopy.java</font>
<font color="#009900">// Creating local copies with clone()</font>
<font color="#0000ff">import</font> java.util.*;

<font color="#0000ff">class</font> MyObject <font color="#0000ff">implements</font> Cloneable {
  <font color="#0000ff">int</font> i;
  MyObject(<font color="#0000ff">int</font> ii) { i = ii; }
  <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.out.println("MyObject can't clone");
    }
    <font color="#0000ff">return</font> o;
  }
  <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> LocalCopy {
  <font color="#0000ff">static</font> MyObject g(MyObject v) {
    <font color="#009900">// Passing a handle, modifies outside object:</font>
    v.i++;
    <font color="#0000ff">return</font> v;
  }
  <font color="#0000ff">static</font> MyObject f(MyObject v) {
    v = (MyObject)v.clone(); <font color="#009900">// Local copy</font>
    v.i++;
    <font color="#0000ff">return</font> v;
  }
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
    MyObject a = <font color="#0000ff">new</font> MyObject(11);
    MyObject b = g(a);
    <font color="#009900">// Testing handle equivalence,</font>
    <font color="#009900">// not object equivalence:</font>
    <font color="#0000ff">if</font>(a == b) 
      System.out.println("a == b");
    <font color="#0000ff">else</font> 
      System.out.println("a != b");
    System.out.println("a = " + a);
    System.out.println("b = " + b);
    MyObject c = <font color="#0000ff">new</font> MyObject(47);
    MyObject d = f(c);
    <font color="#0000ff">if</font>(c == d) 
      System.out.println("c == d");
    <font color="#0000ff">else</font> 
      System.out.println("c != d");
    System.out.println("c = " + c);
    System.out.println("d = " + d);
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">First
of all, 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>clone(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
must be accessible so you must make it 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Second, for the initial part of your 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>clone(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
operation you should call the base-class version of 
</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 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>clone(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that&#8217;s being called here is the one that&#8217;s predefined inside 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Object</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
and you can call it because it&#8217;s 

⌨️ 快捷键说明

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