﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-PariScamper的java天空-随笔分类-Java SE</title><link>http://www.blogjava.net/PariScamper/category/26373.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 12 Dec 2007 16:40:54 GMT</lastBuildDate><pubDate>Wed, 12 Dec 2007 16:40:54 GMT</pubDate><ttl>60</ttl><item><title>Java Clone机制 (zz)</title><link>http://www.blogjava.net/PariScamper/archive/2007/12/12/167233.html</link><dc:creator>PariScamper</dc:creator><author>PariScamper</author><pubDate>Wed, 12 Dec 2007 06:49:00 GMT</pubDate><guid>http://www.blogjava.net/PariScamper/archive/2007/12/12/167233.html</guid><wfw:comment>http://www.blogjava.net/PariScamper/comments/167233.html</wfw:comment><comments>http://www.blogjava.net/PariScamper/archive/2007/12/12/167233.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/PariScamper/comments/commentRss/167233.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/PariScamper/services/trackbacks/167233.html</trackback:ping><description><![CDATA[<div class="postText">
<h1 style="margin: auto 0cm auto 21.55pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore"><font size="5">1</font> <span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><font size="5"><span style="font-family: 黑体; mso-ascii-font-family: 'Times New Roman'">什么是</span> <span lang="EN-US">Clone</span> <span style="font-family: 黑体; mso-ascii-font-family: 'Times New Roman'">，容易实现吗？</span> </font></h1>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 21pt"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">简单地说，</span> <span lang="EN-US">Clone</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就是对于给定的一个对象实例</span> <span lang="EN-US">o</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，得到另一个对象实例</span> <span lang="EN-US">o&#8217;</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：</span> <span lang="EN-US">o</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">与</span> <span lang="EN-US">o&#8217;</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">型相同（</span> <span lang="EN-US">o.getClass() == o&#8217;.getClass()</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">），内容相同（对于</span> <span lang="EN-US">o/o&#8217;</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的字段</span> <span lang="EN-US">f</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，如果</span> <span lang="EN-US">f</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是基本数据类型，则</span> <span lang="EN-US">o.f == o&#8217;.f</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">；如果</span> <span lang="EN-US">f</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是对象引用，则</span> <span lang="EN-US">o.f == o&#8217;.f</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</span> <span lang="EN-US">o.f</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">指向的对象与</span> <span lang="EN-US">o&#8217;.f</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">指向的对象的内容相同）。通常称</span> <span lang="EN-US">o&#8217;</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为</span> <span lang="EN-US">o</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的克隆或副本。</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">直观上看，似乎很容易为一个类加上</span> <span lang="EN-US">clone</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法：</span> </p>
<table class="MsoTableGrid" style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr style="mso-yfti-irow: 0; mso-yfti-lastrow: yes">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt" valign="top" width="568">
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span lang="EN-US">class A {</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>private Type1 field1;</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>private Type2 field2;</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </span>&#8230;..</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>public Object clone() {</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span lang="EN-US"><span style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>A a = new A();</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>a.field1 = a.getField1();</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>a.field2 = a.getField2();</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&#8230;&#8230;</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return a;</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span lang="EN-US">}</span> </p>
            </td>
        </tr>
    </tbody>
</table>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><o:p>&nbsp;</o:p> </span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">然而，稍加推敲，就会发现这样的实现方法有两个问题：</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 42pt; text-indent: -21pt; mso-list: l0 level2 lfo2; tab-stops: list 42.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">要想某个类有</span> <span lang="EN-US">clone</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">功能，必须单独为其实现</span> <span lang="EN-US">clone()</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数，函数实现代码与该类定义密切相关。</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 42pt; text-indent: -21pt; mso-list: l0 level2 lfo2; tab-stops: list 42.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">即使基类</span> <span lang="EN-US">A</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">已有</span> <span lang="EN-US">clone()</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数，其子类</span> <span lang="EN-US">ExtendA</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">若要具备</span> <span lang="EN-US">clone</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">功能，则必须</span> <span lang="EN-US">override</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">其基类</span> <span lang="EN-US">A</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span> <span lang="EN-US">clone()</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数。否则，对类型为</span> <span lang="EN-US">ExtendA</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的对象</span> <span lang="EN-US">ea</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span> <span lang="EN-US">clone()</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法的调用，会执行于类</span> <span lang="EN-US">A</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中定义的</span> <span lang="EN-US">clone()</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法而返回一个类型为</span> <span lang="EN-US">A</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的对象，它显然不是</span> <span lang="EN-US">ea</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的克隆。</span> </p>
<h1 style="margin: auto 0cm auto 21.55pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore"><font size="5">2</font> <span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><font size="5"><span lang="EN-US">Java</span> <span style="font-family: 黑体; mso-ascii-font-family: 'Times New Roman'">对</span> <span lang="EN-US">clone</span> <span style="font-family: 黑体; mso-ascii-font-family: 'Times New Roman'">的支持</span> </font></h1>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 21pt"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">万类之初的</span> <span lang="EN-US">Object</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类有</span> <span lang="EN-US">clone()</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法：</span> </p>
<table class="MsoTableGrid" style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr style="mso-yfti-irow: 0; mso-yfti-lastrow: yes">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt" valign="top" width="568">
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US">protected native Object clone() throws CloneNotSupportedException;</span> </p>
            </td>
        </tr>
    </tbody>
</table>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 21pt"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">该方法是</span> <span lang="EN-US">protected</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的，显然是留待被子类</span> <span lang="EN-US">override</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的。该方法又是</span> <span lang="EN-US">native</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的，必然做了</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">与具体平台相关的底层工作。</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 21pt"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">事实上，类</span> <span lang="EN-US">Object</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span> <span lang="EN-US">clone()</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法首先会检查</span> <span lang="EN-US">this.getClass()</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是否实现了</span> <span lang="EN-US">Cloneable</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口。</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US">Cloneable</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">只是一个标志接口而已，用来标志该类是否有克隆功能。</span> </p>
<table class="MsoTableGrid" style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr style="mso-yfti-irow: 0; mso-yfti-lastrow: yes">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt" valign="top" width="568">
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none" align="left"><strong><span lang="EN-US" style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'; mso-font-kerning: 0pt">public</span> </strong><strong><span lang="EN-US" style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'; mso-font-kerning: 0pt">interface</span> </strong><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'; mso-font-kerning: 0pt"><span style="background: silver; mso-highlight: silver">Cloneable</span> { </span><span lang="EN-US" style="font-size: 10pt; font-family: 'Courier New'; mso-font-kerning: 0pt"><o:p></o:p></span></p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'; mso-font-kerning: 0pt">}</span> </p>
            </td>
        </tr>
    </tbody>
</table>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果</span> <span lang="EN-US">this.getClass()</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">没有实现</span> <span lang="EN-US">Cloneable</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口，</span> <span lang="EN-US">clone()</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就会抛</span> <span lang="EN-US">CloneNotSupportedException</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">返回。否则就会创建一个类型为</span> <span lang="EN-US">this.getClass()</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的对象</span> <span lang="EN-US">other</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，并将</span> <span lang="EN-US">this</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">各</span> <span lang="EN-US">field</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的值赋值给</span> <span lang="EN-US">other</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的对应</span> <span lang="EN-US">field</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，然后返回</span> <span lang="EN-US">other</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如此一来，我们要定义一个具有</span> <span lang="EN-US">Clone</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">功能的类就相当方便：</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 42pt; text-indent: -21pt; mso-list: l2 level1 lfo3; tab-stops: list 42.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在类的声明中加入&#8220;</span> <span lang="EN-US">implements Cloneable</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8221;，标志该类有克隆功能；</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 42pt; text-indent: -21pt; mso-list: l2 level1 lfo3; tab-stops: list 42.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span lang="EN-US">Override</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类</span> <span lang="EN-US">Object</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span> <span lang="EN-US">clone()</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法，在该方法中调用</span> <span lang="EN-US">super.clone()</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：</span> </p>
<table class="MsoTableGrid" style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr style="mso-yfti-irow: 0; mso-yfti-lastrow: yes">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt" valign="top" width="568">
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US">class CloneableClass implements Cloneable {</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&#8230;&#8230;</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21.75pt"><span lang="EN-US">public Object clone() {</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21.75pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>try {</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21.75pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return super.clone();</span> <span lang="EN-US" style="font-size: 9pt; color: red">//</span> <span style="font-size: 9pt; color: red; font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">直接让</span> <span lang="EN-US" style="font-size: 9pt; color: red">Object.clone()</span> <span style="font-size: 9pt; color: red; font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为我们代劳一切</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21.75pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>} catch (CloneNotSupportedException e) {</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21.75pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>throw new InternalError();</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21.75pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21.75pt"><span lang="EN-US">}</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US">}</span> </p>
            </td>
        </tr>
    </tbody>
</table>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><o:p>&nbsp;</o:p> </span></p>
<h1 style="margin: auto 0cm auto 21.55pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore"><font size="5">3</font> <span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><font size="5"><span lang="EN-US">Shallow Clone</span> <span style="font-family: 黑体; mso-ascii-font-family: 'Times New Roman'">与</span> <span lang="EN-US">Deep Clone</span> </font></h1>
<h2 style="margin: 13pt 0cm 13pt 28.8pt"><span lang="EN-US" style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><span style="mso-list: Ignore"><font face="Arial">3.1</font> <span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp; </span></span></span><span lang="EN-US"><font face="Arial">Shallow</font> </span><span style="font-family: 黑体; mso-ascii-font-family: Arial">与</span> <span lang="EN-US"><font face="Arial">Deep</font> </span><span style="font-family: 黑体; mso-ascii-font-family: Arial">从何而来</span> <span lang="EN-US"><o:p></o:p></span></h2>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 21pt"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一个具有克隆功能的类，如果有可变（</span> <span lang="EN-US">Mutable</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）类类型的字段</span> <span lang="EN-US">field</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，如何为其克隆（副</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">本）对象</span> <span lang="EN-US">o&#8217;</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的</span> <span lang="EN-US">field</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">赋值？</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法一、如</span> <span lang="EN-US">Object</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span> <span lang="EN-US">clone()</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法所实现：设原始对象为</span> <span lang="EN-US">o</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，其克隆对象是</span> <span lang="EN-US">o&#8217;</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，执行</span> <span lang="EN-US">o&#8217;.field = o.field</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。这样，</span> <span lang="EN-US">o&#8217;.field</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">与</span> <span lang="EN-US">o.field</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">指向同一个可变对象</span> <span lang="EN-US">m</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span> <span lang="EN-US">o</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">与</span> <span lang="EN-US">o&#8217;</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可能会相互影响（一个对象的状态可能会随着另一个对象的状态的改变而改变）。这样的</span> <span lang="EN-US">Clone</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">称为</span> <span lang="EN-US">Shallow Clone</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。这也是</span> <span lang="EN-US">Object</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span> <span lang="EN-US">clone()</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法的实现方式。</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法二、将</span> <span lang="EN-US">o.field</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">指向的可变对象</span> <span lang="EN-US">m</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">克隆，得到</span> <span lang="EN-US">m&#8217;</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，将</span> <span lang="EN-US">m&#8217;</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的引用赋值给</span> <span lang="EN-US">o&#8217;.field</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。这样</span> <span lang="EN-US">o&#8217;</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">与</span> <span lang="EN-US">o</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内容相同，且相互之间无影响（一个对象状态的改变不会影响另一个对象的状态）。这样的</span> <span lang="EN-US">Clone</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">称为</span> <span lang="EN-US">Deep Clone</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Java Collection</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类库中具体数据结构类（</span> <span lang="EN-US">ArrayList/LinkedList</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</span> <span lang="EN-US">HashSet/TreeSet</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</span> <span lang="EN-US">HashMap/TreeMap</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">等）都具有克隆功能，且都是</span> <span lang="EN-US">Shallow Clone</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，这样设计是合理的，因为它们不知道存放其中的每个数据对象是否也有克隆功能。</span> <span lang="EN-US">System.arrayCopy()</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的实现采用的也是</span> <span lang="EN-US">Shallow Clone</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Deep Clone</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对于实现不可变（</span> <span lang="EN-US">Immutable</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）类很有帮助。设一个类包含可变类</span> <span lang="EN-US">M</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类型的</span> <span lang="EN-US">field</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，如何将其设计为不可变类呢？先为</span> <span lang="EN-US">M</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">实现</span> <span lang="EN-US">Deep Clone</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">功能，然后这样设计类</span> <span lang="EN-US">ImmutableClass</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：</span> </p>
<table class="MsoTableGrid" style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr style="mso-yfti-irow: 0; mso-yfti-lastrow: yes">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt" valign="top" width="568">
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US">class ImmutableClass {</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>MutableClass m;</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21.75pt"><span lang="EN-US">ImmutableClass(MutableClass m) {</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21.75pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>this.m = m.clone(); </span><span lang="EN-US" style="font-size: 9pt; color: red">//</span> <span style="font-size: 9pt; color: red; font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将传入的</span> <span lang="EN-US" style="font-size: 9pt; color: red">m</span> <span style="font-size: 9pt; color: red; font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span> <span lang="EN-US" style="font-size: 9pt; color: red">clone</span> <span style="font-size: 9pt; color: red; font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">赋值给内部</span> <span lang="EN-US" style="font-size: 9pt; color: red">m</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21.75pt"><span lang="EN-US">}</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21.75pt"><span lang="EN-US">public MutableClass getM() {</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21.75pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>return this.m.clone(); </span><span lang="EN-US" style="font-size: 9pt; color: red">//</span> <span style="font-size: 9pt; color: red; font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将内部</span> <span lang="EN-US" style="font-size: 9pt; color: red">m</span> <span style="font-size: 9pt; color: red; font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span> <span lang="EN-US" style="font-size: 9pt; color: red">clone</span> <span style="font-size: 9pt; color: red; font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">返回给外部</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21.75pt"><span lang="EN-US">}</span> </p>
            <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US">}</span> </p>
            </td>
        </tr>
    </tbody>
</table>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><o:p>&nbsp;</o:p> </span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<h2 style="margin: 13pt 0cm 13pt 28.8pt"><span lang="EN-US" style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><span style="mso-list: Ignore"><font face="Arial">3.2</font> <span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 黑体; mso-ascii-font-family: Arial">如何实现</span> <span lang="EN-US"><font face="Arial">Deep Clone</font> </span></h2>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">检查类有无可变类类型的字段。如果无，返回</span> <span lang="EN-US">super.clone()</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">即可；</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果有，确保包含的可变类本身都实现了</span> <span lang="EN-US">Deep Clone</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">；</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span lang="EN-US">Object o = super.clone(); </span><span lang="EN-US" style="font-size: 9pt; color: red">//</span> <span style="font-size: 9pt; color: red; font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">先执行浅克隆，确保类型正确和基本类型及非可变类类型字段内容正确</span> <span lang="EN-US" style="font-size: 9pt; color: red"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt">对于每一个可变类类型的字段</span> <span lang="EN-US" style="mso-bidi-font-size: 10.5pt">field</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt">：</span> <span lang="EN-US" style="mso-bidi-font-size: 10.5pt"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span lang="EN-US" style="mso-bidi-font-size: 10.5pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>o.field = this.getField().clone();<o:p></o:p></span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt">返回</span> <span lang="EN-US" style="mso-bidi-font-size: 10.5pt">o</span> <span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt">。</span> <span lang="EN-US" style="mso-bidi-font-size: 10.5pt"><o:p></o:p></span></p>
</div>
<img src ="http://www.blogjava.net/PariScamper/aggbug/167233.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/PariScamper/" target="_blank">PariScamper</a> 2007-12-12 14:49 <a href="http://www.blogjava.net/PariScamper/archive/2007/12/12/167233.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一篇不错的讲解Java异常的文章(转载）----感觉很不错，读了以后很有启发 </title><link>http://www.blogjava.net/PariScamper/archive/2007/10/15/152961.html</link><dc:creator>PariScamper</dc:creator><author>PariScamper</author><pubDate>Mon, 15 Oct 2007 05:09:00 GMT</pubDate><guid>http://www.blogjava.net/PariScamper/archive/2007/10/15/152961.html</guid><wfw:comment>http://www.blogjava.net/PariScamper/comments/152961.html</wfw:comment><comments>http://www.blogjava.net/PariScamper/archive/2007/10/15/152961.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/PariScamper/comments/commentRss/152961.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/PariScamper/services/trackbacks/152961.html</trackback:ping><description><![CDATA[<p><span style="font-size: 12pt">六种异常处理的陋习</span></p>
<p><span style="font-size: 12pt">你觉得自己是一个Java专家吗？是否肯定自己已经全面掌握了Java的异常处理机制？在下面这段代码中，你能够迅速找出异常处理的六个问题吗？ <br />
<br />
</span></p>
<table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1">
    <tbody>
        <tr>
            <td><span style="font-size: 12pt">1 OutputStreamWriter out = ... <br />
            2 java.sql.Connection conn = ... <br />
            3 try { // ⑸ <br />
            4 　Statement stat = conn.createStatement(); <br />
            5 　ResultSet rs = stat.executeQuery( <br />
            6 　　"select uid, name from user"); <br />
            7 　while (rs.next()) <br />
            8 　{ <br />
            9 　　out.println("ID：" + rs.getString("uid") // ⑹ <br />
            10 　　　"，姓名：" + rs.getString("name")); <br />
            11 　} <br />
            12 　conn.close(); // ⑶ <br />
            13 　out.close(); <br />
            14 } <br />
            15 catch(Exception ex) // ⑵ <br />
            16 { <br />
            17 　ex.printStackTrace(); //⑴，⑷ <br />
            18 }</span></td>
        </tr>
    </tbody>
</table>
<p><br />
<span style="font-size: 12pt">　　作为一个Java程序员，你至少应该能够找出两个问题。但是，如果你不能找出全部六个问题，请继续阅读本文。 <br />
<br />
　　本文讨论的不是Java异常处理的一般性原则，因为这些原则已经被大多数人熟知。我们要做的是分析各种可称为&#8220;反例&#8221;（anti-pattern）的违背优秀编码规范的常见坏习惯，帮助读者熟悉这些典型的反面例子，从而能够在实际工作中敏锐地察觉和避免这些问题。 <br />
<br />
　　<strong>反例之一：丢弃异常 </strong><br />
<br />
　　代码：15行-18行。 <br />
<br />
　　这段代码捕获了异常却不作任何处理，可以算得上Java编程中的杀手。从问题出现的频繁程度和祸害程度来看，它也许可以和C/C++程序的一个恶名远播的问题相提并论??不检查缓冲区是否已满。如果你看到了这种丢弃（而不是抛出）异常的情况，可以百分之九十九地肯定代码存在问题（在极少数情况下，这段代码有存在的理由，但最好加上完整的注释，以免引起别人误解）。 <br />
<br />
　　这段代码的错误在于，异常（几乎）总是意味着某些事情不对劲了，或者说至少发生了某些不寻常的事情，我们不应该对程序发出的求救信号保持沉默和无动于衷。调用一下printStackTrace算不上&#8220;处理异常&#8221;。不错，调用printStackTrace对调试程序有帮助，但程序调试阶段结束之后，printStackTrace就不应再在异常处理模块中担负主要责任了。 <br />
<br />
　　丢弃异常的情形非常普遍。打开JDK的ThreadDeath类的文档，可以看到下面这段说明：&#8220;特别地，虽然出现ThreadDeath是一种&#8216;正常的情形&#8217;，但ThreadDeath类是Error而不是Exception的子类，因为许多应用会捕获所有的Exception然后丢弃它不再理睬。&#8221;这段话的意思是，虽然ThreadDeath代表的是一种普通的问题，但鉴于许多应用会试图捕获所有异常然后不予以适当的处理，所以JDK把ThreadDeath定义成了Error的子类，因为Error类代表的是一般的应用不应该去捕获的严重问题。可见，丢弃异常这一坏习惯是如此常见，它甚至已经影响到了Java本身的设计。 <br />
<br />
　　那么，应该怎样改正呢？主要有四个选择： <br />
<br />
　　1、处理异常。针对该异常采取一些行动，例如修正问题、提醒某个人或进行其他一些处理，要根据具体的情形确定应该采取的动作。再次说明，调用printStackTrace算不上已经&#8220;处理好了异常&#8221;。 <br />
<br />
　　2、重新抛出异常。处理异常的代码在分析异常之后，认为自己不能处理它，重新抛出异常也不失为一种选择。 <br />
<br />
　　3、把该异常转换成另一种异常。大多数情况下，这是指把一个低级的异常转换成应用级的异常（其含义更容易被用户了解的异常）。 <br />
<br />
　　4、不要捕获异常。 <br />
<br />
　　结论一：既然捕获了异常，就要对它进行适当的处理。不要捕获异常之后又把它丢弃，不予理睬。 <br />
<br />
　　<strong>反例之二：不指定具体的异常 </strong><br />
<br />
　　代码：15行。 <br />
<br />
　　许多时候人们会被这样一种&#8220;美妙的&#8221;想法吸引：用一个catch语句捕获所有的异常。最常见的情形就是使用catch(Exception ex)语句。但实际上，在绝大多数情况下，这种做法不值得提倡。为什么呢？ <br />
<br />
　　要理解其原因，我们必须回顾一下catch语句的用途。catch语句表示我们预期会出现某种异常，而且希望能够处理该异常。异常类的作用就是告诉Java编译器我们想要处理的是哪一种异常。由于绝大多数异常都直接或间接从java.lang.Exception派生，catch(Exception ex)就相当于说我们想要处理几乎所有的异常。 <br />
<br />
　　再来看看前面的代码例子。我们真正想要捕获的异常是什么呢？最明显的一个是SQLException，这是JDBC操作中常见的异常。另一个可能的异常是IOException，因为它要操作OutputStreamWriter。显然，在同一个catch块中处理这两种截然不同的异常是不合适的。如果用两个catch块分别捕获SQLException和IOException就要好多了。这就是说，catch语句应当尽量指定具体的异常类型，而不应该指定涵盖范围太广的Exception类。 <br />
<br />
　　另一方面，除了这两个特定的异常，还有其他许多异常也可能出现。例如，如果由于某种原因，executeQuery返回了null，该怎么办？答案是让它们继续抛出，即不必捕获也不必处理。实际上，我们不能也不应该去捕获可能出现的所有异常，程序的其他地方还有捕获异常的机会??直至最后由JVM处理。 <br />
<br />
　　结论二：在catch语句中尽可能指定具体的异常类型，必要时使用多个catch。不要试图处理所有可能出现的异常。 <br />
<br />
　　<strong>反例之三：占用资源不释放 </strong><br />
<br />
　　代码：3行-14行。 <br />
<br />
　　异常改变了程序正常的执行流程。这个道理虽然简单，却常常被人们忽视。如果程序用到了文件、Socket、JDBC连接之类的资源，即使遇到了异常，也要正确释放占用的资源。为此，Java提供了一个简化这类操作的关键词finally。 <br />
<br />
　　finally是样好东西：不管是否出现了异常，Finally保证在try/catch/finally块结束之前，执行清理任务的代码总是有机会执行。遗憾的是有些人却不习惯使用finally。 <br />
<br />
　　当然，编写finally块应当多加小心，特别是要注意在finally块之内抛出的异常??这是执行清理任务的最后机会，尽量不要再有难以处理的错误。 <br />
<br />
　　结论三：保证所有资源都被正确释放。充分运用finally关键词。</span></p>
<p><font size="2"><span style="font-size: 12pt"><strong>反例之四：不说明异常的详细信息 <br />
<br />
</strong>　　代码：3行-18行。 <br />
<br />
　　仔细观察这段代码：如果循环内部出现了异常，会发生什么事情？我们可以得到足够的信息判断循环内部出错的原因吗？不能。我们只能知道当前正在处理的类发生了某种错误，但却不能获得任何信息判断导致当前错误的原因。 <br />
<br />
　　printStackTrace的堆栈跟踪功能显示出程序运行到当前类的执行流程，但只提供了一些最基本的信息，未能说明实际导致错误的原因，同时也不易解读。 <br />
<br />
　　因此，在出现异常时，最好能够提供一些文字信息，例如当前正在执行的类、方法和其他状态信息，包括以一种更适合阅读的方式整理和组织printStackTrace提供的信息。 <br />
<br />
　　结论四：在异常处理模块中提供适量的错误原因信息，组织错误信息使其易于理解和阅读。 <br />
<br />
　　<strong>反例之五：过于庞大的try块 </strong><br />
<br />
　　代码：3行-14行。 <br />
<br />
　　经常可以看到有人把大量的代码放入单个try块，实际上这不是好习惯。这种现象之所以常见，原因就在于有些人图省事，不愿花时间分析一大块代码中哪几行代码会抛出异常、异常的具体类型是什么。把大量的语句装入单个巨大的try块就象是出门旅游时把所有日常用品塞入一个大箱子，虽然东西是带上了，但要找出来可不容易。 <br />
<br />
　　一些新手常常把大量的代码放入单个try块，然后再在catch语句中声明Exception，而不是分离各个可能出现异常的段落并分别捕获其异常。这种做法为分析程序抛出异常的原因带来了困难，因为一大段代码中有太多的地方可能抛出Exception。 <br />
<br />
　　结论五：尽量减小try块的体积。 <br />
<br />
　　<strong>反例之六：输出数据不完整</strong> <br />
<br />
　　代码：7行-11行。 <br />
<br />
　　不完整的数据是Java程序的隐形杀手。仔细观察这段代码，考虑一下如果循环的中间抛出了异常，会发生什么事情。循环的执行当然是要被打断的，其次，catch块会执行??就这些，再也没有其他动作了。已经输出的数据怎么办？使用这些数据的人或设备将收到一份不完整的（因而也是错误的）数据，却得不到任何有关这份数据是否完整的提示。对于有些系统来说，数据不完整可能比系统停止运行带来更大的损失。 <br />
<br />
　　较为理想的处置办法是向输出设备写一些信息，声明数据的不完整性；另一种可能有效的办法是，先缓冲要输出的数据，准备好全部数据之后再一次性输出。 <br />
<br />
　　结论六：全面考虑可能出现的异常以及这些异常对执行流程的影响。 <br />
<br />
　　<strong>改写后的代码</strong> <br />
<br />
　　根据上面的讨论，下面给出改写后的代码。也许有人会说它稍微有点?嗦，但是它有了比较完备的异常处理机制。 <br />
<br />
</span></font>
<table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1">
    <tbody>
        <tr>
            <td><span style="font-size: 12pt">OutputStreamWriter out = ... <br />
            java.sql.Connection conn = ... <br />
            try { <br />
            　Statement stat = conn.createStatement(); <br />
            　ResultSet rs = stat.executeQuery( <br />
            　　"select uid, name from user"); <br />
            　while (rs.next()) <br />
            　{ <br />
            　　out.println("ID：" + rs.getString("uid") + "，姓名: " + rs.getString("name")); <br />
            　} <br />
            } <br />
            catch(SQLException sqlex) <br />
            { <br />
            　out.println("警告：数据不完整"); <br />
            　throw new ApplicationException("读取数据时出现SQL错误", sqlex); <br />
            } <br />
            catch(IOException ioex) <br />
            { <br />
            　throw new ApplicationException("写入数据时出现IO错误", ioex); <br />
            } <br />
            finally <br />
            { <br />
            　if (conn != null) { <br />
            　　try { <br />
            　　　conn.close(); <br />
            　　} <br />
            　　catch(SQLException sqlex2) <br />
            　　{ <br />
            　　　System.err(this.getClass().getName() + ".mymethod - 不能关闭数据库连接: " + sqlex2.toString()); <br />
            　　} <br />
            　} <br />
            <br />
            　if (out != null) { <br />
            　　try { <br />
            　　　out.close(); <br />
            　　} <br />
            　　catch(IOException ioex2) <br />
            　　{ <br />
            　　　System.err(this.getClass().getName() + ".mymethod - 不能关闭输出文件" + ioex2.toString()); <br />
            　　} <br />
            　} <br />
            } </span></td>
        </tr>
    </tbody>
</table>
<br />
<span style="font-size: 12pt">　　本文的结论不是放之四海皆准的教条，有时常识和经验才是最好的老师。如果你对自己的做法没有百分之百的信心，务必加上详细、全面的注释。 <br />
<br />
　　另一方面，不要笑话这些错误，不妨问问你自己是否真地彻底摆脱了这些坏习惯。即使最有经验的程序员偶尔也会误入歧途，原因很简单，因为它们确确实实带来了&#8220;方便&#8221;。所有这些反例都可以看作Java编程世界的恶魔，它们美丽动人，无孔不入，时刻诱惑着你。也许有人会认为这些都属于鸡皮蒜毛的小事，不足挂齿，但请记住：勿以恶小而为之，勿以善小而不为。<br />
<br />
<br />
<br />
<br />
<br />
------------------------------------------------------------------下面是一些java异常集-------------------------------------------------------------------------------------------</span></p>
<br />
<p><span style="font-size: 12pt">算术异常类：ArithmeticExecption</span></p>
<p><span style="font-size: 12pt">空指针异常类：NullPointerException</span></p>
<p><span style="font-size: 12pt">类型强制转换异常：ClassCastException</span></p>
<p><span style="font-size: 12pt">数组负下标异常：NegativeArrayException</span></p>
<p><span style="font-size: 12pt">数组下标越界异常：ArrayIndexOutOfBoundsException</span></p>
<p><span style="font-size: 12pt">违背安全原则异常：SecturityException</span></p>
<p><span style="font-size: 12pt">文件已结束异常：EOFException</span></p>
<p><span style="font-size: 12pt">文件未找到异常：FileNotFoundException</span></p>
<p><span style="font-size: 12pt">字符串转换为数字异常：NumberFormatException</span></p>
<p><br />
<span style="font-size: 12pt">操作数据库异常：SQLException</span></p>
<p><br />
<span style="font-size: 12pt">输入输出异常：IOException</span></p>
<p><br />
<span style="font-size: 12pt">方法未找到异常：NoSuchMethodException</span></p>
<p><span style="font-size: 12pt">java.lang.AbstractMethodError</span></p>
<p><span style="font-size: 12pt">抽象方法错误。当应用试图调用抽象方法时抛出。</span></p>
<p><span style="font-size: 12pt">java.lang.AssertionError</span></p>
<p><span style="font-size: 12pt">断言错。用来指示一个断言失败的情况。</span></p>
<p><span style="font-size: 12pt">java.lang.ClassCircularityError</span></p>
<p><span style="font-size: 12pt">类循环依赖错误。在初始化一个类时，若检测到类之间循环依赖则抛出该异常。</span></p>
<p><span style="font-size: 12pt">java.lang.ClassFormatError</span></p>
<p><span style="font-size: 12pt">类格式错误。当Java虚拟机试图从一个文件中读取Java类，而检测到该文件的内容不符合类的有效格式时抛出。</span></p>
<p><span style="font-size: 12pt">java.lang.Error</span></p>
<p><span style="font-size: 12pt">错误。是所有错误的基类，用于标识严重的程序运行问题。这些问题通常描述一些不应被应用程序捕获的反常情况。</span></p>
<p><span style="font-size: 12pt">java.lang.ExceptionInInitializerError</span></p>
<p><span style="font-size: 12pt">初始化程序错误。当执行一个类的静态初始化程序的过程中，发生了异常时抛出。静态初始化程序是指直接包含于类中的static语句段。</span></p>
<p><span style="font-size: 12pt">java.lang.IllegalAccessError</span></p>
<p><span style="font-size: 12pt">违法访问错误。当一个应用试图访问、修改某个类的域（Field）或者调用其方法，但是又违反域或方法的可见性声明，则抛出该异常。</span></p>
<p><span style="font-size: 12pt">java.lang.IncompatibleClassChangeError</span></p>
<p><span style="font-size: 12pt">不兼容的类变化错误。当正在执行的方法所依赖的类定义发生了不兼容的改变时，抛出该异常。一般在修改了应用中的某些类的声明定义而没有对整个应用重新编译而直接运行的情况下，容易引发该错误。</span></p>
<p><span style="font-size: 12pt">java.lang.InstantiationError</span></p>
<p><span style="font-size: 12pt">实例化错误。当一个应用试图通过Java的new操作符构造一个抽象类或者接口时抛出该异常.</span></p>
<p><span style="font-size: 12pt">java.lang.InternalError</span></p>
<p><span style="font-size: 12pt">内部错误。用于指示Java虚拟机发生了内部错误。</span></p>
<p><span style="font-size: 12pt">java.lang.LinkageError</span></p>
<p><span style="font-size: 12pt">链接错误。该错误及其所有子类指示某个类依赖于另外一些类，在该类编译之后，被依赖的类改变了其类定义而没有重新编译所有的类，进而引发错误的情况。</span></p>
<p><span style="font-size: 12pt">java.lang.NoClassDefFoundError</span></p>
<p><span style="font-size: 12pt">未找到类定义错误。当Java虚拟机或者类装载器试图实例化某个类，而找不到该类的定义时抛出该错误。</span></p>
<p><span style="font-size: 12pt">java.lang.NoSuchFieldError</span></p>
<p><span style="font-size: 12pt">域不存在错误。当应用试图访问或者修改某类的某个域，而该类的定义中没有该域的定义时抛出该错误。</span></p>
<p><span style="font-size: 12pt">java.lang.NoSuchMethodError</span></p>
<p><span style="font-size: 12pt">方法不存在错误。当应用试图调用某类的某个方法，而该类的定义中没有该方法的定义时抛出该错误。</span></p>
<p><span style="font-size: 12pt">java.lang.OutOfMemoryError</span></p>
<p><span style="font-size: 12pt">内存不足错误。当可用内存不足以让Java虚拟机分配给一个对象时抛出该错误。</span></p>
<p><span style="font-size: 12pt">java.lang.StackOverflowError</span></p>
<p><span style="font-size: 12pt">堆栈溢出错误。当一个应用递归调用的层次太深而导致堆栈溢出时抛出该错误。</span></p>
<p><span style="font-size: 12pt">java.lang.ThreadDeath</span></p>
<p><span style="font-size: 12pt">线程结束。当调用Thread类的stop方法时抛出该错误，用于指示线程结束。</span></p>
<p><span style="font-size: 12pt">java.lang.UnknownError</span></p>
<p><span style="font-size: 12pt">未知错误。用于指示Java虚拟机发生了未知严重错误的情况。</span></p>
<p><span style="font-size: 12pt">java.lang.UnsatisfiedLinkError</span></p>
<p><span style="font-size: 12pt">未满足的链接错误。当Java虚拟机未找到某个类的声明为native方法的本机语言定义时抛出。</span></p>
<p><span style="font-size: 12pt">java.lang.UnsupportedClassVersionError</span></p>
<p><span style="font-size: 12pt">不支持的类版本错误。当Java虚拟机试图从读取某个类文件，但是发现该文件的主、次版本号不被当前Java虚拟机支持的时候，抛出该错误。</span></p>
<p><span style="font-size: 12pt">java.lang.VerifyError</span></p>
<p><span style="font-size: 12pt">验证错误。当验证器检测到某个类文件中存在内部不兼容或者安全问题时抛出该错误。</span></p>
<p><span style="font-size: 12pt">java.lang.VirtualMachineError</span></p>
<p><span style="font-size: 12pt">虚拟机错误。用于指示虚拟机被破坏或者继续执行操作所需的资源不足的情况。</span></p>
<p><br />
<span style="font-size: 12pt">java.lang.ArithmeticException</span></p>
<p><span style="font-size: 12pt">算术条件异常。譬如：整数除零等。</span></p>
<p><span style="font-size: 12pt">java.lang.ArrayIndexOutOfBoundsException</span></p>
<p><span style="font-size: 12pt">数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。</span></p>
<p><span style="font-size: 12pt">java.lang.ArrayStoreException</span></p>
<p><span style="font-size: 12pt">数组存储异常。当向数组中存放非数组声明类型对象时抛出。</span></p>
<p><span style="font-size: 12pt">java.lang.ClassCastException</span></p>
<p><span style="font-size: 12pt">类造型异常。假设有类A和B（A不是B的父类或子类），O是A的实例，那么当强制将O构造为类B的实例时抛出该异常。该异常经常被称为强制类型转换异常。</span></p>
<p><span style="font-size: 12pt">java.lang.ClassNotFoundException</span></p>
<p><span style="font-size: 12pt">找不到类异常。当应用试图根据字符串形式的类名构造类，而在遍历CLASSPAH之后找不到对应名称的class文件时，抛出该异常。</span></p>
<p><span style="font-size: 12pt">java.lang.CloneNotSupportedException</span></p>
<p><span style="font-size: 12pt">不支持克隆异常。当没有实现Cloneable接口或者不支持克隆方法时,调用其clone()方法则抛出该异常。</span></p>
<p><span style="font-size: 12pt">java.lang.EnumConstantNotPresentException</span></p>
<p><span style="font-size: 12pt">枚举常量不存在异常。当应用试图通过名称和枚举类型访问一个枚举对象，但该枚举对象并不包含常量时，抛出该异常。</span></p>
<p><span style="font-size: 12pt">java.lang.Exception</span></p>
<p><span style="font-size: 12pt">根异常。用以描述应用程序希望捕获的情况。</span></p>
<p><span style="font-size: 12pt">java.lang.IllegalAccessException</span></p>
<p><span style="font-size: 12pt">违法的访问异常。当应用试图通过反射方式创建某个类的实例、访问该类属性、调用该类方法，而当时又无法访问类的、属性的、方法的或构造方法的定义时抛出该异常。</span></p>
<p><span style="font-size: 12pt">java.lang.IllegalMonitorStateException</span></p>
<p><span style="font-size: 12pt">违法的监控状态异常。当某个线程试图等待一个自己并不拥有的对象（O）的监控器或者通知其他线程等待该对象（O）的监控器时，抛出该异常。</span></p>
<p><span style="font-size: 12pt">java.lang.IllegalStateException</span></p>
<p><span style="font-size: 12pt">违法的状态异常。当在Java环境和应用尚未处于某个方法的合法调用状态，而调用了该方法时，抛出该异常。</span></p>
<p><span style="font-size: 12pt">java.lang.IllegalThreadStateException</span></p>
<p><span style="font-size: 12pt">违法的线程状态异常。当县城尚未处于某个方法的合法调用状态，而调用了该方法时，抛出异常。</span></p>
<p><span style="font-size: 12pt">java.lang.IndexOutOfBoundsException</span></p>
<p><span style="font-size: 12pt">索引越界异常。当访问某个序列的索引值小于0或大于等于序列大小时，抛出该异常。</span></p>
<p><span style="font-size: 12pt">java.lang.InstantiationException</span></p>
<p><span style="font-size: 12pt">实例化异常。当试图通过newInstance()方法创建某个类的实例，而该类是一个抽象类或接口时，抛出该异常。</span></p>
<p><span style="font-size: 12pt">java.lang.InterruptedException</span></p>
<p><span style="font-size: 12pt">被中止异常。当某个线程处于长时间的等待、休眠或其他暂停状态，而此时其他的线程通过Thread的interrupt方法终止该线程时抛出该异常。</span></p>
<p><span style="font-size: 12pt">java.lang.NegativeArraySizeException</span></p>
<p><span style="font-size: 12pt">数组大小为负值异常。当使用负数大小值创建数组时抛出该异常。</span></p>
<p><span style="font-size: 12pt">java.lang.NoSuchFieldException</span></p>
<p><span style="font-size: 12pt">属性不存在异常。当访问某个类的不存在的属性时抛出该异常。</span></p>
<p><span style="font-size: 12pt">java.lang.NoSuchMethodException</span></p>
<p><span style="font-size: 12pt">方法不存在异常。当访问某个类的不存在的方法时抛出该异常。</span></p>
<p><span style="font-size: 12pt">java.lang.NullPointerException</span></p>
<p><span style="font-size: 12pt">空指针异常。当应用试图在要求使用对象的地方使用了null时，抛出该异常。譬如：调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等。</span></p>
<p><span style="font-size: 12pt">java.lang.NumberFormatException</span></p>
<p><span style="font-size: 12pt">数字格式异常。当试图将一个String转换为指定的数字类型，而该字符串确不满足数字类型要求的格式时，抛出该异常。</span></p>
<p><span style="font-size: 12pt">java.lang.RuntimeException</span></p>
<p><span style="font-size: 12pt">运行时异常。是所有Java虚拟机正常操作期间可以被抛出的异常的父类。</span></p>
<p><span style="font-size: 12pt">java.lang.SecurityException</span></p>
<p><span style="font-size: 12pt">安全异常。由安全管理器抛出，用于指示违反安全情况的异常。</span></p>
<p><span style="font-size: 12pt">java.lang.StringIndexOutOfBoundsException</span></p>
<p><span style="font-size: 12pt">字符串索引越界异常。当使用索引值访问某个字符串中的字符，而该索引值小于0或大于等于序列大小时，抛出该异常。</span></p>
<p><span style="font-size: 12pt">java.lang.TypeNotPresentException</span></p>
<p><span style="font-size: 12pt">类型不存在异常。当应用试图以某个类型名称的字符串表达方式访问该类型，但是根据给定的名称又找不到该类型是抛出该异常。该异常与ClassNotFoundException的区别在于该异常是unchecked（不被检查）异常，而ClassNotFoundException是checked（被检查）异常。</span></p>
<p><span style="font-size: 12pt">java.lang.UnsupportedOperationException</span></p>
<p><span style="font-size: 12pt">不支持的方法异常。指明请求的方法不被支持情况的异常。</span></p>
<p><span style="font-size: 12pt">异常<br />
javax.servlet.jsp.JspException: Cannot retrieve mapping for action /Login （/Login是你的action名字）&nbsp;&nbsp; </span></p>
<p><span style="font-size: 12pt">可能原因<br />
action没有再struts-config.xml 中定义，或没有找到匹配的action，例如在JSP文件中使用 &lt;html:form action="Login.do".将表单提交给Login.do处理，如果出现上述异常，请查看struts-config.xml中的定义部分，有时可能是打错了字符或者是某些不符合规则，可以使用strutsconsole工具来检查。<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
org.apache.jasper.JasperException: Cannot retrieve definition for form bean null</span></p>
<p><span style="font-size: 12pt">可能原因&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
这个异常是因为Struts根据struts-config.xml中的mapping没有找到action期望的form bean。大部分的情况可能是因为在form-bean中设置的name属性和action中设置的name属性不匹配所致。换句话说，action和form都应该各自有一个name属性，并且要精确匹配，包括大小写。这个错误当没有name属性和action关联时也会发生，如果没有在action中指定name属性，那么就没有name属性和action相关联。当然当action制作某些控制时，譬如根据参数值跳转到相应的jsp页面，而不是处理表单数据，这是就不用name属性，这也是action的使用方法之一。<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
No action instance for path /xxxx could be created</span></p>
<p><span style="font-size: 12pt">可能原因<br />
特别提示：因为有很多中情况会导致这个错误的发生，所以推荐大家调高你的web服务器的日志/调试级别，这样可以从更多的信息中看到潜在的、在试图创建action类时发生的错误，这个action类你已经在struts-config.xml中设置了关联（即添加了&lt;action&gt;标签）。</span></p>
<p><span style="font-size: 12pt">在struts-config.xml中通过action标签的class属性指定的action类不能被找到有很多种原因，例如：定位编译后的.class文件失败。Failure to place compiled .class file for the action in the classpath (在web开发中，class的的位置在r WEB-INF/classes，所以你的action class必须要在这个目录下。例如你的action类位于WEB-INF/classes/action/Login.class,那么在struts-config.xml中设置action的属性type时就是action.Login).<br />
拼写错误，这个也时有发生，并且不易找到，特别注意第一个字母的大小写和包的名称。 <br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
javax.servlet.jsp.JspException: No getter method for property username of bean org.apache.struts.taglib.html.BEAN</span></p>
<p><span style="font-size: 12pt">可能原因<br />
没有位form bean中的某个变量定义getter 方法</span></p>
<p><span style="font-size: 12pt">这个错误主要发生在表单提交的FormBean中，用struts标记&lt;html:text property=&#8221;username&#8221;&gt;时，在FormBean中必须有一个getUsername()方法。注意字母&#8220;U&#8221;。<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
java.lang.NoClassDefFoundError: org/apache/struts/action/ActionForm</span></p>
<p><span style="font-size: 12pt">可能原因<br />
这个错误主要发生在在classpath中找不到相应的Java .class文件。如果这个错误发生在web应用程序的运行时，主要是因为指定的class文件不在web server的classpath中（/WEB-INF/classes 和 /WEB-INF/lib）。在上面的错误中，原因是找不到ActionForm类。<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
javax.servlet.jsp.JspException: Exception creating bean of class org.apache.struts.action.ActionForm: {1}</span></p>
<p><span style="font-size: 12pt">可能原因<br />
Instantiating Struts-provided ActionForm class directly instead of instantiating a class derived off ActionForm. This mightoccur implicitly if you specify that a form-bean is this Struts ActionForm class rather than specifying a child of this classfor the form-bean.</span></p>
<p><span style="font-size: 12pt">Not associating an ActionForm-descended class with an action can also lead to this error.<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
javax.servlet.jsp.JspException: Cannot find ActionMappings or ActionFormBeans collection</span></p>
<p><span style="font-size: 12pt">可能原因<br />
不是标识Struts actionServlet的&lt;servlet&gt;标记就是映射.do扩展名的&lt;sevlet-mapping&gt;标记或者两者都没有在web.xml中声明。</span></p>
<p><span style="font-size: 12pt">在struts-config.xml中的打字或者拼写错误也可导致这个异常的发生。例如缺少一个标记的关闭符号/&gt;。最好使用struts console工具检查一下。</span></p>
<p><span style="font-size: 12pt">另外，load-on-startup必须在web.xml中声明，这要么是一个空标记，要么指定一个数值，这个数值用来表servlet运行的优先级，数值越大优先级越低。</span></p>
<p><span style="font-size: 12pt">还有一个和使用load-on-startup有关的是使用Struts预编译JSP文件时也可能导致这个异常。<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
java.lang.NullPointerException at org.apache.struts.util.RequestUtils.forwardURL(RequestUtils.java:1223)</span></p>
<p><span style="font-size: 12pt">可能原因<br />
在struts-config.xml中的forward元素缺少path属性。例如应该是如下形式：<br />
&lt;forward name="userhome" path="/user/userhome.jsp"/&gt;<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
javax.servlet.jsp.JspException: Cannot find bean org.apache.struts.taglib.html.BEAN in any scope</span></p>
<p><br />
<span style="font-size: 12pt">&nbsp; </span></p>
<p><span style="font-size: 12pt">Probable Causes<br />
试图在Struts的form标记外使用form的子元素。这常常发生在你在&lt;/html:form&gt;后面使用Struts的html标记。另外要注意可能你不经意使用的无主体的标记，如&lt;html:form &#8230; /&gt;，这样web 服务器解析时就当作一个无主体的标记，随后使用的所有&lt;html&gt;标记都被认为是在这个标记之外的，如又使用了&lt;html:text property=&#8221;id&#8221;&gt;还有就是在使用taglib引入HTML标记库时，你使用的prefix的值不是html。<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
javax.servlet.jsp.JspException: Missing message for key xx.xx.xx</span></p>
<p><span style="font-size: 12pt">Probable Causes<br />
这个key的值对没有在资源文件ApplicationResources.properties中定义。如果你使用eclipse时经常碰到这样的情况，当项目重新编译时，eclipse会自动将classes目录下的资源文件删除。</span></p>
<p><span style="font-size: 12pt">资源文件ApplicationResources.properties 不在classpath中应将资源文件放到 WEB-INF/classes 目录下，当然要在struts-config.xml中定义)<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
Cannot find message resources under key org.apache.struts.action.MESSAGE</span></p>
<p><span style="font-size: 12pt">可能原因<br />
很显然，这个错误是发生在使用资源文件时，而Struts没有找到资源文件。</span></p>
<p><span style="font-size: 12pt">Implicitly trying to use message resources that are not available (such as using empty html:options tag instead of specifyingthe options in its body -- this assumes options are specified in ApplicationResources.properties file)</span></p>
<p><span style="font-size: 12pt">XML parser issues -- too many, too few, incorrect/incompatible versions<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
Strange and seemingly random characters in HTML and on screen, but not in original JSP or servlet.</span></p>
<p><span style="font-size: 12pt">可能原因<br />
混和使用Struts的html:form标记和标准的HTML标记不正确。</span></p>
<p><span style="font-size: 12pt">使用的编码样式在本页中不支持。<br />
-----------------------------------------------------------------------------------------------------------------<br />
异常<br />
"Document contained no data" in Netscape</span></p>
<p><span style="font-size: 12pt">No data rendered (completely empty) page in Microsoft Internet Explorer</span></p>
<p><span style="font-size: 12pt">可能原因<br />
使用一个Action的派生类而没有实现perform()方法或execute()方法。在Struts1.0中实现的是perform()方法，在Struts1.1中实现的是execute()方法，但Struts1.1向后兼容perform()方法。但你使用Struts1.1创建一个Action的派生类，并且实现了execute()方法，而你在Struts1.0中运行的话，就会得到"Document contained nodata" error message in Netscape or a completely empty (no HTML whatsoever) page rendered in Microsoft Internet Explorer.&#8221;的错误信息。</span></p>
<p><span style="font-size: 12pt">---------------------------------------------------------------------------------------------------------------------------<br />
异常<br />
ServletException: BeanUtils.populate<br />
解决方案<br />
在用Struts上传文件时,遇到了javax.servlet.ServletException: BeanUtils.populate异常。<br />
我的ActionServlet并没有用到BeanUtils这些工具类。后来仔细检查代码发现是在jsp文件里的form忘了加enctype=&amp;quot;multipart/form-data&amp;quot; 了。所以写程序遇到错误或异常应该从多方面考虑问题存在的可能性，想到系统提示信息以外的东西。<br />
----------------------------------------------------------------------------------------------------------------------------<br />
1. 定义Action后, 如果指定了name, 那么必须要定义一个与它同名的FormBean才能进行form映射.2. 如果定义Action后, 提交页面时出现 "No input attribute for mapping path..." 错误, 则需要在其input属性中定义转向的页面.3. 如果插入新的数据时出现 "Batch update row count wrong:..." 错误, 则说明XXX.hbm.xml中指定的key的类型为原始类型(int, long),因为这种类型会自动分配值, 而这个值往往会让系统认为已经存在该记录, 正确的方法是使用java.lang.Integer或java.lang.Long对象.4. 如果插入数据时出现 "argument type mismatch" 错误, 可能是你使用了Date等特殊对象, 因为struts不能自动从String型转换成Date型,所以, 你需要在Action中手动把String型转换成Date型.5. Hibernate中, Query的iterator()比list()方法快很多.6. 如果出现 "equal symbol expected" 错误, 说明你的strtus标签中包含另一个标签或者变量, 例如:<br />
&lt;html:select property="test" onchange="&lt;%=test%&gt;"/&gt;<br />
或者<br />
&lt;html:hidden property="test" value="&lt;bean:write name="t" property="p"/&gt;"/&gt;<br />
这样的情况... <br />
---------------------------------------------------------------------------------------------------------------------------<br />
错误：Exception in thread "main" org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update原因与解决：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 因为Hibernate Tools（或者Eclipse本身的Database Explorer）生成*.hbn.xml工具中包含有catalog="***"（*表示数据库名称）这样的属性,将该属性删除就可以了<br />
---------------------------------------------------------------------------------------------------------------------------<br />
错误：org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations)<br />
原因与解决：<br />
方法1 删除Set方的cascade<br />
方法2 解决关联关系后，再删除<br />
方法3 在many-to-one方增加cascade 但值不能是none<br />
最后一招：<br />
检查一下hashCode equals是否使用了id作为唯一标示的选项了；我用uuid.hex时是没有问题的；但是用了native，就不行了，怎么办？删除啊！<br />
----------------------------------------------------------------------------------------------------------------------------<br />
问题：今天用Tomcat 5.5.12，发现原来很好用的系统不能用了，反复测试发现页面中不能包含 taglib，否则会出现以下提示：HTTP Status 500 -type Exception reportMessage description The server encountered an internal error () that prevented it from fulfilling this request.exceptionorg.apache.jasper.JasperException: /index.jsp(1,1) Unable to read TLD "META-INF/tlds/struts-bean.tld" from JAR file"file:*****/WEB-INF/lib/struts.jar":原因：更新了工程用的lib文件夹下的jar，发布时也发布了servlet.jar和jsp-api.jar。解决：把jsp-api.jar删除就解决这个问题了。-----------------------------------------------------------------------------------------------------------------------------<br />
错误： java.lang.NullPointerException<br />
原因： 发现 dao 实例、 manage 实例等需要注入的东西没有被注入（俗称空指针异常）解决：这个时候，你应该查看日志文件；默认是应用服务器的 log 文件，比如 Tomcat 就是 [Tomcat 安装目录 ]/logs ；你会发现提示你：可能是：org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sf' defined in ServletContextresource [/WEB-INF/applicationContext.xml]: Initialization of bean failed; nested exception isorg.hibernate.HibernateException: could not configure from URL: file:src/hibernate.cfg.xmlorg.hibernate.HibernateException: could not configure from URL: file:src/hibernate.cfg.xml&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.Caused by: java.io.FileNotFoundException: src\hibernate.cfg.xml可能是：org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined inServletContext resource [/WEB-INF/applicationContext.xml]: Initialization of bean failed; nested exception isorg.hibernate.MappingException: Resource: com/mcc/coupon/model/UserRole.hbm.xml not foundorg.hibernate.MappingException: Resource: com/mcc/coupon/model/UserRole.hbm.xml not found然后你就知道原因是因为配置文件的解析出了错误，这个通过 Web 页面是看不出来的。更多的是持久化影射文件出的错误；导致了没有被解析；当然你需要的功能就无法使用了。<br />
----------------------------------------------------------------------------------------------------------------------------<br />
错误：StandardWrapperValve[action]: Servlet.service() for servlet action threw exception<br />
javax.servlet.jsp.JspException: Cannot retrieve mapping for action /settlementTypeManage<br />
或者：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type Status report&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; message Servlet action is not available&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; description The requested resource (Servlet action is not available) is not available.<br />
原因： 同 上<br />
----------------------------------------------------------------------------------------------------------------------------<br />
错误StandardWrapperValve[jsp]: Servlet.service() for servlet jsp threw exceptionjava.lang.ClassNotFoundException: org.apache.struts.taglib.bean.CookieTei界面错误具体描述：<br />
org.apache.jasper.JasperException: Failed to load or instantiate TagExtraInfo class: org.apache.struts.taglib.bean.CookieTei<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 原因与解决：&nbsp;&nbsp;&nbsp; &lt;方案一&gt;你的&#8220;html:&#8221;开头的标签没有放在一个&lt;html:form&gt;中&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;方案二&gt;重新启动你的应用服务器，自动就没有这个问题<br />
</span></p>
<img src ="http://www.blogjava.net/PariScamper/aggbug/152961.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/PariScamper/" target="_blank">PariScamper</a> 2007-10-15 13:09 <a href="http://www.blogjava.net/PariScamper/archive/2007/10/15/152961.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java编程规范</title><link>http://www.blogjava.net/PariScamper/archive/2007/10/11/152052.html</link><dc:creator>PariScamper</dc:creator><author>PariScamper</author><pubDate>Thu, 11 Oct 2007 07:24:00 GMT</pubDate><guid>http://www.blogjava.net/PariScamper/archive/2007/10/11/152052.html</guid><wfw:comment>http://www.blogjava.net/PariScamper/comments/152052.html</wfw:comment><comments>http://www.blogjava.net/PariScamper/archive/2007/10/11/152052.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/PariScamper/comments/commentRss/152052.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/PariScamper/services/trackbacks/152052.html</trackback:ping><description><![CDATA[(1) 类名首字母应该大写。字段、方法以及对象（句柄）的首字母应小写。对于所有标识符，其中包含的所有单词都应紧靠在一起，而且大写中间单词的首字母。例如： ThisIsAClassName thisIsMethodOrFieldName 若在定义中出现了常数初始化字符，则大写static final基本类型标识符中的所有字母。这样便可标志出它们属于编译期的常数。 Java包（Package）属于一种特殊情况：它们全都是小写字母，即便中间的单词亦是如此。对于域名扩展名称，如com，org，net或者edu等，全部都应小写（这也是Java 1.1和Java 1.2的区别之一）。 <br />
(2) 为了常规用途而创建一个类时，请采取"经典形式"，并包含对下述元素的定义： equals() <br />
hashCode() <br />
toString() <br />
clone()（implement Cloneable）<br />
implement Serializable <br />
(3) 对于自己创建的每一个类，都考虑置入一个main()，其中包含了用于测试那个类的代码。为使用一个项目中的类，我们没必要删除测试代码。若进行了任何形式的改动，可方便地返回测试。这些代码也可作为如何使用类的一个示例使用。 <br />
(4) 应将方法设计成简要的、功能性单元，用它描述和实现一个不连续的类接口部分。理想情况下，方法应简明扼要。若长度很大，可考虑通过某种方式将其分割成较短的几个方法。这样做也便于类内代码的重复使用（有些时候，方法必须非常大，但它们仍应只做同样的一件事情）。 <br />
(5) 设计一个类时，请设身处地为客户程序员考虑一下（类的使用方法应该是非常明确的）。然后，再设身处地为管理代码的人考虑一下（预计有可能进行哪些形式的修改，想想用什么方法可把它们变得更简单）。 <br />
(6) 使类尽可能短小精悍，而且只解决一个特定的问题。下面是对类设计的一些建议： <br />
■一个复杂的开关语句：考虑采用"多形"机制 <br />
■数量众多的方法涉及到类型差别极大的操作：考虑用几个类来分别实现 <br />
■许多成员变量在特征上有很大的差别：考虑使用几个类 <br />
(7) 让一切东西都尽可能地"私有"--private。可使库的某一部分"公共化"（一个方法、类或者一个字段等等），就永远不能把它拿出。若强行拿出，就可能破坏其他人现有的代码，使他们不得不重新编写和设计。若只公布自己必须公布的，就可放心大胆地改变其他任何东西。在多线程环境中，隐私是特别重要的一个因素--只有private字段才能在非同步使用的情况下受到保护。 <br />
(8) 谨惕"巨大对象综合症"。对一些习惯于顺序编程思维、且初涉OOP领域的新手，往往喜欢先写一个顺序执行的程序，再把它嵌入一个或两个巨大的对象里。根据编程原理，对象表达的应该是应用程序的概念，而非应用程序本身。 <br />
(9) 若不得已进行一些不太雅观的编程，至少应该把那些代码置于一个类的内部。 <br />
(10) 任何时候只要发现类与类之间结合得非常紧密，就需要考虑是否采用内部类，从而改善编码及维护工作（参见第14章14.1.2小节的"用内部类改进代码"）。 <br />
(11) 尽可能细致地加上注释，并用javadoc注释文档语法生成自己的程序文档。 <br />
(12) 避免使用"魔术数字"，这些数字很难与代码很好地配合。如以后需要修改它，无疑会成为一场噩梦，因为根本不知道"100"到底是指"数组大小"还是"其他全然不同的东西"。所以，我们应创建一个常数，并为其使用具有说服力的描述性名称，并在整个程序中都采用常数标识符。这样可使程序更易理解以及更易维护。 <br />
(13) 涉及构建器和异常的时候，通常希望重新丢弃在构建器中捕获的任何异常--如果它造成了那个对象的创建失败。这样一来，调用者就不会以为那个对象已正确地创建，从而盲目地继续。 <br />
(14) 当客户程序员用完对象以后，若你的类要求进行任何清除工作，可考虑将清除代码置于一个良好定义的方法里，采用类似于cleanup()这样的名字，明确表明自己的用途。除此以外，可在类内放置一个boolean（布尔）标记，指出对象是否已被清除。在类的finalize()方法里，请确定对象已被清除，并已丢弃了从RuntimeException继承的一个类（如果还没有的话），从而指出一个编程错误。在采取象这样的方案之前，请确定finalize()能够在自己的系统中工作（可能需要调用System.runFinalizersonExit(true)，从而确保这一行为）。 <br />
(15) 在一个特定的作用域内，若一个对象必须清除（非由垃圾收集机制处理），请采用下述方法：初始化对象；若成功，则立即进入一个含有finally从句的try块，开始清除工作。 <br />
(16) 若在初始化过程中需要覆盖（取消）finalize()，请记住调用super.finalize()（若Object属于我们的直接超类，则无此必要）。在对finalize()进行覆盖的过程中，对super.finalize()的调用应属于最后一个行动，而不应是第一个行动，这样可确保在需要基础类组件的时候它们依然有效。 <br />
(17) 创建大小固定的对象集合时，请将它们传输至一个数组（若准备从一个方法里返回这个集合，更应如此操作）。这样一来，我们就可享受到数组在编译期进行类型检查的好处。此外，为使用它们，数组的接收者也许并不需要将对象"造型"到数组里。 <br />
(18) 尽量使用interfaces，不要使用abstract类。若已知某样东西准备成为一个基础类，那么第一个选择应是将其变成一个interface（接口）。只有在不得不使用方法定义或者成员变量的时候，才需要将其变成一个abstract（抽象）类。接口主要描述了客户希望做什么事情，而一个类则致力于（或允许）具体的实施细节。 <br />
(19) 在构建器内部，只进行那些将对象设为正确状态所需的工作。尽可能地避免调用其他方法，因为那些方法可能被其他人覆盖或取消，从而在构建过程中产生不可预知的结果（参见第7章的详细说明）。 <br />
(20) 对象不应只是简单地容纳一些数据；它们的行为也应得到良好的定义。 <br />
(21) 在现成类的基础上创建新类时，请首先选择"新建"或"创作"。只有自己的设计要求必须继承时，才应考虑这方面的问题。若在本来允许新建的场合使用了继承，则整个设计会变得没有必要地复杂。 <br />
(22) 用继承及方法覆盖来表示行为间的差异，而用字段表示状态间的区别。一个非常极端的例子是通过对不同类的继承来表示颜色，这是绝对应该避免的：应直接使用一个"颜色"字段。 <br />
(23) 为避免编程时遇到麻烦，请保证在自己类路径指到的任何地方，每个名字都仅对应一个类。否则，编译器可能先找到同名的另一个类，并报告出错消息。若怀疑自己碰到了类路径问题，请试试在类路径的每一个起点，搜索一下同名的.class文件。 <br />
(24) 在Java 1.1 AWT中使用事件"适配器"时，特别容易碰到一个陷阱。若覆盖了某个适配器方法，同时拼写方法没有特别讲究，最后的结果就是新添加一个方法，而不是覆盖现成方法。然而，由于这样做是完全合法的，所以不会从编译器或运行期系统获得任何出错提示--只不过代码的工作就变得不正常了。 <br />
(25) 用合理的设计方案消除"伪功能"。也就是说，假若只需要创建类的一个对象，就不要提前限制自己使用应用程序，并加上一条"只生成其中一个"注释。请考虑将其封装成一个"独生子"的形式。若在主程序里有大量散乱的代码，用于创建自己的对象，请考虑采纳一种创造性的方案，将些代码封装起来。 <br />
(26) 警惕"分析瘫痪"。请记住，无论如何都要提前了解整个项目的状况，再去考察其中的细节。由于把握了全局，可快速认识自己未知的一些因素，防止在考察细节的时候陷入"死逻辑"中。 <br />
(27) 警惕"过早优化"。首先让它运行起来，再考虑变得更快--但只有在自己必须这样做、而且经证实在某部分代码中的确存在一个性能瓶颈的时候，才应进行优化。除非用专门的工具分析瓶颈，否则很有可能是在浪费自己的时间。性能提升的隐含代价是自己的代码变得难于理解，而且难于维护。 <br />
(28) 请记住，阅读代码的时间比写代码的时间多得多。思路清晰的设计可获得易于理解的程序，但注释、细致的解释以及一些示例往往具有不可估量的价值。无论对你自己，还是对后来的人，它们都是相当重要的。如对此仍有怀疑，那么请试想自己试图从联机Java文档里找出有用信息时碰到的挫折，这样或许能将你说服。 <br />
(29) 如认为自己已进行了良好的分析、设计或者实施，那么请稍微更换一下思维角度。试试邀请一些外来人士--并不一定是专家，但可以是来自本公司其他部门的人。请他们用完全新鲜的眼光考察你的工作，看看是否能找出你一度熟视无睹的问题。采取这种方式，往往能在最适合修改的阶段找出一些关键性的问题，避免产品发行后再解决问题而造成的金钱及精力方面的损失。 <br />
(30) 良好的设计能带来最大的回报。简言之，对于一个特定的问题，通常会花较长的时间才能找到一种最恰当的解决方案。但一旦找到了正确的方法，以后的工作就轻松多了，再也不用经历数小时、数天或者数月的痛苦挣扎。我们的努力工作会带来最大的回报（甚至无可估量）。而且由于自己倾注了大量心血，最终获得一个出色的设计方案，成功的快感也是令人心动的。坚持抵制草草完工的诱惑--那样做往往得不偿失。
<img src ="http://www.blogjava.net/PariScamper/aggbug/152052.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/PariScamper/" target="_blank">PariScamper</a> 2007-10-11 15:24 <a href="http://www.blogjava.net/PariScamper/archive/2007/10/11/152052.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>