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

📄 tij0127.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 5 页
字号:
can see what’s necessary in order to do a deep copy of a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:
after 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 cloned, you have to step through and clone each one of the objects pointed
to by the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
You&#8217;d have to do something similar to this to do a deep copy of a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Hashtable</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">The
remainder of the example shows that the cloning did happen by showing that,
once an object is cloned, you can change it and the original object is left
untouched.
</FONT><a name="_Toc408018664"></a><a name="_Toc375545429"></a><P></DIV>
<A NAME="Heading377"></A><H3 ALIGN=LEFT>
Deep
copy via serialization
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">When
you consider Java 1.1<A NAME="Index1478"></A>
object serialization (introduced in Chapter 10), you might observe that an
object that&#8217;s serialized and then deserialized is, in effect, cloned.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">So
why not use <A NAME="Index1479"></A><A NAME="Index1480"></A>serialization
to perform deep copying? Here&#8217;s an example that compares the two
approaches by timing them:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: Compete.java</font>
<font color="#0000ff">import</font> java.io.*;

<font color="#0000ff">class</font> Thing1 <font color="#0000ff">implements</font> Serializable {}
<font color="#0000ff">class</font> Thing2 <font color="#0000ff">implements</font> Serializable {
  Thing1 o1 = <font color="#0000ff">new</font> Thing1();
}

<font color="#0000ff">class</font> Thing3 <font color="#0000ff">implements</font> Cloneable {
  <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("Thing3 can't clone");
    }
    <font color="#0000ff">return</font> o;
  }
}

<font color="#0000ff">class</font> Thing4 <font color="#0000ff">implements</font> Cloneable {
  Thing3 o3 = <font color="#0000ff">new</font> Thing3();
  <font color="#0000ff">public</font> Object clone() {
    Thing4 o = <font color="#0000ff">null</font>;
    <font color="#0000ff">try</font> {
      o = (Thing4)<font color="#0000ff">super</font>.clone();
    } <font color="#0000ff">catch</font> (CloneNotSupportedException e) {
      System.out.println("Thing4 can't clone");
    }
    <font color="#009900">// Clone the field, too:</font>
    o.o3 = (Thing3)o3.clone();
    <font color="#0000ff">return</font> o;
  }
}

<font color="#0000ff">public</font> <font color="#0000ff">class</font> Compete {
  <font color="#0000ff">static</font> <font color="#0000ff">final</font> <font color="#0000ff">int</font> SIZE = 5000;
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
    Thing2[] a = <font color="#0000ff">new</font> Thing2[SIZE];
    <font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 0; i &lt; a.length; i++)
      a[i] = <font color="#0000ff">new</font> Thing2();
    Thing4[] b = <font color="#0000ff">new</font> Thing4[SIZE];
    <font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 0; i &lt; b.length; i++)
      b[i] = <font color="#0000ff">new</font> Thing4();
    <font color="#0000ff">try</font> {
      <font color="#0000ff">long</font> t1 = System.currentTimeMillis();
      ByteArrayOutputStream buf = 
        <font color="#0000ff">new</font> ByteArrayOutputStream();
      ObjectOutputStream o =
        <font color="#0000ff">new</font> ObjectOutputStream(buf);
      <font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 0; i &lt; a.length; i++)
        o.writeObject(a[i]);
      <font color="#009900">// Now get copies:</font>
      ObjectInputStream in =
        <font color="#0000ff">new</font> ObjectInputStream(
          <font color="#0000ff">new</font> ByteArrayInputStream(
            buf.toByteArray()));
      Thing2[] c = <font color="#0000ff">new</font> Thing2[SIZE];
      <font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 0; i &lt; c.length; i++)
        c[i] = (Thing2)in.readObject();
      <font color="#0000ff">long</font> t2 = System.currentTimeMillis();
      System.out.println(
        "Duplication via serialization: " +
        (t2 - t1) + " Milliseconds");
      <font color="#009900">// Now try cloning:</font>
      t1 = System.currentTimeMillis();
      Thing4[] d = <font color="#0000ff">new</font> Thing4[SIZE];
      <font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 0; i &lt; d.length; i++)
        d[i] = (Thing4)b[i].clone();
      t2 = System.currentTimeMillis();
      System.out.println(
        "Duplication via cloning: " +
        (t2 - t1) + " Milliseconds");
    } <font color="#0000ff">catch</font>(Exception e) {
      e.printStackTrace();
    }
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Thing2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Thing4</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
contain member objects so that there&#8217;s some deep copying going on.
It&#8217;s interesting to notice that while 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Serializable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
classes are easy to set up, there&#8217;s much more work going on to duplicate
them. Cloning involves a lot of work to set up the class, but the actual
duplication of objects is relatively simple. The results really tell the tale.
Here is the output from three different runs:
</FONT><P></DIV>

<font color="#990000"><PRE>Duplication via serialization: 3400 Milliseconds
Duplication via cloning: 110 Milliseconds

Duplication via serialization: 3410 Milliseconds
Duplication via cloning: 110 Milliseconds

Duplication via serialization: 3520 Milliseconds
Duplication via cloning: 110 Milliseconds </PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Despite
the obviously huge time difference between serialization and cloning,
you&#8217;ll also notice that the serialization technique seems to vary
significantly in its duration, while cloning takes the same amount of time
every time.
</FONT><a name="_Toc408018665"></a><P></DIV>
<A NAME="Heading378"></A><H3 ALIGN=LEFT>
Adding
cloneability 
<P>further
down a hierarchy
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">If
you create a new class, its base class defaults to 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Object</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which defaults to non-clonability (as you&#8217;ll see in the next section). As
long as you don&#8217;t explicitly add clonability, you won&#8217;t get it. <A NAME="Index1481"></A><A NAME="Index1482"></A>But
you can add it in at any layer and it will then be cloneable from that layer
downward, like this:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: HorrorFlick.java</font>
<font color="#009900">// You can insert Cloneability at any</font>
<font color="#009900">// level of inheritance.</font>
<font color="#0000ff">import</font> java.util.*;

<font color="#0000ff">class</font> Person {}
<font color="#0000ff">class</font> Hero <font color="#0000ff">extends</font> Person {}
<font color="#0000ff">class</font> Scientist <font color="#0000ff">extends</font> Person 
    <font color="#0000ff">implements</font> Cloneable {
  <font color="#0000ff">public</font> Object clone() {
    <font color="#0000ff">try</font> {
      <font color="#0000ff">return</font> <font color="#0000ff">super</font>.clone();
    } <font color="#0000ff">catch</font> (CloneNotSupportedException e) {
      <font color="#009900">// this should never happen:</font>
      <font color="#009900">// It's Cloneable already!</font>
      <font color="#0000ff">throw</font> <font color="#0000ff">new</font> InternalError();
    }
  }
}
<font color="#0000ff">class</font> MadScientist <font color="#0000ff">extends</font> Scientist {}

<font color="#0000ff">public</font> <font color="#0000ff">class</font> HorrorFlick {
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
    Person p = <font color="#0000ff">new</font> Person();
    Hero h = <font color="#0000ff">new</font> Hero();
    Scientist s = <font color="#0000ff">new</font> Scientist();
    MadScientist m = <font color="#0000ff">new</font> MadScientist();

    <font color="#009900">// p = (Person)p.clone(); // Compile error</font>
    <font color="#009900">// h = (Hero)h.clone(); // Compile error</font>
    s = (Scientist)s.clone();
    m = (MadScientist)m.clone();
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Before
clonability was added, the compiler stopped you from trying to clone things.
When clonability is added in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Scientist</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
then 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Scientist</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and all its descendants are cloneable.
</FONT><a name="_Toc375545430"></a><a name="_Toc408018666"></a><P></DIV>
<A NAME="Heading379"></A><H3 ALIGN=LEFT>
Why
this strange design?
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">If
all this seems to be a strange scheme, that&#8217;s because it is. You might
wonder why it worked out this way. What is the meaning behind this design? What
follows is not a substantiated story &#8211; probably because much of the
marketing around Java makes it out to be a perfectly-designed language &#8211;
but it does go a long way toward explaining how things ended up the way they did.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Originally,
Java was designed as a language to control hardware boxes, and definitely not
with the Internet in mind. In a general-purpose language like this, it makes
sense that the programmer be able to clone any object. Thus, 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>clone(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
was placed in the root class 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Object</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>but</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
it was a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method so you could 

⌨️ 快捷键说明

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