📄 chapter12.html
字号:
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) {
e.printStackTrace();
}
<font color=#0000ff>return</font> o;
}
}
<font color=#0000ff>class</font> TemperatureReading <font color=#0000ff>implements</font> Cloneable {
<font color=#0000ff>private</font> <font color=#0000ff>long</font> time;
<font color=#0000ff>private</font> <font color=#0000ff>double</font> temperature;
<font color=#0000ff>public</font> TemperatureReading(<font color=#0000ff>double</font> temperature) {
time = System.currentTimeMillis();
<font color=#0000ff>this</font>.temperature = temperature;
}
<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) {
e.printStackTrace();
}
<font color=#0000ff>return</font> o;
}
}
<font color=#0000ff>class</font> OceanReading <font color=#0000ff>implements</font> Cloneable {
<font color=#0000ff>private</font> DepthReading depth;
<font color=#0000ff>private</font> TemperatureReading temperature;
<font color=#0000ff>public</font> OceanReading(<font color=#0000ff>double</font> tdata, <font color=#0000ff>double</font> ddata){
temperature = <font color=#0000ff>new</font> TemperatureReading(tdata);
depth = <font color=#0000ff>new</font> DepthReading(ddata);
}
<font color=#0000ff>public</font> Object clone() {
OceanReading o = <font color=#0000ff>null</font>;
<font color=#0000ff>try</font> {
o = (OceanReading)<font color=#0000ff>super</font>.clone();
} <font color=#0000ff>catch</font> (CloneNotSupportedException e) {
e.printStackTrace();
}
<font color=#009900>// Must clone handles:</font>
o.depth = (DepthReading)o.depth.clone();
o.temperature =
(TemperatureReading)o.temperature.clone();
<font color=#0000ff>return</font> o; <font color=#009900>// Upcasts back to Object</font>
}
}
<font color=#0000ff>public</font> <font color=#0000ff>class</font> DeepCopy {
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
OceanReading reading =
<font color=#0000ff>new</font> OceanReading(33.9, 100.5);
<font color=#009900>// Now clone it:</font>
OceanReading r =
(OceanReading)reading.clone();
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>DepthReading</B> and
<B>TemperatureReading</B> are quite similar; they both contain only primitives.
Therefore, the <B>clone( )</B> method can be quite simple: it calls
<B>super.clone( )</B> and returns the result. Note that the
<B>clone( )</B> code for both classes is identical.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>OceanReading</B> is composed of
<B>DepthReading</B> and <B>TemperatureReading</B> objects and so, to produce a
deep copy, its <B>clone( )</B> must clone the handles inside
<B>OceanReading</B>. To accomplish this, the result of
<B>super.clone( )</B> must be cast to an <B>OceanReading</B> object (so you
can access the <B>depth</B> and <B>temperature</B>
handles).</FONT><A NAME="_Toc408018663"></A><BR></P></DIV>
<A NAME="Heading375"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
A deep copy with Vector</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Let’s revisit the
<A NAME="Index1475"></A><A NAME="Index1476"></A><B>Vector</B> example from
earlier in this chapter. This time the <B>Int2</B> class is cloneable so the
<B>Vector</B> can be deep copied:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: AddingClone.java</font>
<font color=#009900>// You must go through a few gyrations to</font>
<font color=#009900>// add cloning to your own class.</font>
<font color=#0000ff>import</font> java.util.*;
<font color=#0000ff>class</font> Int2 <font color=#0000ff>implements</font> Cloneable {
<font color=#0000ff>private</font> <font color=#0000ff>int</font> i;
<font color=#0000ff>public</font> Int2(<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> 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(<font color=#004488>"Int2 can't clone"</font>);
}
<font color=#0000ff>return</font> o;
}
}
<font color=#009900>// Once it's cloneable, inheritance</font>
<font color=#009900>// doesn't remove cloneability:</font>
<font color=#0000ff>class</font> Int3 <font color=#0000ff>extends</font> Int2 {
<font color=#0000ff>private</font> <font color=#0000ff>int</font> j; <font color=#009900>// Automatically duplicated</font>
<font color=#0000ff>public</font> Int3(<font color=#0000ff>int</font> i) { <font color=#0000ff>super</font>(i); }
}
<font color=#0000ff>public</font> <font color=#0000ff>class</font> AddingClone {
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
Int2 x = <font color=#0000ff>new</font> Int2(10);
Int2 x2 = (Int2)x.clone();
x2.increment();
System.out.println(
<font color=#004488>"x = "</font> + x + <font color=#004488>", x2 = "</font> + x2);
<font color=#009900>// Anything inherited is also cloneable:</font>
Int3 x3 = <font color=#0000ff>new</font> Int3(7);
x3 = (Int3)x3.clone();
Vector v = <font color=#0000ff>new</font> Vector();
<font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i < 10; i++ )
v.addElement(<font color=#0000ff>new</font> Int2(i));
System.out.println(<font color=#004488>"v: "</font> + v);
Vector v2 = (Vector)v.clone();
<font color=#009900>// Now clone each element:</font>
<font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i < v.size(); i++)
v2.setElementAt(
((Int2)v2.elementAt(i)).clone(), i);
<font color=#009900>// Increment all v2's elements:</font>
<font color=#0000ff>for</font>(Enumeration e = v2.elements();
e.hasMoreElements(); )
((Int2)e.nextElement()).increment();
<font color=#009900>// See if it changed v's elements:</font>
System.out.println(<font color=#004488>"v: "</font> + v);
System.out.println(<font color=#004488>"v2: "</font> + v2);
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>Int3</B> is inherited from
<B>Int2</B> and a new primitive member <B>int j </B>is added. You might think
that you’d need to override <B>clone( )</B> again to make sure
<B>j</B> is copied, but that’s not the case. When <B>Int2</B>’s
<B>clone( )</B> is called as <B>Int3</B>’s <B>clone( )</B>, it
calls <B>Object.clone( ),</B> which determines that it’s working with
an <B>Int3</B> and duplicates all the bits in the <B>Int3</B>. As long as you
don’t add handles that need to be cloned, the one call to
<B>Object.clone( )</B> performs all of the necessary duplication,
regardless of how far down in the hierarchy <B>clone( )</B> is
defined.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can see what’s necessary
in order to do a deep copy of a <B>Vector</B>: after the <B>Vector</B> is
cloned, you have to step through and clone each one of the objects pointed to by
the <B>Vector</B>. You’d have to do something similar to this to do a deep
copy of a <B>Hashtable</B>.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">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="_Toc375545429"></A><A NAME="_Toc408018664"></A><BR></P></DIV>
<A NAME="Heading376"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Deep copy via serialization</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">When you consider Java
1.1<A NAME="Index1477"></A> object serialization (introduced in Chapter 10), you
might observe that an object that’s serialized and then deserialized is,
in effect, cloned.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">So why not use
<A NAME="Index1478"></A><A NAME="Index1479"></A>serialization to perform deep
copying? Here’s an example that compares the two approaches by timing
them:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><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(<font color=#004488>"Thing3 can't clone"</font>);
}
<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(<font color=#004488>"Thing4 can't clone"</font>);
}
<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 < 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 < 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 < 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()));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -