﻿<?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-落雪的梦想</title><link>http://www.blogjava.net/gufen/</link><description /><language>zh-cn</language><lastBuildDate>Wed, 08 Apr 2026 21:03:09 GMT</lastBuildDate><pubDate>Wed, 08 Apr 2026 21:03:09 GMT</pubDate><ttl>60</ttl><item><title>MyEclipse+WebSphere通过JNDI连接Sybase简介</title><link>http://www.blogjava.net/gufen/archive/2006/06/12/52182.html</link><dc:creator>落花飞雪</dc:creator><author>落花飞雪</author><pubDate>Mon, 12 Jun 2006 04:57:00 GMT</pubDate><guid>http://www.blogjava.net/gufen/archive/2006/06/12/52182.html</guid><wfw:comment>http://www.blogjava.net/gufen/comments/52182.html</wfw:comment><comments>http://www.blogjava.net/gufen/archive/2006/06/12/52182.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gufen/comments/commentRss/52182.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gufen/services/trackbacks/52182.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: MyEclipse+WebSphere						通过						JNDI						连接						Sybase						简介																		 																		       								很久不来这里写东西了，一是工作忙，还有就是我是个初学者也写不出什么东西。这几天因工作需要学习了一下...&nbsp;&nbsp;<a href='http://www.blogjava.net/gufen/archive/2006/06/12/52182.html'>阅读全文</a><img src ="http://www.blogjava.net/gufen/aggbug/52182.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gufen/" target="_blank">落花飞雪</a> 2006-06-12 12:57 <a href="http://www.blogjava.net/gufen/archive/2006/06/12/52182.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDK5.0的11个主要新特征</title><link>http://www.blogjava.net/gufen/archive/2005/10/15/15567.html</link><dc:creator>落花飞雪</dc:creator><author>落花飞雪</author><pubDate>Sat, 15 Oct 2005 04:15:00 GMT</pubDate><guid>http://www.blogjava.net/gufen/archive/2005/10/15/15567.html</guid><wfw:comment>http://www.blogjava.net/gufen/comments/15567.html</wfw:comment><comments>http://www.blogjava.net/gufen/archive/2005/10/15/15567.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/gufen/comments/commentRss/15567.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gufen/services/trackbacks/15567.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 泛型(Generic)1.1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 说明增强了java的类型安全，可以在编译期间对容器内的对象进行类型检查，在运行期不必进行类型的转换。而在j2se5之前必须在运行期...&nbsp;&nbsp;<a href='http://www.blogjava.net/gufen/archive/2005/10/15/15567.html'>阅读全文</a><img src ="http://www.blogjava.net/gufen/aggbug/15567.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gufen/" target="_blank">落花飞雪</a> 2005-10-15 12:15 <a href="http://www.blogjava.net/gufen/archive/2005/10/15/15567.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Win32下Swt-Designer4.1.1与MyEclipse4.0的破解方法及注册机</title><link>http://www.blogjava.net/gufen/archive/2005/09/27/14184.html</link><dc:creator>落花飞雪</dc:creator><author>落花飞雪</author><pubDate>Tue, 27 Sep 2005 05:05:00 GMT</pubDate><guid>http://www.blogjava.net/gufen/archive/2005/09/27/14184.html</guid><wfw:comment>http://www.blogjava.net/gufen/comments/14184.html</wfw:comment><comments>http://www.blogjava.net/gufen/archive/2005/09/27/14184.html#Feedback</comments><slash:comments>48</slash:comments><wfw:commentRss>http://www.blogjava.net/gufen/comments/commentRss/14184.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gufen/services/trackbacks/14184.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>Win32</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下</SPAN><SPAN lang=EN-US>Swt-Designer<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><st1:chsdate Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False" w:st="on">4.1.1</st1:chsdate></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>win32</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</SPAN><SPAN lang=EN-US>Eclipse3.1</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</SPAN><SPAN lang=EN-US>Designer_v<st1:chsdate Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False" w:st="on">4.1.1</st1:chsdate></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.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; </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 href="http://www.swt-designer.com/">http://www.swt-designer.com/</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>download</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">菜单点击进去后下载</SPAN><SPAN lang=EN-US>Edition for Eclipse 3.1 &amp; 3.2</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，下载后的文件名为</SPAN><SPAN lang=EN-US>Designer_v<st1:chsdate Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False" w:st="on">4.1.1</st1:chsdate>_for_Eclipse3.1.zip<IMG height=283 alt=Snap2.gif src="http://www.blogjava.net/images/blogjava_net/gufen/001.swt.myeclipse.crack/Snap2.gif" width=606 border=0><BR></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt"><SPAN lang=EN-US><?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><v:shapetype id=_x0000_t75 coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></v:path><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:lock v:ext="edit" aspectratio="t"></o:lock></v:shapetype></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.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; </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 href="http://www.thefilehut.com/userfiles/gufen/forblog/swt.designer.pro.keygen.for.eclipse.3.1.rar">http://www.thefilehut.com/userfiles/gufen/forblog/swt.designer.pro.keygen.for.eclipse.3.1.rar</A></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">3．<SPAN style="FONT: 7pt 'Times New Roman'">&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>cmd</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">命令中敲入</SPAN><SPAN lang=EN-US>swt.ui.bat</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，运行后出现以下界面，输入框中的内容，然后点击</SPAN><SPAN lang=EN-US>Generate</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 18pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><IMG height=241 alt=Snap3.gif src="http://www.blogjava.net/images/blogjava_net/gufen/001.swt.myeclipse.crack/Snap3.gif" width=377 border=0><BR>如果你所使用的环境和版本不是</SPAN><SPAN lang=EN-US>win32</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</SPAN><SPAN lang=EN-US>Eclipse3.1</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</SPAN><SPAN lang=EN-US>Designer_v<st1:chsdate Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False" w:st="on">4.1.1</st1:chsdate></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 href="http://blog.chinaz.com/u1/530/archives/2005/1789.shtml">http://blog.chinaz.com/u1/530/archives/2005/1789.shtml</A></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 45pt; TEXT-INDENT: -9pt; mso-list: l2 level2 lfo2; tab-stops: list 45.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">a)<SPAN style="FONT: 7pt 'Times New Roman'"> </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>org.eclipse.swt.win32.win32.x86_<st1:chsdate Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False" w:st="on">3.1.0</st1:chsdate>.jar</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US>swt-win32-3138.dll</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 45pt; TEXT-INDENT: -9pt; mso-list: l2 level2 lfo2; tab-stops: list 45.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">b)</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>Eclipse</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">目录下找到</SPAN><SPAN lang=EN-US>swt.jar</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（名字视版本而定，</SPAN><SPAN lang=EN-US>eclipse3.1</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下是</SPAN><SPAN lang=EN-US>org.eclipse.swt.win32.win32.x86_<st1:chsdate Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False" w:st="on">3.1.0</st1:chsdate>.jar</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）</SPAN> <SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US>swt-win32-2135.dll</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（名字视版本而定，</SPAN><SPAN lang=EN-US>eclipse3.1</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下是</SPAN><SPAN lang=EN-US>swt-win32-3138.dll</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）</SPAN><SPAN lang=EN-US>2</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个文件，拷贝到</SPAN><SPAN lang=EN-US>swt.ui.bat</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 45pt; TEXT-INDENT: -9pt; mso-list: l2 level2 lfo2; tab-stops: list 45.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">c)</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>swt.ui.bat,</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 36pt; TEXT-INDENT: 21pt; mso-para-margin-left: 3.43gd"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">原来是</SPAN><SPAN lang=EN-US>: start javaw -cp SWTDesigner_<st1:chsdate Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False" w:st="on">2.0.0</st1:chsdate>_Keygen.jar;<SPAN style="COLOR: red">org.eclipse.swt.win32.win32.x86_3.1.0.jar</SPAN> swtdesigner.keygen.SWTUI</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 36pt; TEXT-INDENT: 21pt; mso-para-margin-left: 3.43gd"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">修改为</SPAN><SPAN lang=EN-US>:start javaw -cp SWTDesigner_<st1:chsdate Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False" w:st="on">2.0.0</st1:chsdate>_Keygen.jar;<SPAN style="COLOR: red">swt.jar</SPAN> swtdesigner.keygen.SWTUI</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 36pt; TEXT-INDENT: 21pt; mso-para-margin-left: 3.43gd"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">红色为修改的地方，然后运行后将</SPAN><SPAN lang=EN-US>Version</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">填入你下载的</SPAN><SPAN lang=EN-US>swt-designer</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 18pt"><SPAN lang=EN-US></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l1 level1 lfo3; tab-stops: list 21.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">4.<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>Designer_v<st1:chsdate Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False" w:st="on">4.1.1</st1:chsdate>_for_Eclipse3.1.zip</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">插件安装到</SPAN><SPAN lang=EN-US>eclipse,</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果你不知道如何安装插件请在</SPAN><SPAN lang=EN-US>google</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 21pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">运行</SPAN><SPAN lang=EN-US>eclipse,</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打开</SPAN><SPAN lang=EN-US>window-&gt;preferences…-&gt;</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">选择左边树形中的</SPAN><SPAN lang=EN-US>designer(</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果没有这一项说明</SPAN><SPAN lang=EN-US>swt-designer</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">插件没有安装成功</SPAN><SPAN lang=EN-US>)</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US>-&gt;</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">点击右下的“</SPAN><SPAN lang=EN-US>Registration and Activation</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”</SPAN><SPAN lang=EN-US>-&gt;</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">弹出“</SPAN><SPAN lang=EN-US>Product Registration and Activation</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”框，用默认直接点击</SPAN><SPAN lang=EN-US>Next-&gt;</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这一步需要注意的是</SPAN><SPAN lang=EN-US>Name</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">框中两个字符串之间要有个空格，他会认为一个是姓一个是名，否则</SPAN><SPAN lang=EN-US>Next</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">按钮一直是灰的，其他随便填，</SPAN><SPAN lang=EN-US>email</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">框中要合乎</SPAN><SPAN lang=EN-US>email</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">格式就可以了</SPAN><SPAN lang=EN-US>-&gt;</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">输入破解产生的序列号和激活码</SPAN><SPAN lang=EN-US>-&gt;</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">显示“</SPAN><SPAN lang=EN-US>Activation is complete. Thank you.</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 21pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">现在就可以免费使用</SPAN><SPAN lang=EN-US>swt-designer</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 21pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>Win32</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下</SPAN><SPAN lang=EN-US>MyEclipse4.0</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>http://www.myeclipseide.com</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下载</SPAN><SPAN lang=EN-US>Myeclipse4.0,</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 href="http://www.thefilehut.com/userfiles/gufen/forblog/MyEclipse-4.0.0-GA.Keygen.zip">http://www.thefilehut.com/userfiles/gufen/forblog/MyEclipse-4.0.0-GA.Keygen.zip</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>Myeclipse,</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">之后解压破解文件后运行</SPAN><SPAN lang=EN-US>keygen.bat</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，产生一个</SPAN><SPAN lang=EN-US>key</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，之后在</SPAN><SPAN lang=EN-US>Myeclipse</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">注册一下就可以了。<SPAN lang=EN-US>Myeclipse我忘记什么地方注册了，好像装好<SPAN lang=EN-US>Myeclipse后在preferences中的<SPAN lang=EN-US>Myeclipse里点几下就会弹出来个框，把key copy过去确认就可以了。<BR><BR>以上破解方法仅供个人学习，请支持正版。(形式？)</SPAN></SPAN></SPAN></SPAN></P><img src ="http://www.blogjava.net/gufen/aggbug/14184.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gufen/" target="_blank">落花飞雪</a> 2005-09-27 13:05 <a href="http://www.blogjava.net/gufen/archive/2005/09/27/14184.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>软件设计中的原则</title><link>http://www.blogjava.net/gufen/archive/2005/09/26/14126.html</link><dc:creator>落花飞雪</dc:creator><author>落花飞雪</author><pubDate>Mon, 26 Sep 2005 09:21:00 GMT</pubDate><guid>http://www.blogjava.net/gufen/archive/2005/09/26/14126.html</guid><wfw:comment>http://www.blogjava.net/gufen/comments/14126.html</wfw:comment><comments>http://www.blogjava.net/gufen/archive/2005/09/26/14126.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gufen/comments/commentRss/14126.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gufen/services/trackbacks/14126.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 5.15pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">&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>GoF</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">等软件设计模式高一层。遵循这些原则可以使我们设计出来的软件有更好的可复用性和可维护性，同样</SPAN><SPAN lang=EN-US>GoF</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 5.15pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">&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>Java</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模式》、《</SPAN><SPAN lang=EN-US>UML</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和模式应用</SPAN><SPAN lang=EN-US>-</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 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.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 lang=EN-US>GRASP</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 9pt; TEXT-INDENT: 12pt"><SPAN lang=EN-US>GRASP</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是</SPAN><SPAN lang=EN-US>General Responsibility Assignment Software Pattern(</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通用指责分配软件模式</SPAN><SPAN lang=EN-US>)</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 21pt; TEXT-INDENT: -12pt; mso-list: l2 level1 lfo2; tab-stops: list 21.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; </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>(Expert)</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></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></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; 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 21pt; TEXT-INDENT: -12pt; mso-list: l2 level1 lfo2; tab-stops: list 21.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; </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>(Creator)</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>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>B</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 level2 lfo2; tab-stops: list 42.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">a)<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US>B</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></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l2 level2 lfo2; tab-stops: list 42.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">b)<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US>B</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></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l2 level2 lfo2; tab-stops: list 42.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">c)<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US>B</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></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l2 level2 lfo2; tab-stops: list 42.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">d)<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US>B</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></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l2 level2 lfo2; tab-stops: list 42.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">e)<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>B</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>(</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">也就是说</SPAN><SPAN lang=EN-US>B</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>)</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l2 level2 lfo2; tab-stops: list 42.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">f)<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US>B</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></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>B</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></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></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; 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 21pt; TEXT-INDENT: -12pt; mso-list: l2 level1 lfo2; tab-stops: list 21.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">3)<SPAN style="FONT: 7pt 'Times New Roman'">&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>(High Cohesion)</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></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; 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>(cohesion)</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 21pt; TEXT-INDENT: -12pt; mso-list: l2 level1 lfo2; tab-stops: list 21.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">4)<SPAN style="FONT: 7pt 'Times New Roman'">&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>(Low Coupling)</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></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>(coupling)</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是一个类与其它类关联、知道其他类的信息或者依赖其他类的强弱程度的度量。一个具有低</SPAN><SPAN lang=EN-US>(</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">弱</SPAN><SPAN lang=EN-US>)</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 21pt; TEXT-INDENT: -12pt; mso-list: l2 level1 lfo2; tab-stops: list 21.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">5)<SPAN style="FONT: 7pt 'Times New Roman'">&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>(Controller)</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></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l1 level1 lfo3; tab-stops: list 42.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">a)<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></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l1 level1 lfo3; tab-stops: list 42.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">b)<SPAN style="FONT: 7pt 'Times New Roman'">&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></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l1 level1 lfo3; tab-stops: list 42.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">c)<SPAN style="FONT: 7pt 'Times New Roman'">&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></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l1 level1 lfo3; tab-stops: list 42.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">d)<SPAN style="FONT: 7pt 'Times New Roman'">&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>&lt;</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用例名</SPAN><SPAN lang=EN-US>&gt;</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 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 18pt; TEXT-INDENT: -9pt; mso-list: l1 level2 lfo3; tab-stops: list 18.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">6)</SPAN></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 21pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当相关的可选择的方法或行为随着类型变化时，将行为的职责</SPAN><SPAN lang=EN-US>-</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用多态的操作</SPAN><SPAN lang=EN-US>-</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 21pt; 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>if instanceof </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 18pt; TEXT-INDENT: -9pt; mso-list: l1 level2 lfo3; tab-stops: list 18.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">7)</SPAN></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 18pt"><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 18pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">例，我们的</SPAN><SPAN lang=EN-US>Sale</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类的数据要存入数据库，但是他必须和数据库接口相连接，如果将接口连接放入</SPAN><SPAN lang=EN-US>Sale</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 18pt; TEXT-INDENT: -9pt; mso-list: l1 level2 lfo3; tab-stops: list 18.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">8)</SPAN></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 18pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将职责分配给一个中间对象以便在其他构件或服务之间仲裁，这样这些构件或服务没有被直接耦合。这个中间对象</SPAN><SPAN lang=EN-US>(intermediary)</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在其他构件或服务间创建一个中介者</SPAN><SPAN lang=EN-US>(Indirection)</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。这个中间对象也就事</SPAN><SPAN lang=EN-US>7)</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 18pt; TEXT-INDENT: -9pt; mso-list: l1 level2 lfo3; tab-stops: list 18.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">9)</SPAN></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 18pt; TEXT-INDENT: 23.95pt; mso-char-indent-count: 2.28"><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 18pt; TEXT-INDENT: 23.95pt; mso-char-indent-count: 2.28"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个模式</SPAN><SPAN lang=EN-US>-</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">也被叫做</SPAN><SPAN lang=EN-US>(Demeter)</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></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 4">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 63pt; 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 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.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></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -9pt; mso-list: l0 level2 lfo1; tab-stops: list 18.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">1)</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>-</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">闭”原则（</SPAN><SPAN lang=EN-US>Open-Closed Principle</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，或者</SPAN><SPAN lang=EN-US>OCP</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 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 21pt; 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 18pt; TEXT-INDENT: -9pt; mso-list: l0 level2 lfo1; tab-stops: list 18.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">2)</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>Liskov Substitution Principle, </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或者</SPAN><SPAN lang=EN-US>LSP</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 21pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个就是尽量用多态的方法编程，也就是</SPAN><SPAN lang=EN-US>GRASP</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 18pt; TEXT-INDENT: -9pt; mso-list: l0 level2 lfo1; tab-stops: list 18.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">3)</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>Dependency Inversion Principle, </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或者</SPAN><SPAN lang=EN-US>DIP</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 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 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 18pt; TEXT-INDENT: -9pt; mso-list: l0 level2 lfo1; tab-stops: list 18.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">4)</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>Interface Segregation Principle, </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或者</SPAN><SPAN lang=EN-US>ISP</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 21pt; 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 18pt; TEXT-INDENT: -9pt; mso-list: l0 level2 lfo1; tab-stops: list 18.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">5)</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>/</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">聚合复用原则（</SPAN><SPAN lang=EN-US>Composition/Aggregation Principle, </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或者</SPAN><SPAN lang=EN-US>CARP</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 21pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">又叫合成复用原则。原则就是在一个新的对象里面使用一些已有的对象，使之成为新对象的一部分：新的对象通过向这些对象的委派达到复用已有功能的目的。也就是，要尽量使用类的合成复用，尽量不要使用继承</P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -9pt; mso-list: l0 level2 lfo1; tab-stops: list 18.0pt"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">6)变与不变的分离<BR>&nbsp;&nbsp;&nbsp;&nbsp;更扩展一步,就是将不同变化的组件进行隔离.最简单的例子就是javabean中的存取器。它隔离了不变的接口和变化的内部属性。这方面体现最好的个人觉得就是eclipse，通过变化的插件，eclipse可以用来实现任何功能。</SPAN></SPAN></P></SPAN><img src ="http://www.blogjava.net/gufen/aggbug/14126.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gufen/" target="_blank">落花飞雪</a> 2005-09-26 17:21 <a href="http://www.blogjava.net/gufen/archive/2005/09/26/14126.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>终于找到个适合自己的地方了。</title><link>http://www.blogjava.net/gufen/archive/2005/09/25/13995.html</link><dc:creator>落花飞雪</dc:creator><author>落花飞雪</author><pubDate>Sun, 25 Sep 2005 07:31:00 GMT</pubDate><guid>http://www.blogjava.net/gufen/archive/2005/09/25/13995.html</guid><wfw:comment>http://www.blogjava.net/gufen/comments/13995.html</wfw:comment><comments>http://www.blogjava.net/gufen/archive/2005/09/25/13995.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gufen/comments/commentRss/13995.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gufen/services/trackbacks/13995.html</trackback:ping><description><![CDATA[下边的文章都是从我的msn spaces贴过来的，以后就驻足这里了，感觉这里技术气氛比较浓厚些。不过好像空间少了些，才10M,几张图片就搞定了，看来以后贴图要使劲压了，不过还是尽量少贴图的好。 
<img src ="http://www.blogjava.net/gufen/aggbug/13995.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gufen/" target="_blank">落花飞雪</a> 2005-09-25 15:31 <a href="http://www.blogjava.net/gufen/archive/2005/09/25/13995.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《JSP技术大全》笔记</title><link>http://www.blogjava.net/gufen/archive/2005/09/25/13994.html</link><dc:creator>落花飞雪</dc:creator><author>落花飞雪</author><pubDate>Sun, 25 Sep 2005 07:25:00 GMT</pubDate><guid>http://www.blogjava.net/gufen/archive/2005/09/25/13994.html</guid><wfw:comment>http://www.blogjava.net/gufen/comments/13994.html</wfw:comment><comments>http://www.blogjava.net/gufen/archive/2005/09/25/13994.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gufen/comments/commentRss/13994.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gufen/services/trackbacks/13994.html</trackback:ping><description><![CDATA[<DIV>1.&nbsp;三个伪指令<BR>1.1&nbsp;&lt;%@ page%&gt;<BR>语法: &lt;%@ page attribute=”value” attribute=”value” … %&gt;<BR>属性:<BR>language=”java”，目前仅java<BR>extends=”classeName”，指定当前jsp应该作为哪个超类的子类，一般不用设置<BR>import=”importList”，引入jsp中要用到类<BR>session=”true|false”，指定jsp页面是否需要一个session,默认true。一般不用设置<BR>buffer=”none|size”，描述jsp采用的输出缓存模型，默认8k,一般不用设置。与aotoFlus和配合使用<BR>aotoFlush=”true|false”<BR>isThreadSafe=”true|false”，默认true, 一般不用设置<BR>info=”info_text”,jsp页面的一些描述性信息，可以用servlet的getServletInfo()得到<BR>contentType=”ctinfo”，请求应用返回一个HTTP Content-Type头标，一般为contentType=”type/subtype; charset=charset”,例如：&lt;%@ page contentType=”text/html; charset=utf-8” %&gt;<BR>errorPage=”error_url”,指定如果该jsp页面出错将显示那个页面<BR>isErrorPage=”true|false”,如果为true则声明了该页面是其它jsp页面出错后显示的页面<BR>1.2&nbsp;&lt;%@ include%&gt;<BR>语法: &lt;%@ include file=”filename” %&gt;<BR>说明:filename必须是相对的URL文档，即只能包含路径信息，没有协议或服务器信息。以“/”开始，被认为是相对servlet上下文根的绝对路径。否则，文件名被认为是相对于当前JSP页面的。<BR>在JSP被容器转换成servlet前首先将filename中的文本复制到相应位置，然后再转换为servlet。如果当前JSP页面中存在多个&lt;%@ include%&gt;伪指令，则根据出现的前后顺序依次复制过来。<BR>1.3&nbsp;&lt;%@ taglib%&gt;<BR>语法:&lt;%@ taglib url=”tagLIbraryURL” prefix=”tagPrefix” %&gt;<BR>启用已经定义过的一个标签库<BR>tagLIbraryURL：标签库描述器的url<BR>tagPrefix：用于标识在页面后面部分使用定制标签的唯一前缀<BR>例如：如果abc.tld定义了一个名为table的标签，那么我们可以<BR>&lt;%@ taglib url=”/tlds/abc.tld” prefix=”ft” %&gt;<BR>然后就可以用该标签&lt;ft:table&gt; …&lt;/ft:table&gt;<BR>2.&nbsp;两种注释<BR>&lt;%-- 仅jsp可见 --%&gt;<BR>&lt;!-- html中也可见 --&gt;<BR>3.&nbsp;表达式<BR>&lt;%= exp%&gt;<BR>4.&nbsp;scriptliet: 多个jsp语句的集合<BR>&lt;% statement;[statement;…]%&gt;<BR>scriptliet在servlet中的service() 方法中<BR>5.&nbsp;声明<BR>&lt;%! statement;[statement;…]%&gt;<BR>声明在servlet中的service() 方法之外，注意与scriptliet区别<BR>6.&nbsp;隐含变量<BR>request(常用)<BR>response(常用)<BR>pageContext<BR>session(常用)<BR>application<BR>out(常用)<BR>config<BR>page<BR>exception<BR>7.&nbsp;标准行为<BR>7.1.&nbsp;概念<BR>行为是创建、修改或使用对象的高层jsp元素。行为遵守严格的xml语法：<BR>&lt;tagname [attr=”value” attr=”value”…]&gt;…&lt;/tagname&gt;<BR>如果没有行为主体可简化为：&lt;tagname [attr=”value” attr=”value”…] / &gt;<BR>7.2.&nbsp;7种标准行为标签<BR>&lt;jsp:useBean&gt;…&lt; /jsp:useBean &gt;<BR>&lt;jsp:setProperty … /&gt;<BR>&lt;jsp:getProperty … /&gt;<BR>&lt;jsp:include &gt;…&lt;/jsp: include &gt;<BR>&nbsp;语法:&lt;jsp:include page=”resourcename” flush=”true” /&gt;<BR>&nbsp;说明: resourcename 路径规则同&lt;%@ include%&gt;<BR>&nbsp;表达式语法:&lt;jsp:include page=”&lt;%= jspfile %&gt;” flush=”true” /&gt;<BR>&nbsp;向被调用的jsp页面传递参数:<BR>&lt;jsp:include page=”pageName” flush=”true”&gt;<BR>&lt;jsp:parm name=”parm1Name” value=”parm1Value” /&gt;<BR>&lt;jsp:parm name=”parm2Name” value=”parm2Value” /&gt;<BR>&lt;/jsp:include&gt;<BR>&lt;jsp:forward&gt;…&lt;/jsp: forward &gt;<BR>&lt;jsp:param&gt;…&lt;/jsp: param &gt;<BR>&lt;jsp:plugin&gt;…&lt;/jsp: plugin &gt;</DIV>
<DIV>7.3.&nbsp;&lt;jsp:include &gt;…&lt;/jsp: include &gt;与&lt;%@ include%&gt;的区别<BR>&lt;%@ include%&gt;伪指令：用于在JSP源码被转换成JavaServlet源码和被编译前将静态文本复制到其中。也就是在JSP中出现&lt;%@ include%&gt;的地方将&lt;%@ include%&gt;所包含的文件内容直接拷贝到此处，以此实现将变化和不变化的代码分离。典型情况下，文本为HTML代码，但它可以是在JSP页面内显示的任何内容。<BR>&lt;jsp:include … /&gt;行为：使得servlet引擎调用另一URL，生成带有最初JSP页面的输出。<BR>在构建一种思维模式的关键一点是&lt;%@ include%&gt;伪指令在编译时只执行一次，而&lt;jsp:include &gt;行为每次进行请求时都执行。&lt;jsp:include &gt;行为更像一个C语言的函数调用，因为在Tomcat编译后的源码中可以看见将&lt;jsp:include &gt;翻译为：pageContext.include(“resourcename”)。<BR>此外还必须注意包含与被包含文件之间命名的冲突问题。<BR>8.&nbsp;标签扩展<BR>除了以上7种标准行为的基本标签外，可以自由的扩展标签<BR>步骤：1）定义标签<BR>&nbsp;&nbsp; 2）编写标签库描述器的接口（创建TLD入口）<BR>&nbsp;&nbsp; 3）编写标签处理器<BR>&nbsp;&nbsp;&nbsp; 4）在JSP页面中使用标签<BR>9.&nbsp;JSP与XML<BR>9.1.&nbsp;DTD(文档类型定义，Document Type Definition): 用来定义XML元素及其规则<BR>9.2.&nbsp;XML解析器<BR>1)&nbsp;DOM(Document Object Module) 文档对象模型<BR>2)&nbsp;SAX(Simple API for XML) XML的简单API<BR>SAX 较 DOM有很多优点<BR>可以使用XSLT处理器和XSL样式单转换XML<BR></DIV><img src ="http://www.blogjava.net/gufen/aggbug/13994.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gufen/" target="_blank">落花飞雪</a> 2005-09-25 15:25 <a href="http://www.blogjava.net/gufen/archive/2005/09/25/13994.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《Effective Java》笔记(选择自 njchenyi 的 Blog)</title><link>http://www.blogjava.net/gufen/archive/2005/09/25/13993.html</link><dc:creator>落花飞雪</dc:creator><author>落花飞雪</author><pubDate>Sun, 25 Sep 2005 07:24:00 GMT</pubDate><guid>http://www.blogjava.net/gufen/archive/2005/09/25/13993.html</guid><wfw:comment>http://www.blogjava.net/gufen/comments/13993.html</wfw:comment><comments>http://www.blogjava.net/gufen/archive/2005/09/25/13993.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gufen/comments/commentRss/13993.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gufen/services/trackbacks/13993.html</trackback:ping><description><![CDATA[<DIV>有别人写好的笔记，不用自己费神写了。对于看过Effective Java的偶而忘记某个条目，看看笔记或许能记起来。</DIV>
<DIV>&nbsp;</DIV>
<DIV>Creating and Destroying Object</DIV>
<DIV>Item 1:考虑用静态工厂方法替代构造器<BR>例如：public static Boolean valueOf(boolean b)<BR>&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (b?Boolean.TRUE:Boolean.FALSE);<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>这样的好处是方法有名字，并且它可以复用对象，不像构造器每次调用都产生新的对象。其次它还可以返回返回类型的子类。不好的地方是如果没有public or protected构造器的类将不能被继承。还有就是静态工厂方法的名字和其他的静态方法名字不容易区分。</DIV>
<DIV>Item 2:通过添加私有构造器来加强单例属性（singletom property)<BR>例如：public class Hello<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private static final Hello Instance = new Hell();</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Hello()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static Hello getInstance()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Instance;</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>这个私有构造器只能在内部被使用，确保了单例模式！<BR>Item 3:避免创建重复的对象<BR>对不可修改的对象尽量进行复用，这样效率和性能都会提高。例如如果循环100次String s = new String("hello")将创建100个对象 循环100次String s = "hello";则只创建了一个对象。很好的进行了复用。</DIV>
<DIV>Item 4:用私有构造器来避免被实例化<BR>例如public UtilityClass<BR>{<BR>&nbsp;&nbsp; private UtilityClass()<BR>&nbsp;&nbsp; {}</DIV>
<DIV>///<BR>}<BR>通常那些工具类是这么设计的</DIV>
<DIV>Item 5:消除绝对的对象引用<BR>&nbsp;&nbsp;&nbsp;&nbsp; 虽然java中使用gc来管理内存，但是如果不注意的话也会产生“内存泄漏”。例如下面的程序<BR>public class Stack<BR>{<BR>&nbsp;private Object[] elements;<BR>&nbsp;private int size = 0;<BR>&nbsp;<BR>&nbsp;public Stack(int i)<BR>&nbsp;{<BR>&nbsp; this.elements = new Object[i]; <BR>&nbsp;} <BR>&nbsp;<BR>&nbsp;public void push(Object e)<BR>&nbsp;{<BR>&nbsp; ensure();<BR>&nbsp; elements[size++] = e; <BR>&nbsp;}<BR>&nbsp;<BR>&nbsp;public Object pop()<BR>&nbsp;{<BR>&nbsp; if(size == 0)<BR>&nbsp; {<BR>&nbsp;&nbsp; //// <BR>&nbsp; } <BR>&nbsp; <BR>&nbsp; return elements[size--];<BR>&nbsp;}<BR>&nbsp;<BR>&nbsp;private void ensure()<BR>&nbsp;{<BR>&nbsp; //// <BR>&nbsp;}<BR>}<BR>标记的地方存在着内存泄漏的问题，因为当他被弹出栈的时候，它也没有成为可回收的垃圾对象，Stack维护着他们的绝对的引用。将不能更改。改进的方法是如下的写法<BR>&nbsp;public Object pop()<BR>&nbsp;{<BR>&nbsp; if(size == 0)<BR>&nbsp; {<BR>&nbsp;&nbsp; //// <BR>&nbsp; } <BR>&nbsp; Object obj = elements[--size];<BR>&nbsp; elements[size] = null;<BR>&nbsp; <BR>&nbsp; return obj;<BR>&nbsp;}<BR>&nbsp;但是切忌不要滥用null。</DIV>
<DIV>Item 6:避免finalizer<BR>垃圾回收器是低线程级别运行的且不能被强迫执行。System.gc()只是建议垃圾回收器收集垃圾，它可不一定马上运行，而且垃圾回收器运行的时候会挂起其他线程导致程序停止响应。推荐使用的方法类似于<BR>InputStream is = null;</DIV>
<DIV>try<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is = /////;<BR>}<BR>finally<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is.close();<BR>}</DIV>
<DIV>Methods Common to All Objects</DIV>
<DIV>item 7:当你覆盖equals方法的时候一定要遵守general contact<BR>&nbsp;&nbsp; 覆盖equals的时候一定要加倍的小心，其实最好的办法就是不覆盖这个方法。比如在下面的情况下就可以不覆盖</DIV>
<DIV>&nbsp;&nbsp; 1这个类的每个实例都是唯一的，例如Thread类</DIV>
<DIV>&nbsp;&nbsp; 2 如果你不关心这个类是否该提供一个测试逻辑相等的方法</DIV>
<DIV>&nbsp;&nbsp; 3超类已经覆盖了equals方法，并且它合适子类使用</DIV>
<DIV>&nbsp;&nbsp; 4如果这个类是private或者是package-private的，并且你确信他不会被调用</DIV>
<DIV>&nbsp;&nbsp; 但是当我们要为这个类提供区分逻辑相等和引用相等的方法的时候，我们就必须要覆盖这个方法了。例如String类，Date类等，覆盖的时候我们一定要遵从general contact，说白了就是一个合同。合同的主要内容是<BR>&nbsp;&nbsp; 1．x.equals(x)必须返回true<BR>&nbsp;&nbsp; 2．x.equals（y）当且仅当y.equals(x)返回true的时候返回true<BR>&nbsp;&nbsp; 3．x.equals(y)返回true，y.equals(z)返回true,那么x.equals(z)必须返回true<BR>&nbsp;&nbsp; 4.如果没有任何修改得话 那么多次调用x.equals(y)的返回值应该不变<BR>&nbsp;&nbsp; 5．任何时候非空的对象x,x.equals(null)必须返回false</DIV>
<DIV>下面是作者的建议如何正确的覆盖equals方法<BR>1．&nbsp; 用==检查是否参数就是这个对象的引用<BR>2．&nbsp; 用instanceof判断参数的类型是否正确<BR>3．&nbsp; 把参数转换成合适的类型<BR>4．&nbsp; 比较类的字段是不是匹配</DIV>
<DIV>例如：<BR>public boolean equals(Object o)</DIV>
<DIV>{</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(o== this) return true;</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!(o instanceof xxxx) return false;</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xxx in = (xxx)o;</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ……..</DIV>
<DIV>}</DIV>
<DIV>最后一点要注意的时候不要提供这样的方法public boolean equals(MyClass o)这样是重载并不是覆盖Object的equals方法</DIV>
<DIV>item 8 :当你覆盖equals的时候必须覆盖hashCode方法<BR>&nbsp;&nbsp;&nbsp; 这点必须切忌，不然在你和hash-based集合打交道的时候，错误就会出现了。关键问题在于一定要满足相等的对象必须要有相等的hashCode。如果你在PhoneNumber类中覆盖了equals方法，但是没有覆盖hashCode方法，那么当你做如下操作的时候就会出现问题了。<BR>Map m = new HashMap();<BR>m.put(new PhoneNumber(408,863,3334),”ming”)<BR>当你调用m.get(new PhoneNumber(408,863,3334))的时候你希望得到ming但是你却得到了null,为什么呢因为在整个过程中有两个PhoneNumber的实例，一个是put一个是get，但是他们两个逻辑相等的实例却得到不同的hashCode那么怎么可以取得以前存入的ming呢。</DIV>
<DIV>&nbsp;</DIV>
<DIV>Item 9:永远覆盖toString方法<BR>&nbsp;&nbsp;&nbsp; 在Object的toString方法返回的形式是Class的类型加上@加上16进制的hashcode。你最好在自己的类中提供toString方法更好的表述实例的信息，不然别人怎么看得明白呢。</DIV>
<DIV>Item 10:覆盖clone()方法的时候一定要小心<BR>&nbsp;&nbsp;&nbsp; 一个对象要想被Clone，那么要实现Clone()接口，这个接口没有定义任何的方法，但是如果你不实现这个接口的话，调用clone方法的时候会出现CloneNotSupportedException，这就是作者叫做mixin的接口类型。通常clone()方法可以这样覆盖</DIV>
<DIV>public Object clone()</DIV>
<DIV>{</DIV>
<DIV>try<BR>{</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return super.clone();</DIV>
<DIV>}</DIV>
<DIV>catch(CloneNotSupportedException e)<BR>{}</DIV>
<DIV>}</DIV>
<DIV>但是当你要clone的类里面含有可修改的引用字段的时候，那么你一定要把整个类的蓝图进行复制，如果对你clone得到的对象进行修改的时候还会影响到原来的实例，那么这是不可取的。所以应该这样clone()</DIV>
<DIV>public Object clone() throws CloneNotSupportedException</DIV>
<DIV>{</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stack Result&nbsp; = (Stack)super.clone();</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Result.elements = (Object[])elements.clone();</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Return result;</DIV>
<DIV>}</DIV>
<DIV>其中elements是stack类中可修改的引用字段，注意如果elements是final的话我们就无能为力了，因为不能给他重新赋值了.其实如果不是必须的话，根本就不用它最好。</DIV>
<DIV>&nbsp;</DIV>
<DIV>Item 11:考虑适当的时候覆盖Comparable接口<BR>&nbsp;&nbsp;&nbsp;&nbsp; Thinking in java上说的更清楚，这里不多少了。</DIV>
<DIV>&nbsp;&nbsp;&nbsp; 越来越发现这是一本难得的好书，Java程序员不看这本书的话真是很遗憾。本章讲述的是类和接口相关的问题。这几个Item都非常重要. </DIV>
<DIV>Item 12：把类和成员的可访问范围降到最低<BR>&nbsp;&nbsp;&nbsp; 好的模块设计应该尽最大可能封装好自己的内部信息，这样可以把模块之间的耦合程度降到最低。开发得以并行，无疑这将加快开发的速度，便于系统地维护。Java中通过访问控制符来解决这个问题。</DIV>
<DIV>public表示这个类在任何范围都可用。 <BR>protected表示只有子类和包内的类可以使用 <BR>private-package(default)表示在包内可用 <BR>private表示只有类内才可以用<BR>你在设计一个类的时候应该尽量的按照4321得顺序设计。如果一个类只是被另一个类使用，那么应该考虑把它设计成这个类的内部类。通常public的类不应该有public得字段，不过我们通常会用一个类来定义所有的常量，这是允许的。不过必须保证这些字段要么是基本数据类型要么引用指向的对象是不可修改的。不然他们将可能被修改。例如下面的定义中data就是不合理的，后面两个没有问题。<BR>public class Con<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final int[] data = {1,2,3};// it is bad<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String hello = "world";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final int i = 1;<BR>}</DIV>
<DIV>Item 13:不可修改的类更受青睐</DIV>
<DIV>&nbsp;&nbsp;&nbsp; 不可修改的类意思是他们一经创建就不会改变，例如String类。他们的设计、实现都很方便，安全性高——它们是线程安全的。设计不可修改类有几点规则：</DIV>
<DIV>不要提供任何可以修改对象的方法 <BR>确保没有方法能够被覆盖，可以通过把它声明为final <BR>所有字段设计成final <BR>所有字段设计成private <BR>确保外部不能访问到类的可修改的组件<BR>不可修改类也有个缺点就是创建不同值得类的时候要创建不同的对象，String就是这样的。通常有个解决的办法就是提供一个帮助类来弥补，例如StringBuffer类。<BR>Item 14:化合(合成）比继承更值得考虑</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 实现代码重用最重要的办法就是继承，但是继承破坏了封装，导致软件的键壮性不足。如果子类继承了父类，那么它从父类继承的方法就依赖父类的实现，一旦他改变了会导致不可预测的结果。作者介绍了InstrumentedHashSet作为反例进行说明，原因就是没有明白父类的方法实现。作者给出的解决办法是通过化合来代替继承，用包装类和转发方法来解决问题。把想扩展的类作为本类的一个private final得成员变量。把方法参数传递给这个成员变量并得到返回值。这样做的缺点是这样的类不适合回掉框架。继承虽然好，我们却不应该滥用，只有我们能确定它们之间是is-a得关系的时候才使用。</DIV>
<DIV>Item 15:如果要用继承那么设计以及文档都要有质量保证，否则就不要用它</DIV>
<DIV>&nbsp;&nbsp;&nbsp; 为了避免继承带来的问题，你必须提供精确的文档来说明覆盖相关方法可能出现的问题。在构造器内千万不要调用可以被覆盖的方法，因为子类覆盖方法的时候会出现问题。<BR>import java.util.*;</DIV>
<DIV>public class SubClass extends SuperClass<BR>{<BR>&nbsp;private final Date date;<BR>&nbsp;<BR>&nbsp;public SubClass()<BR>&nbsp;{<BR>&nbsp; date = new Date(); <BR>&nbsp;}<BR>&nbsp;<BR>&nbsp;public void m()<BR>&nbsp;{<BR>&nbsp; System.out.println(date); <BR>&nbsp;}<BR>&nbsp;<BR>&nbsp;public static void main(String[] args)<BR>&nbsp;{<BR>&nbsp; SubClass s = new SubClass();<BR>&nbsp; s.m(); <BR>&nbsp;}<BR>&nbsp;<BR>}</DIV>
<DIV>class SuperClass<BR>{<BR>&nbsp;public SuperClass()<BR>&nbsp;{<BR>&nbsp; m(); <BR>&nbsp;} <BR>&nbsp;<BR>&nbsp;public void m()<BR>&nbsp;{<BR>&nbsp; <BR>&nbsp;}<BR>}<BR>由于在date被初始化之前super（）已经被调用了，所以第一次输出null而不是当前的时间。<BR>由于在Clone()或者序列化的时候非常类似构造器的功能，因此readObject()和clone（）方法内最好也不要包括能被覆盖的方法。</DIV>
<DIV>Item 16:在接口和抽象类之间优先选择前者</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 接口和抽象类都用来实现多态，不过我们应该优先考虑用接口。知道吗？James说过如果要让他重新设计java的话他会把所有都设计成接口的。抽象类的优点是方便扩展，因为它是被继承的，并且方法可以在抽象类内实现，接口则不行。</DIV>
<DIV>Item 17：接口只应该用来定义类型</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 接口可以这样用的 Collection c = new xxxx();这是我们最常用的。不要把接口用来做其他的事情，比如常量的定义。你应该定义一个类，里面包含public final static 得字段。</DIV>
<DIV>Item 18: 在静态和非静态内部类之间选择前者</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果一个类被定义在其他的类内部那么它就是嵌套类，可以分为静态内部类、非静态内部类和匿名类。<BR>&nbsp;&nbsp; static member class 得目的是为enclosing class服务，如果还有其他的目的，就应该把它设计成top-level class。nonstatic member class是和enclosing class instance关联的，如果不需要访问enclosing class instance的话应该把它设计成static得，不然会浪费时间和空间。anonymous class是声明和初始化同时进行的。可以放在代码的任意位置。典型应用是Listener 和process object例如Thread。</DIV>
<DIV>&nbsp;&nbsp;&nbsp; 由于以前学过C语言，所以对C还是蛮有感情，而JAVA和C又有很多相似之处，很多从C转过来学习JAVA的兄弟，可能一开始都不是很适应，因为很多在C里面的结构在JAVA里面都不能使用了，所以下面我们来介绍一下C语言结构的替代。</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Item 19:用类代替结构<BR>&nbsp;&nbsp;&nbsp;&nbsp; JAVA刚面世的时候，很多C程序员都认为用类来代替结构现在太复杂，代价太大了，但是实际上，如果一个JAVA的类退化到只包含一个数据域的话，这样的类与C语言的结构大致是等价的。</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 比方说下面两个程序片段：</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Point<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private float x;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private float y;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 实际上这段代码和C语言的结构基本上没什么区别，但是这段代码恐怕是众多OO设计Fans所不齿的，因为它没有体现封装的优异性，没有体现面向对象设计的优点，当一个域被修改的时候，你不可能再采取任何辅助的措施了，那我们再来看一看采用包含私有域和共有访问方法的OO设计代码段：<BR>&nbsp;&nbsp;&nbsp;&nbsp; class Point<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private float x;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private float y;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Point(float x,float y)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.x=x;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.y=y;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public float getX(){retrun x;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public float getY(){return y;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setX(float x){this.x=x;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setY(float y){this.y=y;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 单从表面上看，这段代码比上面那个多了很多行，还多了很多函数，但是仔细想一下，这样的OO设计，似乎更人性化，我们可以方面的对值域进行提取，修改等操作，而不直接和值域发生关系，这样的代码不仅让人容易读懂，而且很安全，还吸取了面向对象程序设计的灵活性，试想一下，如果一个共有类暴露它的值域，那么想要在将来的版本中进行修改是impossible的，因为共有类的客户代码已经遍布各处了。<BR>需要提醒一点的是，如果一个类是包级私有的，或者是一个私有的嵌套类，则直接暴露其值域并无不妥之处。</DIV>
<DIV>Item 20：用类层次来代替联合<BR>我们在用C语言来进行开发的时候，经常会用到联合这个概念，比如：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; typedef struct{<BR>&nbsp;&nbsp;&nbsp;&nbsp; double length;<BR>&nbsp;&nbsp;&nbsp;&nbsp; double width;&nbsp;&nbsp;&nbsp;&nbsp; <BR>}rectangleDimensions_t;</DIV>
<DIV>那我们在JAVA里面没有联合这个概念，那我们用什么呢？对！用继承，这也是JAVA最吸引我的地方之一，它可以使用更好的机制来定义耽搁数据类型，在Bruce Eckel的Thinking in java里面也多次提到了一个和形状有关的例子，我们可以先笼统的定义一个抽象类，即我们通常所指的超类，每个操作定义一个抽象的方法，其行为取决于标签的值，如果还有其他的操作不依赖于标签的值，则把操作变成根类（继承的类）中的具体方法。<BR>这样做的最重要的优点是：类层次提供了类型的安全性。<BR>其次代码非常明了，这也是OO设计的优点。<BR>而且它很容易扩展，即使是面向多个方面的工作，能够同样胜任。<BR>最后它可以反映这些类型之间本质上的层次关系，从而允许更强的灵活性，以便编译时类型检查。</DIV>
<DIV>Item 21：用类来代替enum结构<BR>Java程序设计语言提出了类型安全枚举的模式来替代enum结构，它的基本思想很简单：定义一个类来代表枚举类型的单个元素，并且不提供任何公有的构造函数，相反，提供公有静态final类，使枚举类型中的每一个常量都对应一个域。<BR>类型安全枚举类型的一个缺点是，装载枚举类的和构造常量对象时，需要一定的时间和空间开销，除非是在资源很受限制的设备比如蜂窝电哈和烤面包机上，否则在实际中这个问题不会被考虑。<BR>&nbsp;总之，类型安全枚举类型明显优于int类型，除非实在一个枚举类型主要被用做一个集合元素，或者主要用在一个资源非常不受限的环境下，否则类型安全枚举类型的缺点都不成问题，依次，在要求使用一个枚举类型的环境下，我们首先应考虑类型安全枚举类型模式。</DIV>
<DIV>Item 22：用类和接口来代替函数指针<BR>众所周知，JAVA语言和C的最大区别在于，前者去掉了指针，小生第一次接触JAVA的时候觉得好不习惯，因为突然一下子没了指针，觉得好不方面啊，C语言的精髓在于其指针的运用，而JAVA却把它砍掉了，让人好生郁闷，不过随着时间的推移，我渐渐明白了用类和接口的应用也同样可以提供同样的功能，我们可以直接定义一个这样一个类，他的方法是执行其他方法上的操作，如果一个类仅仅是导出这样一个方法，那么它实际上就是一个指向该方法的指针，举个例子：<BR>class StringLengthComprator{<BR>public int compare(String s1,String s2)<BR>{<BR>return s1.length()-s2.length();<BR>}<BR>}<BR>这个类导出一个带两个字符串的方法，它是一个用于字符串比较的具体策略。它是无状态的，没有域，所以，这个类的所有实例在功能上都是等价的，可以节省不必要的对象创建开销。但是我们不好直接把这个类传递给可户使用，因为可户无法传递任何其他的比较策略。相反，我们可以定义一个接口，即我们在设计具体策略类的时候还需要定义一个策略接口：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public interface Comparator{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int compare(Object o1,Object o2);<BR>}<BR>&nbsp; 我们完全可以依照自己的需要来定义它。<BR>具体的策略类往往使用匿名类声明。<BR>在JAVA中，我们为了实现指针的模式，声明一个接口来表示该策略，并且为每个具体策略声明一个实现了该接口的类，如果一个具体策略只被使用一次的话，那么通常使用匿名类来声明和实例化这个具体策略类，如果一个策略类反复使用，那么它的类通常是一个私有的的静态成员类。 <BR>下面我们来讨论一下有关方法设计的几个方面，下面说的几个要点大多数都是应用在构造函数中，当然也使用于普通方法，我们追求的依然是程序的可用性，健壮性和灵活性。</DIV>
<DIV>Item 23：检查参数的有效性</DIV>
<DIV>非公有的方法我们应该用断言的方法来检查它的参数，而不是使用通常大家所熟悉的检查语句来检测。如果我们使用的开发平台是JDK1.4或者更高级的平台，我们可以使用assert结构；否则我们应该使用一种临时的断言机制。<BR>有些参数在使用过程中是先保存起来，然后在使用的时候再进行调用，构造函数正是这种类型的一种体现，所以我们通常对构造函数参数的有效性检查是非常仔细的。</DIV>
<DIV>Item 24：需要时使用保护性拷贝<BR>众所周知，JAVA在代码安全性方面较C/C++有显著的提高，缓冲区溢出，数组越界，非法指针等等，我们的JAVA都有一个很完善的机制来进行免疫，但是这并不代表我们不必去考虑JAVA的安全性，即便在安全的语言，如果不采取措施，还是无法使自己与其他类隔开。假设类的客户会尽一切手段来破坏这个类的约束条件，在这样的前提下，你必须从保护性的方面来考虑设计程序。通过大量的程序代码研究我们得出这样的结论：对于构造性函数的每个可变参数进行保护性拷贝是必要的。需要注意的是，保护性拷贝是在检查参数的有效性之前 进行的，并且有效性检查是针对拷贝之后的对象，而不是原始的对象。对于“参数类型可以被不可信方子类化”的情况，不要用clone方法来进行参数的保护性拷贝。<BR>对于参数的保护性拷贝并不仅仅在于非可变类，当我们编写一个函数或者一个构造函数的时候，如果它要接受客户提供的对象，允许该对象进入到内部数据结构中，则有必要考虑一下，客户提供的对象是否是可变的，如果是，则要考虑其变化的范围是否在你的程序所能容纳的范围内，如果不是，则要对对象进行保护性拷贝，并且让拷贝之后的对象而不是原始对象进入到数据结构中去。当然最好的解决方法是使用非可变的对象作为你的对象内部足见，这样你就可以不必关心保护性拷贝问题了。）：</DIV>
<DIV>Item 25：谨慎使用设计方法的原型<BR>（1）谨慎的选择方法的名字：即要注意首先要是易于理解的，其次还要与该包中的其他方法的命名风格相一致，最后当然要注意取一个大众所认可的名字。<BR>（2）不要追求提供便利的方法：每一个方法都应该提供其应具备的功能点，对于接口和类来方法不要过多，否则会对学习使用维护等等方面带来许多不必要的麻烦，对于每一个类型所支持的每一个动作，都提供一个功能完全的方法，只有一个方法过于频繁的使用时，才考虑为它提供一个快捷方法。<BR>（3）避免过长的参数列表：通常在实践中，我们以三个参数作为最大值，参数越少越好，类型相同的长参数列尤其影响客户的使用，两个方法可以避免过长的参数这样的情况发生，一是把一个方法分解成多个，每一个方法只要求使用这些参数的一个子集；二是创建辅助类，用来保存参数的聚集，这些辅助类的状态通常是静态的。<BR>对于参数类型，优先使用接口而不是类。<BR>这样做的目的是避免影响效能的拷贝操作。<BR>谨慎的使用函数对象。<BR>创建函数对象最容易的方法莫过于使用匿名类，但是那样会带来语法上混乱，并且与内联的控制结构相比，这样也会导致功能上的局限性。</DIV>
<DIV>Item 26：谨慎的使用重载<BR>到底是什么造成了重载机制的混淆算法，这是个争论的话题，一个安全而保守的方法是，永远不要导出两个具有相同参数数目的重载方法。而对于构造函数来说，一个类的多个构造函数总是重载的，在某些情况下，我们可以选择静态工厂，但是对于构造函数来说这样做并不总是切合实际的。<BR>当涉及到构造函数时，遵循这条建议也许是不可能的，但我们应该极力避免下面的情形：<BR>同一组参数只需要经过类型的转换就可以传递给不同的重载方法。如果这样做也不能避免的话，我们至少要保证一点：当传递同样的参数时，所有的重载方法行为一致。如果不能做到这一点，程序员就不能有效的使用方法或者构造函数。</DIV>
<DIV>Item 27：返回零长度的数组而不是null<BR>因为这样做的原因是编写客户程序的程序员可能忘记写这种专门的代码来处理null返回值。没有理由从一个取数组值的方法中返回null，而不是返回一个零长度数组。</DIV>
<DIV>Item 28：为所有导出的API元素编写文档注释<BR>不爱写注释可能是大多数程序员新手的通病（包括偶哈~），但是如果想要一个API真正可用，就必须写一个文档来说明它，保持代码和文档的同步是一件比较烦琐的事情，JAVA语言环境提供了javadoc工具，从而使这个烦琐的过程变得容易，这个工具可以根据源代码自动产生API文档。<BR>为了正确得编写API文档，我们必须每一个被导出的类，接口，构造函数，方法和域声明之前加一个文档注释。<BR>每一个方法的文档注释应该见解的描述它和客户之间的约定。<BR>我们接下来讨论一下Java语言的细节，包括局部变量的处理，库的使用，以及两种不是语言本身提供的机制的使用等等一些大家平时可能忽略的问题。</DIV>
<DIV>Item 29:将局部变量的作用域最小化<BR>和C语言要求局部变量必须被生命在代码的开始处相比，Java程序设计语言宽松得多，它允许你在代码的任何位置声明。要想使一个局部变量的作用域最小化，最高小的技术是在第一次需要使用它的地方声明，变量的作用域是从声明它的地方开始到这个声明做在的代码块的结束位止，如果我们把变量的声明和代码的使用位置分开的过大，那么对于读这段代码的人来说，是很不幸的。<BR>我们几乎都是在一个局部变量声明的地方同时给它初始化，注意这是很重要的，甚至有时候，如果我们的初始化应该推迟到下一个代码的位置，我们同时应该把声明也往后延迟。这条规则唯一的例外是try-catch这个语句，因为如果一个变量被方法初始化，那么这个方法很有可能抛出一个异常，那我们最常用的方法就是把它置于try块的内部去进行初始化。由此我们可以得出，for循环优于while循环，我们在能使用for循环的地方尽量使用for而不使用while，因为for循环是完全独立的，所以重用循环变量名字不会有任何伤害。<BR>最后我们要记住的是尽量把我们的函数写的小而集中，这样才能真正组做到”最小化局部变量的作用域”这一要旨。</DIV>
<DIV>Item 30：了解和使用库<BR>使用标准库，我们可以充分利用编写这些库的Java专家的知识，以及在你之前其他人的使用经验，这就是所谓站在巨人的肩膀上看世界吧~<BR>在每一个Java平台的发行版本里面，都会有许多新的包的加入，和这些更新保持一直是值得的，比如说我们J2ME的开发，在MIDP 1.0的时代，我们要写个Game还要自己动手写工具类，现在MIDP2.0推出之后，大多数写游戏的人都觉得方便了很多，因为在这个版本里面加入了游戏包，为我们的开发节省了大量的人力物力。</DIV>
<DIV>Item 31：如果想要知道精确的答案，就要避免使用double和float<BR>&nbsp;&nbsp;&nbsp;&nbsp; 对于金融行业来说，对数据的严整性要求是很高的，不容半点马虎，那大家都知道再我们的Java语言里面有两个浮点数类型的变量float和double，可能大家会认为他们的精度对于金融行业这样对数字敏感的行业来说，已经够用了，但是在开发当中，我们要尽量少使用double和float，因为让他们精确的表达0.1是不可能的。那我们如何解决这个问题呢，答案是使用BigDecimal,int或者long进行货币计算。在这里对大家的忠告是：对于商务运算，我们尽量使用BigDecimal，对于性能要求较高的地方，我们有能力自己处理十进制的小数点，数值不太大的时候，我们可以使用int或者long，根据自己的需要来判定具体使用哪一个，如果范围超过了18位数，那我们必须使用BigDecimal。</DIV>
<DIV>Item 32：如果其他类型更适合，则尽量避免使用字符串<BR>&nbsp;&nbsp;&nbsp;&nbsp; 在偶看到这条建议之前，我就很喜欢用字符串，不管在什么场合下，先String了再说，但是实际上很多情况下，我们要根据实际情况来判定到底使用什么类型，而且字符串不适合替代枚举类型，类型安全枚举类型和int值都比字符串更适合用来表示枚举类型的常量。字符串也不适合替代聚集类型，有一个更好的方法就是简单的写一个类来描述这个数据集，通常是一个私有的静态成员类最好。字符串也不适合代替能力表，总而言之，如果可以适合更加适合的数据类型，或者可以编写更加适当的数据类型，那么应该避免使用字符串来表示对象。</DIV>
<DIV>Item 33：了解字符串的连接功能<BR>我们经常在使用System.out.println()的时候，往括号里写一串用“+”连接起来的字符串，这是我们最常见的，但是这个方法并不适合规模较大的情形，为连接N个字符串而重复地使用字符串连接操作符，要求N的平方级的时间，这是因为字符串是非可变的，这就导致了在字符串进行连接的时候，前后两者都要拷贝，这个时候我们就提倡使用StingBuffer替代String。</DIV>
<DIV>Item 34：通过接口引用对象<BR>通俗的说就是尽量优先使用接口而不是类来引用对象，如果有合适的接口存在那么对使用参数，返回值，变量域都应该使用接口类型养成使用接口作为对象的习惯，会使程序变得更加灵活。<BR>如果没有合适的接口，那么，用类而不是接口来引用一个对象，是完全合适的。</DIV>
<DIV>Item 35：接口优先于映像机制<BR>java.lang.relect提供了“通过程序来访问关于已装载的类的信息”，由此，我们可以通过一个给定的Class实例，获得Constructor,Method和Field实例。<BR>映像机制允许一个类使用另一个类，即使当前编译的时候后者还不存在，但是这种能力也要付出代价：<BR>我们损失了了编译时类型检查的好处，而且要求执行映像访问的代码非常笨拙和冗长，并且在性能上大大损失。<BR>通常，普通应用在运行时刻不应以映像方式访问对象。</DIV>
<DIV>Item 36：谨慎的使用本地方法<BR>JNI允许Java应用程序调用本地方法，所谓本地方法是指用本地程序设计语言（如C，C++）来编写的特殊方法，本地方法可以在本地语言执行任何计算任务，然后返回到Java程序设计语言中。但是随着JDK1.3及后续版本的推出这种通过使用本地方法来提高性能的方法已不值得提倡，因为现在的JVM越来越快了，而且使用本地方法有一些严重的缺点，比如使Java原本引以为傲的安全性荡然无存，总之在使用本地方法的时候要三思。</DIV>
<DIV>Item 37：谨慎使用优化<BR>不要因为性能而牺牲合理的代码结构，努力编写好的程序而不是快的程序，但是避免那些限制性能的设计决定，同时考虑自己设计的API决定的性能后果，为了获得更好的性能而对API进行修改这也是一个非常不好的想法，通常我们在做优化之后，都应该对优化的程度进行一些测量。</DIV>
<DIV>Item 38：遵守普遍接受的命名惯例<BR>Java有一套比较完善的命名惯例机制，大部分包含在《The Java Language Specification》，严格得讲这些惯例分成两类，字面的和语法的。<BR>字面涉及包，类，接口，方法和域，语法的命名惯例比较灵活，所以争议更大，字面惯例是非常直接和明确的，而语法惯例则相对复杂，也很松散。但是有一个公认的做法是：“如果长期养成的习惯用法与此不同的话，请不要盲目遵从 </DIV>
<DIV>Item 12：把类和成员的可访问范围降到最低<BR>&nbsp;&nbsp;&nbsp; 好的模块设计应该尽最大可能封装好自己的内部信息，这样可以把模块之间的耦合程度降到最低。开发得以并行，无疑这将加快开发的速度，便于系统地维护。Java中通过访问控制符来解决这个问题。</DIV>
<DIV>public表示这个类在任何范围都可用。 <BR>protected表示只有子类和包内的类可以使用 <BR>private-package(default)表示在包内可用 <BR>private表示只有类内才可以用<BR>你在设计一个类的时候应该尽量的按照4321得顺序设计。如果一个类只是被另一个类使用，那么应该考虑把它设计成这个类的内部类。通常public的类不应该有public得字段，不过我们通常会用一个类来定义所有的常量，这是允许的。不过必须保证这些字段要么是基本数据类型要么引用指向的对象是不可修改的。不然他们将可能被修改。例如下面的定义中data就是不合理的，后面两个没有问题。<BR>public class Con<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final int[] data = {1,2,3};// it is bad<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String hello = "world";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final int i = 1;<BR>}</DIV>
<DIV>Item 13:不可修改的类更受青睐<BR>&nbsp;&nbsp;&nbsp; 不可修改的类意思是他们一经创建就不会改变，例如String类。他们的设计、实现都很方便，安全性高——它们是线程安全的。设计不可修改类有几点规则：</DIV>
<DIV>不要提供任何可以修改对象的方法 <BR>确保没有方法能够被覆盖，可以通过把它声明为final <BR>所有字段设计成final <BR>所有字段设计成private <BR>确保外部不能访问到类的可修改的组件<BR>不可修改类也有个缺点就是创建不同值得类的时候要创建不同的对象，String就是这样的。通常有个解决的办法就是提供一个帮助类来弥补，例如StringBuffer类。</DIV>
<DIV>Item 14:化合(合成）比继承更值得考虑<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 实现代码重用最重要的办法就是继承，但是继承破坏了封装，导致软件的键壮性不足。如果子类继承了父类，那么它从父类继承的方法就依赖父类的实现，一旦他改变了会导致不可预测的结果。作者介绍了InstrumentedHashSet作为反例进行说明，原因就是没有明白父类的方法实现。作者给出的解决办法是通过化合来代替继承，用包装类和转发方法来解决问题。把想扩展的类作为本类的一个private final得成员变量。把方法参数传递给这个成员变量并得到返回值。这样做的缺点是这样的类不适合回掉框架。继承虽然好，我们却不应该滥用，只有我们能确定它们之间是is-a得关系的时候才使用。</DIV>
<DIV>Item 15:如果要用继承那么设计以及文档都要有质量保证，否则就不要用它</DIV>
<DIV>&nbsp;&nbsp;&nbsp; 为了避免继承带来的问题，你必须提供精确的文档来说明覆盖相关方法可能出现的问题。在构造器内千万不要调用可以被覆盖的方法，因为子类覆盖方法的时候会出现问题。<BR>import java.util.*;</DIV>
<DIV>public class SubClass extends SuperClass<BR>{<BR>&nbsp;private final Date date;<BR>&nbsp;<BR>&nbsp;public SubClass()<BR>&nbsp;{<BR>&nbsp; date = new Date(); <BR>&nbsp;}<BR>&nbsp;<BR>&nbsp;public void m()<BR>&nbsp;{<BR>&nbsp; System.out.println(date); <BR>&nbsp;}<BR>&nbsp;<BR>&nbsp;public static void main(String[] args)<BR>&nbsp;{<BR>&nbsp; SubClass s = new SubClass();<BR>&nbsp; s.m(); <BR>&nbsp;}<BR>&nbsp;<BR>}</DIV>
<DIV>class SuperClass<BR>{<BR>&nbsp;public SuperClass()<BR>&nbsp;{<BR>&nbsp; m(); <BR>&nbsp;} <BR>&nbsp;<BR>&nbsp;public void m()<BR>&nbsp;{<BR>&nbsp; <BR>&nbsp;}<BR>}<BR>由于在date被初始化之前super（）已经被调用了，所以第一次输出null而不是当前的时间。<BR>由于在Clone()或者序列化的时候非常类似构造器的功能，因此readObject()和clone（）方法内最好也不要包括能被覆盖的方法。</DIV>
<DIV>Item 16:在接口和抽象类之间优先选择前者<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 接口和抽象类都用来实现多态，不过我们应该优先考虑用接口。知道吗？James说过如果要让他重新设计java的话他会把所有都设计成接口的。抽象类的优点是方便扩展，因为它是被继承的，并且方法可以在抽象类内实现，接口则不行。</DIV>
<DIV>Item 17：接口只应该用来定义类型<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 接口可以这样用的 Collection c = new xxxx();这是我们最常用的。不要把接口用来做其他的事情，比如常量的定义。你应该定义一个类，里面包含public final static 得字段。</DIV>
<DIV>Item 18: 在静态和非静态内部类之间选择前者<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果一个类被定义在其他的类内部那么它就是嵌套类，可以分为静态内部类、非静态内部类和匿名类。<BR>&nbsp;&nbsp; static member class 得目的是为enclosing class服务，如果还有其他的目的，就应该把它设计成top-level class。nonstatic member class是和enclosing class instance关联的，如果不需要访问enclosing class instance的话应该把它设计成static得，不然会浪费时间和空间。anonymous class是声明和初始化同时进行的。可以放在代码的任意位置。典型应用是Listener 和process object例如Thread。</DIV>
<DIV>&nbsp;&nbsp;&nbsp; 由于以前学过C语言，所以对C还是蛮有感情，而JAVA和C又有很多相似之处，很多从C转过来学习JAVA的兄弟，可能一开始都不是很适应，因为很多在C里面的结构在JAVA里面都不能使用了，所以下面我们来介绍一下C语言结构的替代。</DIV>
<DIV>Item 19:用类代替结构<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JAVA刚面世的时候，很多C程序员都认为用类来代替结构现在太复杂，代价太大了，但是实际上，如果一个JAVA的类退化到只包含一个数据域的话，这样的类与C语言的结构大致是等价的。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 比方说下面两个程序片段：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Point<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private float x;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private float y;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 实际上这段代码和C语言的结构基本上没什么区别，但是这段代码恐怕是众多OO设计Fans所不齿的，因为它没有体现封装的优异性，没有体现面向对象设计的优点，当一个域被修改的时候，你不可能再采取任何辅助的措施了，那我们再来看一看采用包含私有域和共有访问方法的OO设计代码段：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Point<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private float x;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private float y;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Point(float x,float y)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.x=x;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.y=y;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public float getX(){retrun x;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public float getY(){return y;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setX(float x){this.x=x;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setY(float y){this.y=y;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 单从表面上看，这段代码比上面那个多了很多行，还多了很多函数，但是仔细想一下，这样的OO设计，似乎更人性化，我们可以方面的对值域进行提取，修改等操作，而不直接和值域发生关系，这样的代码不仅让人容易读懂，而且很安全，还吸取了面向对象程序设计的灵活性，试想一下，如果一个共有类暴露它的值域，那么想要在将来的版本中进行修改是impossible的，因为共有类的客户代码已经遍布各处了。<BR>需要提醒一点的是，如果一个类是包级私有的，或者是一个私有的嵌套类，则直接暴露其值域并无不妥之处。</DIV>
<DIV>Item 20：用类层次来代替联合<BR>我们在用C语言来进行开发的时候，经常会用到联合这个概念，比如：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; typedef struct{<BR>&nbsp;&nbsp;&nbsp;&nbsp; double length;<BR>&nbsp;&nbsp;&nbsp;&nbsp; double width;&nbsp;&nbsp;&nbsp;&nbsp; <BR>}rectangleDimensions_t;<BR>那我们在JAVA里面没有联合这个概念，那我们用什么呢？对！用继承，这也是JAVA最吸引我的地方之一，它可以使用更好的机制来定义耽搁数据类型，在Bruce Eckel的Thinking in java里面也多次提到了一个和形状有关的例子，我们可以先笼统的定义一个抽象类，即我们通常所指的超类，每个操作定义一个抽象的方法，其行为取决于标签的值，如果还有其他的操作不依赖于标签的值，则把操作变成根类（继承的类）中的具体方法。<BR>这样做的最重要的优点是：类层次提供了类型的安全性。<BR>其次代码非常明了，这也是OO设计的优点。<BR>而且它很容易扩展，即使是面向多个方面的工作，能够同样胜任。<BR>最后它可以反映这些类型之间本质上的层次关系，从而允许更强的灵活性，以便编译时类型检查。</DIV>
<DIV>Item 21：用类来代替enum结构<BR>Java程序设计语言提出了类型安全枚举的模式来替代enum结构，它的基本思想很简单：定义一个类来代表枚举类型的单个元素，并且不提供任何公有的构造函数，相反，提供公有静态final类，使枚举类型中的每一个常量都对应一个域。<BR>类型安全枚举类型的一个缺点是，装载枚举类的和构造常量对象时，需要一定的时间和空间开销，除非是在资源很受限制的设备比如蜂窝电哈和烤面包机上，否则在实际中这个问题不会被考虑。<BR>&nbsp;总之，类型安全枚举类型明显优于int类型，除非实在一个枚举类型主要被用做一个集合元素，或者主要用在一个资源非常不受限的环境下，否则类型安全枚举类型的缺点都不成问题，依次，在要求使用一个枚举类型的环境下，我们首先应考虑类型安全枚举类型模式。</DIV>
<DIV>Item 22：用类和接口来代替函数指针<BR>&nbsp;class StringLengthComprator{<BR>public int compare(String s1,String s2)<BR>{<BR>return s1.length()-s2.length();<BR>}<BR>}<BR>这个类导出一个带两个字符串的方法，它是一个用于字符串比较的具体策略。它是无状态的，没有域，所以，这个类的所有实例在功能上都是等价的，可以节省不必要的对象创建开销。但是我们不好直接把这个类传递给可户使用，因为可户无法传递任何其他的比较策略。相反，我们可以定义一个接口，即我们在设计具体策略类的时候还需要定义一个策略接口：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public interface Comparator{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int compare(Object o1,Object o2);<BR>}<BR>&nbsp; 我们完全可以依照自己的需要来定义它。<BR>在JAVA中，我们为了实现指针的模式，声明一个接口来表示该策略，并且为每个具体策略声明一个实现了该接口的类，如果一个具体策略只被使用一次的话，那么通常使用匿名类来声明和实例化这个具体策略类，如果一个策略类反复使用，那么它的类通常是一个私有的的静态成员类。 <BR>下面我们来讨论一下有关方法设计的几个方面，下面说的几个要点大多数都是应用在构造函数中，当然也使用于普通方法，我们追求的依然是程序的可用性，健壮性和灵活性。</DIV>
<DIV>Item 23：检查参数的有效性<BR>非公有的方法我们应该用断言的方法来检查它的参数，而不是使用通常大家所熟悉的检查语句来检测。如果我们使用的开发平台是JDK1.4或者更高级的平台，我们可以使用assert结构；否则我们应该使用一种临时的断言机制。<BR>有些参数在使用过程中是先保存起来，然后在使用的时候再进行调用，构造函数正是这种类型的一种体现，所以我们通常对构造函数参数的有效性检查是非常仔细的。</DIV>
<DIV>Item 24：需要时使用保护性拷贝<BR>众所周知，JAVA在代码安全性方面较C/C++有显著的提高，缓冲区溢出，数组越界，非法指针等等，我们的JAVA都有一个很完善的机制来进行免疫，但是这并不代表我们不必去考虑JAVA的安全性，即便在安全的语言，如果不采取措施，还是无法使自己与其他类隔开。假设类的客户会尽一切手段来破坏这个类的约束条件，在这样的前提下，你必须从保护性的方面来考虑设计程序。通过大量的程序代码研究我们得出这样的结论：对于构造性函数的每个可变参数进行保护性拷贝是必要的。需要注意的是，保护性拷贝是在检查参数的有效性之前 进行的，并且有效性检查是针对拷贝之后的对象，而不是原始的对象。对于“参数类型可以被不可信方子类化”的情况，不要用clone方法来进行参数的保护性拷贝。<BR>对于参数的保护性拷贝并不仅仅在于非可变类，当我们编写一个函数或者一个构造函数的时候，如果它要接受客户提供的对象，允许该对象进入到内部数据结构中，则有必要考虑一下，客户提供的对象是否是可变的，如果是，则要考虑其变化的范围是否在你的程序所能容纳的范围内，如果不是，则要对对象进行保护性拷贝，并且让拷贝之后的对象而不是原始对象进入到数据结构中去。当然最好的解决方法是使用非可变的对象作为你的对象内部足见，这样你就可以不必关心保护性拷贝问题了。）：</DIV>
<DIV>Item 25：谨慎使用设计方法的原型<BR>（1）谨慎的选择方法的名字：即要注意首先要是易于理解的，其次还要与该包中的其他方法的命名风格相一致，最后当然要注意取一个大众所认可的名字。<BR>（2）不要追求提供便利的方法：每一个方法都应该提供其应具备的功能点，对于接口和类来方法不要过多，否则会对学习使用维护等等方面带来许多不必要的麻烦，对于每一个类型所支持的每一个动作，都提供一个功能完全的方法，只有一个方法过于频繁的使用时，才考虑为它提供一个快捷方法。<BR>（3）避免过长的参数列表：通常在实践中，我们以三个参数作为最大值，参数越少越好，类型相同的长参数列尤其影响客户的使用，两个方法可以避免过长的参数这样的情况发生，一是把一个方法分解成多个，每一个方法只要求使用这些参数的一个子集；二是创建辅助类，用来保存参数的聚集，这些辅助类的状态通常是静态的。<BR>对于参数类型，优先使用接口而不是类。<BR>这样做的目的是避免影响效能的拷贝操作。<BR>谨慎的使用函数对象。<BR>创建函数对象最容易的方法莫过于使用匿名类，但是那样会带来语法上混乱，并且与内联的控制结构相比，这样也会导致功能上的局限性。</DIV>
<DIV>Item 26：谨慎的使用重载<BR>到底是什么造成了重载机制的混淆算法，这是个争论的话题，一个安全而保守的方法是，永远不要导出两个具有相同参数数目的重载方法。而对于构造函数来说，一个类的多个构造函数总是重载的，在某些情况下，我们可以选择静态工厂，但是对于构造函数来说这样做并不总是切合实际的。<BR>当涉及到构造函数时，遵循这条建议也许是不可能的，但我们应该极力避免下面的情形：<BR>同一组参数只需要经过类型的转换就可以传递给不同的重载方法。如果这样做也不能避免的话，我们至少要保证一点：当传递同样的参数时，所有的重载方法行为一致。如果不能做到这一点，程序员就不能有效的使用方法或者构造函数。</DIV>
<DIV>Item 27：返回零长度的数组而不是null<BR>因为这样做的原因是编写客户程序的程序员可能忘记写这种专门的代码来处理null返回值。没有理由从一个取数组值的方法中返回null，而不是返回一个零长度数组。</DIV>
<DIV>Item 28：为所有导出的API元素编写文档注释<BR>不爱写注释可能是大多数程序员新手的通病（包括偶哈~），但是如果想要一个API真正可用，就必须写一个文档来说明它，保持代码和文档的同步是一件比较烦琐的事情，JAVA语言环境提供了javadoc工具，从而使这个烦琐的过程变得容易，这个工具可以根据源代码自动产生API文档。<BR>为了正确得编写API文档，我们必须每一个被导出的类，接口，构造函数，方法和域声明之前加一个文档注释。<BR>每一个方法的文档注释应该见解的描述它和客户之间的约定。<BR>我们接下来讨论一下Java语言的细节，包括局部变量的处理，库的使用，以及两种不是语言本身提供的机制的使用等等一些大家平时可能忽略的问题。</DIV>
<DIV>Item 29:将局部变量的作用域最小化<BR>和C语言要求局部变量必须被生命在代码的开始处相比，Java程序设计语言宽松得多，它允许你在代码的任何位置声明。要想使一个局部变量的作用域最小化，最高小的技术是在第一次需要使用它的地方声明，变量的作用域是从声明它的地方开始到这个声明做在的代码块的结束位止，如果我们把变量的声明和代码的使用位置分开的过大，那么对于读这段代码的人来说，是很不幸的。<BR>我们几乎都是在一个局部变量声明的地方同时给它初始化，注意这是很重要的，甚至有时候，如果我们的初始化应该推迟到下一个代码的位置，我们同时应该把声明也往后延迟。这条规则唯一的例外是try-catch这个语句，因为如果一个变量被方法初始化，那么这个方法很有可能抛出一个异常，那我们最常用的方法就是把它置于try块的内部去进行初始化。由此我们可以得出，for循环优于while循环，我们在能使用for循环的地方尽量使用for而不使用while，因为for循环是完全独立的，所以重用循环变量名字不会有任何伤害。<BR>最后我们要记住的是尽量把我们的函数写的小而集中，这样才能真正组做到”最小化局部变量的作用域”这一要旨。</DIV>
<DIV>Item 30：了解和使用库<BR>使用标准库，我们可以充分利用编写这些库的Java专家的知识，以及在你之前其他人的使用经验，这就是所谓站在巨人的肩膀上看世界吧~<BR>在每一个Java平台的发行版本里面，都会有许多新的包的加入，和这些更新保持一直是值得的，比如说我们J2ME的开发，在MIDP 1.0的时代，我们要写个Game还要自己动手写工具类，现在MIDP2.0推出之后，大多数写游戏的人都觉得方便了很多，因为在这个版本里面加入了游戏包，为我们的开发节省了大量的人力物力。</DIV>
<DIV>Item 31：如果想要知道精确的答案，就要避免使用double和float<BR>&nbsp;&nbsp;&nbsp;&nbsp; 对于金融行业来说，对数据的严整性要求是很高的，不容半点马虎，那大家都知道再我们的Java语言里面有两个浮点数类型的变量float和double，可能大家会认为他们的精度对于金融行业这样对数字敏感的行业来说，已经够用了，但是在开发当中，我们要尽量少使用double和float，因为让他们精确的表达0.1是不可能的。那我们如何解决这个问题呢，答案是使用BigDecimal,int或者long进行货币计算。在这里对大家的忠告是：对于商务运算，我们尽量使用BigDecimal，对于性能要求较高的地方，我们有能力自己处理十进制的小数点，数值不太大的时候，我们可以使用int或者long，根据自己的需要来判定具体使用哪一个，如果范围超过了18位数，那我们必须使用BigDecimal。</DIV>
<DIV>Item 32：如果其他类型更适合，则尽量避免使用字符串<BR>&nbsp;&nbsp;&nbsp;&nbsp; 在偶看到这条建议之前，我就很喜欢用字符串，不管在什么场合下，先String了再说，但是实际上很多情况下，我们要根据实际情况来判定到底使用什么类型，而且字符串不适合替代枚举类型，类型安全枚举类型和int值都比字符串更适合用来表示枚举类型的常量。字符串也不适合替代聚集类型，有一个更好的方法就是简单的写一个类来描述这个数据集，通常是一个私有的静态成员类最好。字符串也不适合代替能力表，总而言之，如果可以适合更加适合的数据类型，或者可以编写更加适当的数据类型，那么应该避免使用字符串来表示对象。</DIV>
<DIV>Item 33：了解字符串的连接功能<BR>我们经常在使用System.out.println()的时候，往括号里写一串用“+”连接起来的字符串，这是我们最常见的，但是这个方法并不适合规模较大的情形，为连接N个字符串而重复地使用字符串连接操作符，要求N的平方级的时间，这是因为字符串是非可变的，这就导致了在字符串进行连接的时候，前后两者都要拷贝，这个时候我们就提倡使用StingBuffer替代String。</DIV>
<DIV>Item 34：通过接口引用对象<BR>通俗的说就是尽量优先使用接口而不是类来引用对象，如果有合适的接口存在那么对使用参数，返回值，变量域都应该使用接口类型养成使用接口作为对象的习惯，会使程序变得更加灵活。<BR>如果没有合适的接口，那么，用类而不是接口来引用一个对象，是完全合适的。</DIV>
<DIV>Item 35：接口优先于映像机制<BR>java.lang.relect提供了“通过程序来访问关于已装载的类的信息”，由此，我们可以通过一个给定的Class实例，获得Constructor,Method和Field实例。<BR>映像机制允许一个类使用另一个类，即使当前编译的时候后者还不存在，但是这种能力也要付出代价：<BR>我们损失了了编译时类型检查的好处，而且要求执行映像访问的代码非常笨拙和冗长，并且在性能上大大损失。<BR>通常，普通应用在运行时刻不应以映像方式访问对象。</DIV>
<DIV>Item 36：谨慎的使用本地方法<BR>JNI允许Java应用程序调用本地方法，所谓本地方法是指用本地程序设计语言（如C，C++）来编写的特殊方法，本地方法可以在本地语言执行任何计算任务，然后返回到Java程序设计语言中。但是随着JDK1.3及后续版本的推出这种通过使用本地方法来提高性能的方法已不值得提倡，因为现在的JVM越来越快了，而且使用本地方法有一些严重的缺点，比如使Java原本引以为傲的安全性荡然无存，总之在使用本地方法的时候要三思。</DIV>
<DIV>Item 37：谨慎使用优化<BR>不要因为性能而牺牲合理的代码结构，努力编写好的程序而不是快的程序，但是避免那些限制性能的设计决定，同时考虑自己设计的API决定的性能后果，为了获得更好的性能而对API进行修改这也是一个非常不好的想法，通常我们在做优化之后，都应该对优化的程度进行一些测量。</DIV>
<DIV>Item 38：遵守普遍接受的命名惯例<BR>Java有一套比较完善的命名惯例机制，大部分包含在《The Java Language Specification》，严格得讲这些惯例分成两类，字面的和语法的。<BR>字面涉及包，类，接口，方法和域，语法的命名惯例比较灵活，所以争议更大，字面惯例是非常直接和明确的，而语法惯例则相对复杂，也很松散。但是有一个公认的做法是：“如果长期养成的习惯用法与此不同的话，请不要盲目遵从 </DIV><img src ="http://www.blogjava.net/gufen/aggbug/13993.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gufen/" target="_blank">落花飞雪</a> 2005-09-25 15:24 <a href="http://www.blogjava.net/gufen/archive/2005/09/25/13993.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《Practical Java》笔记</title><link>http://www.blogjava.net/gufen/archive/2005/09/25/13992.html</link><dc:creator>落花飞雪</dc:creator><author>落花飞雪</author><pubDate>Sun, 25 Sep 2005 07:22:00 GMT</pubDate><guid>http://www.blogjava.net/gufen/archive/2005/09/25/13992.html</guid><wfw:comment>http://www.blogjava.net/gufen/comments/13992.html</wfw:comment><comments>http://www.blogjava.net/gufen/archive/2005/09/25/13992.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/gufen/comments/commentRss/13992.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gufen/services/trackbacks/13992.html</trackback:ping><description><![CDATA[<P>1.&nbsp;声明是什么?<BR>String s = "Hello world!";</P>
<P>许多人都做过这样的事情，但是，我们到底声明了什么？回答通常是：一个String，内容是“Hello world!”。这样模糊的回答通常是概念不清的根源。如果要准确的回答，一半的人大概会回答错误。<BR>这个语句声明的是一个指向对象的引用，名为“s”，可以指向类型为String的任何对象，目前指</P>
<P>1.&nbsp;声明是什么?<BR>String s = "Hello world!";</P>
<P>许多人都做过这样的事情，但是，我们到底声明了什么？回答通常是：一个String，内容是“Hello world!”。这样模糊的回答通常是概念不清的根源。如果要准确的回答，一半的人大概会回答错误。<BR>这个语句声明的是一个指向对象的引用，名为“s”，可以指向类型为String的任何对象，目前指向"Hello world!"这个String类型的对象。这就是真正发生的事情。我们并没有声明一个String对象，我们只是声明了一个只能指向String对象的引用变量。所以，如果在刚才那句语句后面，如果再运行一句：</P>
<P>String string = s;</P>
<P>我们是声明了另外一个只能指向String对象的引用，名为string，并没有第二个对象产生，string还是指向原来那个对象，也就是，和s指向同一个对象。<BR>2.&nbsp;String类的特殊性<BR>1)&nbsp;String s1 = “Hello”;&nbsp; //产生一个String ”Hello”对象,并产生该对象的一个别名s1来引用该对象<BR>String s2 = “Hello”;&nbsp; //又产生一个别名s2来引用上面的”Hello”对象<BR>s1 == s2 = true;&nbsp;&nbsp; //由于是同一个对象所以“==”返回为true<BR>s1 = “World”;&nbsp; //产生一个String ”World”对象, s1的引用不再指向“Hello”而是指向对象”World”<BR>s1 == s2 = false;&nbsp;&nbsp; //由于不是同一个对象所以“==”返回为false<BR>s1 = “Hello”;&nbsp; //同上面的String s2 = “Hello”; 现在s1又指向对象”Hello”, 因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。<BR>s1 == s2 = true;&nbsp;&nbsp; //由于是同一个对象所以“==”又返回为true了<BR>s1 = s1 + “World”;&nbsp; //这时又产生一个对象”HelloWord”,s1不再指向”Hello”而是指向”HelloWord”<BR>s1 == s2 = false;&nbsp; //不是一个对象当然是false拉<BR>s1 = s1+ "a"+"b"+"c"+…;&nbsp; // String不停的创建对象,影响性能，这种易变的String用StringBuffer会得到更好的性能<BR>StringBuffer s3 = new StringBuffer(“Hello”); <BR>s3.append(“a”); //没有生成新的对象，而是将s3引用的对象内容改为”Helloa”</P>
<P>//说明: String类用来表示那些创建后就不会再改变的字符串，它是immutable的。而StringBuffer类用来表示内容可变的字符串，并提供了修改底层字符串的方法。<BR>StingBuffer是一个可变的字符串，它可以被更改。同时StringBuffer是Thread safe的， 你可以放心的使用.</P>
<P>因为String被设计成一种安全的字符串， 避免了C/C++中的尴尬。因此在内部操作的时候会频繁的进行对象的交换， 因此它的效率不如StringBuffer。 如果需要频繁的进行字符串的增删操作的话最好用StringBuffer。 比如拼SQL文， 写共函。 另： 编绎器对String的+操作进行了一定的优化。 <BR>x = "a" + 4 + "c"<BR>会被编绎成<BR>x = new StringBuffer().append("a").append(4).append("c").toString()<BR>但：<BR>x = “a”;<BR>x = x + 4;<BR>x = x + “c”;<BR>则不会被优化。 可以看出如果在一个表达式里面进行String的多次+操作会被优化， 而多个表达式的+操作不会被优化。<BR>摘自：《Java API Using, Tips And Performance Tuning》<BR><FONT color=#000000>2)&nbsp;Integer、Boolean等wrapper类以及BigInteger、BigDecimal是immutable的，所以也有与String类似的地方，不过没有IntegerBuffer之类的东西。不过Float, Double比较特殊。如<BR>T a1 = 10; //T代指Byte,Integer,Short,Long,Boolean。 注：应用了JDK5的AUTOBOXING<BR>T a2 = 10;<BR>if (a1 == a2)<BR>&nbsp;System.out.println(true);<BR>else<BR>&nbsp;System.out.println(false);<BR>这时总是true,和String有点类似</FONT></P>
<P><FONT color=#000000>//Float时<BR>Float i1 =&nbsp; (float)10.0;<BR>Float i2 =&nbsp; (float)10.0;<BR>if (i1==i2)<BR>&nbsp;&nbsp;&nbsp;System.out.println(true);<BR>else<BR>&nbsp;&nbsp;&nbsp;System.out.println(false);<BR>这时总是false<BR><BR>//Double时<BR>Double i1 =&nbsp; 10.0;<BR>Double i2 =&nbsp; 10.0;<BR>if (i1==i2)<BR>&nbsp;&nbsp;&nbsp;System.out.println(true);<BR>else<BR>&nbsp;&nbsp;&nbsp;System.out.println(false);<BR>这时总是false<BR></FONT></P>
<P><FONT color=#000000>总之如果比较两个Wrapper类的值用equals，以免不必要的麻烦<BR></FONT>3)&nbsp;再看<BR>String s1 = new String(“Hello”);<BR>String s2 = new String(“Hello”);<BR>s1 == s2 = false;<BR>//因为new的时候JVM不管heap中有没有”Hello”对象都会产生一个新的”Hello”对象<BR>String s3 = “Hello”; //重新创建对象”Hello”, 并令s3指向对象”Hello”<BR>s3 == s1 = false; //不同对象当然false<BR>String s4 = “Hello”; <BR>s3 == s4 = true;&nbsp; //故伎重演，jvm清楚的知道哪些用了new，哪些没用new<BR><BR>3.&nbsp;方法的参数传递中都是以reference传递，而primitive传递的是副本，但如果传递的是Integer、Boolean等wrapper类和String类的Object则是以immutable方式传递。示例：<BR>import java.awt.Point;<BR>class HelloWorld<BR>{<BR>&nbsp; public static void modifyPoint(Point pt, String j, int k, Integer m, Boolean b)<BR>&nbsp; {<BR>&nbsp;&nbsp;&nbsp; pt.setLocation(5,5);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; j = "15";<BR>&nbsp;&nbsp;&nbsp; k = 25;<BR>&nbsp;&nbsp;&nbsp; m = 35;<BR>&nbsp;&nbsp;&nbsp; b = true;<BR>&nbsp;&nbsp;&nbsp; System.out.println("During modifyPoint " + "pt = " + pt +<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " and j = " + j+ " and k = "+ k+ <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " and m = "+ m+ " and b = "+ b);<BR>&nbsp; }</P>
<P>&nbsp; public static void main(String args[])<BR>&nbsp; {<BR>&nbsp;&nbsp;&nbsp; Point p = new Point(0,0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; String i = "10";<BR>&nbsp;&nbsp;&nbsp; int k = 20;<BR>&nbsp;&nbsp;&nbsp; Integer m = 30;<BR>&nbsp;&nbsp;&nbsp; Boolean b = false;<BR>&nbsp;&nbsp;&nbsp; System.out.println("Before modifyPoint " + "p = " + p +<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " and i = " + i+ " and k = "+ k+ <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " and m = "+ m+ " and b = "+ b);<BR>&nbsp;&nbsp;&nbsp; modifyPoint(p, i, k, m, b);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; System.out.println("After modifyPoint " + "p = " + p +<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " and i = " + i+ " and k = "+ k+ <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " and m = "+ m+ " and b = "+ b);<BR>&nbsp; }<BR>}<BR>输出结果：<BR>Before modifyPoint p = java.awt.Point[x=0,y=0] and i = 10 and k = 20 and m = 30 and b = false<BR>During modifyPoint pt = java.awt.Point[x=5,y=5] and j = 15 and k = 25 and m = 35 and b = true<BR>After modifyPoint p = java.awt.Point[x=5,y=5] and i = 10 and k = 20 and m = 30 and b = false<BR>4.&nbsp;final作用于基本类型变量则该变量为恒常量；final作用于对象类型变量则该对象reference为恒量；final作用于方法则该方法不能被覆盖；final作用于class则该class不能被继承。<BR>final使得被修饰的变量"不变"，但是由于对象型变量的本质是“引用”，使得“不变”也有了两种含义：引用本身的不变，和引用指向的对象不变。</P>
<P>引用本身的不变：<BR>final StringBuffer a=new StringBuffer("immutable");<BR>final StringBuffer b=new StringBuffer("not immutable");<BR>a=b;//编译期错误</P>
<P>引用指向的对象不变：<BR>final StringBuffer a=new StringBuffer("immutable");<BR>a.append(" broken!"); //编译通过</P>
<P>可见，final只对引用的“值”(也即它所指向的那个对象的内存地址)有效，它迫使引用只能指向初始指向的那个对象，改变它的指向会导致编译期错误。至于它所指向的对象的变化，final是不负责的。这很类似==操作符：==操作符只负责引用的“值”相等，至于这个地址所指向的对象内容是否相等，==操作符是不管的。</P>
<P>理解final问题有很重要的含义。许多程序漏洞都基于此----final只能保证引用永远指向固定对象，不能保证那个对象的状态不变。在多线程的操作中,一个对象会被多个线程共享或修改，一个线程对对象无意识的修改可能会导致另一个使用此对象的线程崩溃。一个错误的解决方法就是在此对象新建的时候把它声明为final，意图使得它“永远不变”。其实那是徒劳的。<BR>5.&nbsp;怎样初始化<BR>本问题讨论变量的初始化，所以先来看一下Java中有哪些种类的变量。<BR>1). 类的属性，或者叫值域<BR>2). 方法里的局部变量<BR>3). 方法的参数</P>
<P>对于第一种变量，Java虚拟机会自动进行初始化。如果给出了初始值，则初始化为该初始值。如果没有给出，则把它初始化为该类型变量的默认初始值。</P>
<P>primitive类型默认值<BR>boolean: false<BR>char: '\u0000'&nbsp; 对于未初始化的char c, c == ‘\u0000’ = true<BR>byte: 0<BR>short: 0<BR>int: 0<BR>long: 0<BR>float: 0.0<BR>double: 0.0<BR>object reference: null<BR>array: null<BR>注意数组本身也是对象，所以没有初始化的数组引用在自动初始化后其值也是null。</P>
<P>对于两种不同的类属性，static属性与instance属性，初始化的时机是不同的。instance属性在创建实例的时候初始化，static属性在类加载，也就是第一次用到这个类的时候初始化，对于后来的实例的创建，不再次进行初始化。</P>
<P>对于第二种变量，必须明确地进行初始化。如果再没有初始化之前就试图使用它，编译器会抗议。如果初始化的语句在try块中或if块中，也必须要让它在第一次使用前一定能够得到赋值。也就是说，把初始化语句放在只有if块的条件判断语句中编译器也会抗议，因为执行的时候可能不符合if后面的判断条件，如此一来初始化语句就不会被执行了，这就违反了局部变量使用前必须初始化的规定。但如果在else块中也有初始化语句，就可以通过编译，因为无论如何，总有至少一条初始化语句会被执行，不会发生使用前未被初始化的事情。对于try-catch也是一样，如果只有在try块里才有初始化语句，编译部通过。如果在 catch或finally里也有，则可以通过编译。总之，要保证局部变量在使用之前一定被初始化了。所以，一个好的做法是在声明他们的时候就初始化他们，如果不知道要出事化成什么值好，就用上面的默认值吧！</P>
<P>其实第三种变量和第二种本质上是一样的，都是方法中的局部变量。只不过作为参数，肯定是被初始化过的，传入的值就是初始值，所以不需要初始化。<BR>6.&nbsp;尽量使用多态(polymorphism)特性而不是instanceof<BR>7.&nbsp;一旦不需要对象，尽量显式的使之为null<BR>8.&nbsp;对象之间的”=”赋值操作乃是赋值的reference, 即左边的对象也指向右边的对象，只是该reference多了一个别名而已。<BR>9.&nbsp;“==”和equals()的区别<BR>==操作符专门用来比较变量的值是否相等。比较好理解的一点是：<BR>int a=10;<BR>int b=10;<BR>则a==b将是true。<BR>但不好理解的地方是：<BR>String a=new String("foo");<BR>String b=new String("foo");<BR>则a==b将返回false。</P>
<P>根据前一帖说过，对象变量其实是一个引用，它们的值是指向对象所在的内存地址，而不是对象本身。a和b都使用了new操作符，意味着将在内存中产生两个内容为"foo"的字符串，既然是“两个”，它们自然位于不同的内存地址。a和b的值其实是两个不同的内存地址的值，所以使用"=="操作符，结果会是 false。诚然，a和b所指的对象，它们的内容都是"foo"，应该是“相等”，但是==操作符并不涉及到对象内容的比较。<BR>对象内容的比较，正是equals方法做的事。</P>
<P>看一下Object对象的equals方法是如何实现的：<BR>boolean equals(Object o){</P>
<P>return this==o;</P>
<P>}<BR>Object 对象默认使用了==操作符。所以如果你自创的类没有覆盖equals方法，那你的类使用equals和使用==会得到同样的结果。同样也可以看出， Object的equals方法没有达到equals方法应该达到的目标：比较两个对象内容是否相等。因为答案应该由类的创建者决定，所以Object把这个任务留给了类的创建者。</P>
<P>看一下一个极端的类：<BR>Class Monster{<BR>private String content;<BR>...<BR>boolean equals(Object another){ return true;}</P>
<P>}<BR>我覆盖了equals方法。这个实现会导致无论Monster实例内容如何，它们之间的比较永远返回true。</P>
<P>所以当你是用equals方法判断对象的内容是否相等，请不要想当然。因为可能你认为相等，而这个类的作者不这样认为，而类的equals方法的实现是由他掌握的。如果你需要使用equals方法，或者使用任何基于散列码的集合（HashSet,HashMap,HashTable），请察看一下java doc以确认这个类的equals逻辑是如何实现的。<BR>10.&nbsp;不要依赖equals()的缺省实现<BR>11.&nbsp;一个equals()的实现模版<BR>class Golfball<BR>{<BR>&nbsp; private String brand;<BR>&nbsp; private String make;<BR>&nbsp; private int compression;</P>
<P>&nbsp; public boolean equals(Object obj)<BR>&nbsp; {</P>
<P>&nbsp;&nbsp;&nbsp; if (this == obj)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;</P>
<P>&nbsp;&nbsp;&nbsp; if (obj != null &amp;&amp; getClass() == obj.getClass())<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Golfball gb = (Golfball)obj;&nbsp; //Classes are equal, downcast.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (brand.equals(gb.brand()) &amp;&amp;&nbsp; //Compare attributes.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; make.equals(gb.make()) &amp;&amp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; compression == gb.compression())<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; return false;<BR>&nbsp; }<BR>}<BR>注意getClass() == obj.getClass()的限制，如果判断必须相等则无法比较基类和子类是否相等,完全不同的类不用考虑，完全没有可比性，除了特殊需要或很糟糕的程序。<BR>12.&nbsp;实现equals()应优先考虑使用getClass()<BR>13.&nbsp;如果某个基类我们自己实现了equals()，在它的子类中要覆盖此方法，最好调用super.equals()唤起base class的相关行为,然后再实现子类域的比较。<BR>Example:<BR>&nbsp; public boolean equals(Object obj)<BR>&nbsp; {<BR>&nbsp;&nbsp;&nbsp; if (this == obj)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //1<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;</P>
<P>&nbsp;&nbsp;&nbsp; if (obj != null &amp;&amp; getClass() == obj.getClass() &amp;&amp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //2<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.equals(obj))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //3<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MyGolfball gb = (MyGolfball)obj;&nbsp; //Classes equal, downcast.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ballConstruction == gb.construction())&nbsp; //Compare attrs.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; return false;<BR>&nbsp; }<BR>14.&nbsp;如果要在base class与derived class之间应运equals(),可以考虑instanceof来代替getClass()。对此论题的详细讨论参见:Practical Java, Practice 14<BR>15.&nbsp;instanceof什么东西？<BR>instanceof是Java的一个二元操作符，和==，&gt;，&lt;是同一类东东。由于它是由字母组成的，所以也是Java的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例，返回boolean类型的数据。举个例子：</P>
<P>String s = "I AM an Object!";<BR>boolean isObject = s instanceof Object;</P>
<P>我们声明了一个String对象引用，指向一个String对象，然后用instancof来测试它所指向的对象是否是Object类的一个实例，显然，这是真的，所以返回true，也就是isObject的值为True。<BR>instanceof有一些用处。比如我们写了一个处理账单的系统，其中有这样三个类：</P>
<P>public class Bill {//省略细节}<BR>public class PhoneBill extends Bill {//省略细节}<BR>public class GasBill extends Bill {//省略细节}</P>
<P>在处理程序里有一个方法，接受一个Bill类型的对象，计算金额。假设两种账单计算方法不同，而传入的Bill对象可能是两种中的任何一种，所以要用instanceof来判断：</P>
<P>public double calculate(Bill bill) {<BR>if (bill instanceof PhoneBill) {<BR>//计算电话账单<BR>}<BR>if (bill instanceof GasBill) {<BR>//计算燃气账单<BR>}<BR>...<BR>}<BR>这样就可以用一个方法处理两种子类。</P>
<P>然而，这种做法通常被认为是没有好好利用面向对象中的多态性。其实上面的功能要求用方法重载完全可以实现，这是面向对象变成应有的做法，避免回到结构化编程模式。只要提供两个名字和返回值都相同，接受参数类型不同的方法就可以了：</P>
<P>public double calculate(PhoneBill bill) {<BR>//计算电话账单<BR>}</P>
<P>public double calculate(GasBill bill) {<BR>//计算燃气账单<BR>}</P>
<P>所以，使用instanceof在绝大多数情况下并不是推荐的做法，应当好好利用多态。<BR>16.&nbsp;认真对待异常。<BR>1).在方法体用throws子句抛出异常时尽量包括所有出现的异常，而不是仅仅抛出base exception.<BR>2).在super class中定义的方法抛出某个异常，如果在deriver class中要override该方法，那么overriding method必须：<BR>a.&nbsp;不抛出任何异常<BR>b.&nbsp;抛出和super class 中同样的异常<BR>c.&nbsp;抛出和super class 中异常的deriver class<BR>如果super class中定义的方法没有抛出异常，但deriver class中的override的方法会产生异常，必须自己内部解决<BR>&nbsp;3).好好利用finally功能。一般只要有finally，它总是会被执行，除非在try中用System.exit(0)或者在try块执行期间强行拔掉电源。finally被执行有三种情况：<BR>a.&nbsp;抛出异常<BR>b.&nbsp;try正常结束<BR>c.&nbsp;在try中执行了return, break, continue而引起离开try的操作<BR>尤其注意c.如果方法中在try块return 1,而在finally块return 2,则最终永远是2，因此尽量避免在try中使用return, break, continue，要么确保在finally中不会改变返回值<BR>&nbsp;4).不要在循环体中使用try,因为在无JIT的JVM中将大大降低性能，而且这也是良好的编程习惯<BR>&nbsp;5).不要将异常用于控制流程，而是仅仅用于会发生错误的地方<BR>&nbsp;6).不要每逢出错就使用异常，尽量使用传统的方法判断变量的有效性<BR>17.&nbsp;关于不可变类(Immutable class),如String、Byte、Integer、Short、Long、Float、Double、BigInteger、BigDecimal等，它们之所以能将同一值自动地指向同一引用，实际上是它们实现了静态工厂方法。</P><img src ="http://www.blogjava.net/gufen/aggbug/13992.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gufen/" target="_blank">落花飞雪</a> 2005-09-25 15:22 <a href="http://www.blogjava.net/gufen/archive/2005/09/25/13992.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>derby(cloudscape)数据库初探(二)—eclipse中对derby的访问</title><link>http://www.blogjava.net/gufen/archive/2005/09/25/13991.html</link><dc:creator>落花飞雪</dc:creator><author>落花飞雪</author><pubDate>Sun, 25 Sep 2005 07:21:00 GMT</pubDate><guid>http://www.blogjava.net/gufen/archive/2005/09/25/13991.html</guid><wfw:comment>http://www.blogjava.net/gufen/comments/13991.html</wfw:comment><comments>http://www.blogjava.net/gufen/archive/2005/09/25/13991.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/gufen/comments/commentRss/13991.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gufen/services/trackbacks/13991.html</trackback:ping><description><![CDATA[<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在(一)中提到以嵌入式引擎作为db不是很清楚其工作方式，后来考虑了下大概就是个强大的Access数据库，这种方式下我觉得将它作为Access数据库来进行理解比较直观些。</P>
<P>目前我就用了eclipse下访问derby的3个插件：</P>
<P>1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ibm和apache的两个插件一起使用，安装后在java项目点击右键后出现“Apache Derby”,里面有一个菜单“Add Apache Derby nature”,点击后将出现start、ij、sysinfo工具，这个插件就这些东西。</P>
<P>2)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;用Quantum或dbedit插件访问derby.dbedit插件比较强大些，可以可视的进行表的alert操作，好像没有proc,view的显示界面。Quantum有proc,view的显示界面，但是没法可视进行添加表功能。两个都有可视sql edit界面。我没搞定如何用derby的jdbc进行对数据库的访问，只能用db2的jdbc访问，url为：jdbc:db2://localhost:1527/"C:\IBM\Cloudscape_10.0\demo\databases\toursDB"</P><img src ="http://www.blogjava.net/gufen/aggbug/13991.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gufen/" target="_blank">落花飞雪</a> 2005-09-25 15:21 <a href="http://www.blogjava.net/gufen/archive/2005/09/25/13991.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>derby（cloudscape）数据库初探(一)</title><link>http://www.blogjava.net/gufen/archive/2005/09/25/13990.html</link><dc:creator>落花飞雪</dc:creator><author>落花飞雪</author><pubDate>Sun, 25 Sep 2005 07:20:00 GMT</pubDate><guid>http://www.blogjava.net/gufen/archive/2005/09/25/13990.html</guid><wfw:comment>http://www.blogjava.net/gufen/comments/13990.html</wfw:comment><comments>http://www.blogjava.net/gufen/archive/2005/09/25/13990.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gufen/comments/commentRss/13990.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gufen/services/trackbacks/13990.html</trackback:ping><description><![CDATA[1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 该数据库可在IBM和Apache两处下载，cloudscape是derby数据库的商业版本，由IBM赠送与Apache后的称呼。<BR>Apache一方目前版本是Derby 10.1.0.0 alpha (Apr 28, 2005 / SVN 165185)。由于alpha版，而且Derby 10.0.2.2 (Apr 28, 2005 / SVN 165169)版本的数据库提供的附加工具及少，所以我是去IBM网站下载的数据库。<BR>IBM网站目前版本是V10.0.2.0&nbsp; Build: 30301，提供3种类型的下载，有installer的linux,win32和没有installer一个单一的zip包文件。win32中包括jdk1.4,考虑到我的机器已经被迫安装了n个jdk，故此我下载了单一zip包的cloudscape。IBM下载地址为：<A href="http://www-128.ibm.com/developerworks/cn/db2/library/techarticles/dm-0408cline/index.html"><FONT color=#4563b9>http://www-128.ibm.com/developerworks/cn/db2/library/techarticles/dm-0408cline/index.html</FONT></A>，需要以自己的mail作为id注册一个用户才能下载。<BR>2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下载后运行java –jar 10.0-IBM-Cloudscape.jar,出现安装界面，在这里需要指定安装目录，需要注意的是安装目录尽量不要带有空格。<BR>3.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 安装完后需要进行一些环境变量的设置，请根据自己的实际情况增加以下环境变量：<BR>数据库安装目录环境变量：<BR>CLOUDSCAPE_INSTALL= D:\IBM\Cloudscape_10.0<BR>classpath中增加：<BR>.;%CLOUDSCAPE_INSTALL%\lib\derby.jar;%CLOUDSCAPE_INSTALL%\lib\derbynet.jar;%CLOUDSCAPE_INSTALL%\lib\derbytools.jar;%CLOUDSCAPE_INSTALL%\lib\db2jcc.jar;%CLOUDSCAPE_INSTALL%\lib\db2jcc_license_c.jar<BR>path中增加：<BR>%CLOUDSCAPE_INSTALL%\frameworks\NetworkServer\bin<BR>4.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 现在就可以对数据库进行操作。该数据库提供两种模式的数据库引擎：1. 服务器架构中充当客户机/服务器的引擎。2. 作为可嵌入类库的数据库引擎。在c/s引擎应该比较了解。可嵌入类库的数据库引擎就是和java程序运行在同一JVM中，不需要启动数据库，不需要对数据库进行管理（对这个我也知道个大概，呵呵）。<BR>1．C/S模式下的数据库访问：<BR>打开dos界面，敲入startNetworkServer启动数据库，再打开一个dos界面敲ij以进行数据库管理。<BR>在D:\IBM\Cloudscape_10.0\demo\databases下有一toursDB的demo数据库，我们要连至该数据库我们可以在ij下敲入：connect 'jdbc:derby:net://localhost:1527/"D:\IBM\Cloudscape_10.0\demo\databases\toursDB"'<BR>例如以下我是对数据库的一些简单操作：<BR>--连接数据库：<BR>ij&gt; connect 'jdbc:derby:net://localhost:1527/"D:\IBM\Cloudscape_10.0\demo\databases\toursDB"';<BR>--创建一个名为abc的表：<BR>ij&gt; create table abc (a int, b int);<BR>0 rows inserted/updated/deleted<BR>--往abc表中插入数据，没into还报错，用sybase用习惯了。<BR>ij&gt; insert abc values(1,2);<BR>ERROR 42X01: DB2 SQL error: SQLCODE: -1, SQLSTATE: 42X01, SQLERRMC: Encountered "abc" at line 1, column 8?42X0(?代表一个怪字符，spaces上发布的时候提示“此空间暂时不可用”，没办法只好用?代替啦，发现问题浪费了我十几分钟时间，TNND)<BR>--这次数据进去了<BR>ij&gt; insert into abc values(1,2);<BR>1 row inserted/updated/deleted<BR>--察看刚才插入的数据<BR>ij&gt; select * from abc;<BR>A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |B<BR>-----------------------<BR>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2<BR>1 row selected<BR>--断开数据库连接，没有任何信息输出<BR>ij&gt; disconnect;<BR>--退出ij<BR>ij&gt; exit;<BR>注意命令结束符是分号“；”<BR>如果要停止数据库在dos中敲入stopnetworkserver即可。<BR>2．可嵌入类库模式下对DB的访问（该模式下不需要启动数据库，且ij中只能有一个连接操作数据库）<BR>我的toursDB数据库目录为C:\IBM\Cloudscape_10.0\demo\databases下，如果我们DOS界面所在的目录已经在在该目录，则进入ij后直接敲入“connect 'jdbc:derby:toursDB';”就可以连接至数据库，否则得指定数据库所在路径“connect 'jdbc:derby:C:\IBM\Cloudscape_10.0\demo\databases\toursDB';”。下面是我对数据库的一些访问：<BR>ij&gt; connect 'jdbc:derby:toursDB';<BR>ij&gt; select * from cities;<BR>CITY_ID&nbsp;&nbsp;&nbsp; |CITY_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |COUNTRY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |AIRPORT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |LANGUAGE<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |COU&amp;<BR>----------------------------------------------------------------------------------------------------<BR>------------<BR>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |Amsterdam&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |Netherlands&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |AMS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |Dutch<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NL<BR>……………………………等等<BR>87 rows selected<BR>ij&gt; disconnect;<BR>ij&gt; exit;<BR>C:\IBM\Cloudscape_10.0\demo\databases&gt;<BR>其中cities是toursDB数据库自带的一个表，其它的表还有airlines, countries,flightavailability,flights,flights_history,maps。<BR>关于数据库的一些操作命令可在ij下敲入help;进行察看，详细的帮助信息在D:\IBM\Cloudscape_10.0\doc\pdf中，IBM的developerWorks下的DB2有很多介绍cloudscape相关技术的文章，网址：<A href="http://www-128.ibm.com/developerworks/cn/index.html"><FONT color=#4563b9>http://www-128.ibm.com/developerworks/cn/index.html</FONT></A>。 还有IBM的在线帮助手册有3本是中文的，网址：<A href="http://www.elink.ibmlink.ibm.com/public/applications/publications/cgibin/pbi.cgi?CTY=US&amp;FNC=ICL"><FONT color=#4563b9>http://www.elink.ibmlink.ibm.com/public/applications/publications/cgibin/pbi.cgi?CTY=US&amp;FNC=ICL</FONT></A>，进去后选择cloudscape。<img src ="http://www.blogjava.net/gufen/aggbug/13990.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gufen/" target="_blank">落花飞雪</a> 2005-09-25 15:20 <a href="http://www.blogjava.net/gufen/archive/2005/09/25/13990.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MyEclipse中配置Weblogic(转)</title><link>http://www.blogjava.net/gufen/archive/2005/09/25/13989.html</link><dc:creator>落花飞雪</dc:creator><author>落花飞雪</author><pubDate>Sun, 25 Sep 2005 07:19:00 GMT</pubDate><guid>http://www.blogjava.net/gufen/archive/2005/09/25/13989.html</guid><wfw:comment>http://www.blogjava.net/gufen/comments/13989.html</wfw:comment><comments>http://www.blogjava.net/gufen/archive/2005/09/25/13989.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/gufen/comments/commentRss/13989.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gufen/services/trackbacks/13989.html</trackback:ping><description><![CDATA[<P>转自<A href="http://dev2dev.bea.com.cn/bbs"><FONT color=#4563b9>http://dev2dev.bea.com.cn/bbs</FONT></A>,作者:<A title=钟伟海 href="http://dev2dev.bea.com.cn/bbs/profile.jspa?userID=2012"><FONT color=#4563b9>newwei</FONT></A></P>
<P>1)选择菜单Window-&gt;Preferences-&gt;MyEclipse-&gt;Application Servers-&gt;Weblogic 8，配置项目如下：<BR>BEA home directory: 选择Bea的安装目录<BR>Weblogic installation directory:现在BEA下面的weblogic81目录<BR>Admin username:输入上面在配置过程中设的用户名<BR>Admin password:输入刚才设的密码<BR>Execution domain root:选择BEA下user_projects\domains目录下上面第一步创建的目录<BR>Execution domain name:输入上面那个目录的名称<BR>Execution server name:输入上一步的那个Congfiguration Name<BR>Hostname:PortNumber:输入IP地址和监听的端口<BR>Security policy file:输入BEA安装目录下的\weblogic81\server\lib\weblogic.policy<BR>(2)在Weblogic 8下面配置JDK，在WLS JDK name那里选择新建，弹出的对话框中选择BEA下面的JDK安装路径，输入一个名字确定就可以；在Optional Java VM arguments对话框里面输入-ms64m -mx64m -Djava.library.path="D:/BEA/weblogic81/server/bin" -Dweblogic.management.discover=false -Dweblogic.ProductionModeEnabled=false<BR>(3在Weblogic 8下面配置Paths，加入BEA安装路径下/weblogic81/server/lib中的webservices.jar和weblogic.jar两个包。如果需要其他的包，也在这里加入。</P>
<P>PS:我使用的环境是Eclipse 3.0.3和MyEclipse3.8.4，操作系统是Windows 2000</P><img src ="http://www.blogjava.net/gufen/aggbug/13989.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gufen/" target="_blank">落花飞雪</a> 2005-09-25 15:19 <a href="http://www.blogjava.net/gufen/archive/2005/09/25/13989.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat下JSP、Servlet和JavaBean环境的配置 </title><link>http://www.blogjava.net/gufen/archive/2005/09/25/13988.html</link><dc:creator>落花飞雪</dc:creator><author>落花飞雪</author><pubDate>Sun, 25 Sep 2005 07:17:00 GMT</pubDate><guid>http://www.blogjava.net/gufen/archive/2005/09/25/13988.html</guid><wfw:comment>http://www.blogjava.net/gufen/comments/13988.html</wfw:comment><comments>http://www.blogjava.net/gufen/archive/2005/09/25/13988.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.blogjava.net/gufen/comments/commentRss/13988.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gufen/services/trackbacks/13988.html</trackback:ping><description><![CDATA[<P><FONT color=#000000>版本：Tomcat 5.5.9，Win2000</FONT></P>
<P dir=ltr><FONT color=#000000><STRONG>1.&nbsp;安装jdk5.0, jre5.0，之后设置环境变量</STRONG><BR>增加如下系统环境变量(注：jdk安装目录D:\jdk15)。<BR>java_home= D:\jdk15<BR>classpath=.;%java_home%\lib\tools.jar;%java_home%\lib\dt.jar; <BR>path系统变量中增加%java_home%\bin;(尽量加在最前面)<BR><STRONG>2.&nbsp;安装Tomcat</STRONG><BR>&nbsp;&nbsp;&nbsp; 一路“下一步”安装完成，途中有确认jre路径界面需要注意。启动Tomcat服务后在游览器中敲入</FONT><A href="http://127.0.0.1:8080/"><FONT color=#3300ff>http://127.0.0.1:8080/</FONT></A><FONT color=#000000>或者</FONT><A href="http://localhost:5000/"><FONT color=#0000ff>http://localhost:<FONT color=#3300ff>8080</FONT>/</FONT></A><FONT color=#000000>后出现传说中丑陋的三脚Cat即安装成功。<BR>&nbsp;&nbsp;增加如下系统环境变量<BR>&nbsp;&nbsp;CATALINA_HOME= C:\Program Files\Apache Software Foundation\Tomcat 5.5（我是默认安装）<BR>classpath中增加以下内容<BR>%CATALINA_HOME%\common\lib\servlet-api.jar;%CATALINA_HOME%\common\lib\jasper-runtime.jar;%CATALINA_HOME%\common\lib\jsp-api.jar;<BR>TOMCAT的一些JAVA CLASS都在%CATALINA_HOME%\common\lib，如果jsp,bean编译不过去，看看错误如果有not found class之类的，就去%CATALINA_HOME%\common\lib下找，找到后加至classpath中就可以了。<BR><STRONG>3.&nbsp;发布第一个jsp：HelloWord</STRONG><BR>Tomcat所有的程序均发布在D:\Program Files\Apache Software Foundation\Tomcat 5.5\webapps路径的各个目录里，在2中看见的丑陋猫就是ROOT下的index.jsp。<BR>在webapps下建立一个目录mytest,然后拷贝ROOT下的WEB-INF目录到mytest目录，这里面是一些配置文件。之后在mytest中建立文件HelloWorld.jsp，文件内容为：<BR>&lt;%@ page language="java" %&gt;<BR>&lt;html&gt;<BR>&nbsp;&lt;head&gt;&lt;title&gt;&lt;/title&gt;&lt;/head&gt;<BR>&nbsp;&lt;body&gt;<BR>&nbsp;&nbsp;&lt;center&gt;<BR>&nbsp;&nbsp;&nbsp;&lt;%! String str = new String("HelloWorld!"); %&gt;<BR>&nbsp;&nbsp;&nbsp;&lt;font color="blue"&gt;&lt;%= str %&gt; &lt;/font&gt;&lt;br&gt;<BR>&nbsp;&nbsp;&lt;/center&gt;<BR>&nbsp;&lt;/body&gt;<BR>&lt;/html&gt;<BR>保存后在游览器中输入</FONT><A href="http://127.0.0.1:5000/mytest/HelloWorld.jsp"><FONT color=#3300ff>http://127.0.0.1:8080/mytest/HelloWorld.jsp</FONT></A><FONT color=#000000>, 如果没有意外的话应该执行成功，表示已正式进入jsp世界，不行重起tomcat。<BR><STRONG>4.&nbsp;发布第一个servlet</STRONG><BR>&nbsp;在mytest\WEB-INF下新建classes目录，然后在classes下新建目录test,test目录中新建文件HelloServlet.java。内容为：<BR>package test; <BR>//因为我们的包为test所以以上一句必须有，如果直接是在classes下新建//HelloServlet.java，则不需要声明包。<BR>import java.io.*;<BR>import java.util.*;<BR>//导入servlet包<BR>import javax.servlet.*;<BR>public class HelloServlet extends GenericServlet<BR>{&nbsp;<BR>&nbsp;public void init(ServletConfig config)throws ServletException<BR>&nbsp;{<BR>&nbsp;&nbsp;super.init(config);<BR>&nbsp;&nbsp;//调用父类的初始化方法；也可以加入自己需要的初始化代码。<BR>&nbsp;}&nbsp;<BR>&nbsp;public void destroy(){<BR>&nbsp;&nbsp;//destroy方法中加入一些做最后清理工作的代码；<BR>}&nbsp;<BR>&nbsp;public String getServletInfo(){<BR>&nbsp;&nbsp;return "This servlet is a simple Servlet's example.";<BR>&nbsp;&nbsp;//返回此servlet的信息&nbsp;；<BR>&nbsp;}&nbsp;<BR>&nbsp;public void service(ServletRequest req,ServletResponse res)<BR>&nbsp;&nbsp;&nbsp;throws ServletException,IOException<BR>&nbsp;{&nbsp;&nbsp;//service是最主要的方法，提供服务<BR>&nbsp;&nbsp;//获得服务器当前时间。<BR>&nbsp;&nbsp;Date today=new Date();</FONT></P>
<P dir=ltr><FONT color=#000000>&nbsp;&nbsp;//获得响应用户请求的输出流，以反馈执行结果；<BR>&nbsp;&nbsp;ServletOutputStream out=res.getOutputStream();</FONT></P>
<P><FONT color=#000000>&nbsp;&nbsp;//通过输出流向客户端写回了一个HTML文件；<BR>&nbsp;&nbsp;out.println("&lt;html&gt;&lt;head&gt;&lt;title&gt;HelloServlet.java&lt;/title&gt;&lt;/head&gt;&lt;body&gt;");<BR>&nbsp;&nbsp;out.println("Hello,this is my first test.+&lt;BR&gt;");<BR>&nbsp;&nbsp;out.println("Today is "+today.toString()+"&lt;BR&gt;");<BR>&nbsp;&nbsp;out.println(getServletInfo()+"&lt;BR&gt;");<BR>&nbsp;}<BR>}</FONT></P>
<P><FONT color=#000000>&nbsp;之后编译HelloServlet.java ，在命令行中敲入javac HelloServlet.java。在游览器中查看该Servlet之前需要改动mytest\WEB-INF\web.xml文件，建立HelloServlet的映射。将以下代码拷贝至web.xml文件。<BR>&nbsp;&nbsp;&nbsp; &lt;servlet&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;HelloServlet&lt;/servlet-name&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-class&gt;test.HelloServlet&lt;/servlet-class&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/servlet&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;servlet-mapping&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;HelloServlet&lt;/servlet-name&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/servlet/HelloServlet&lt;/url-pattern&gt;<BR>&lt;/servlet-mapping&gt;<BR>保存后在游览器地址栏中敲入</FONT><A href="http://localhost:5000/mytest/servlet/HelloServlet"><FONT color=#3300ff>http://localhost:8080/mytest/servlet/HelloServlet</FONT></A><FONT color=#000000>后出现Hello,this is my first test.+等字样表示已经进入Servlet世界。<BR>注意我们将HelloServlet映射为/servlet/HelloServlet所以在</FONT><A href="http://localhost:8080/mytest"><FONT color=#3300ff>http://localhost:8080/mytest</FONT></A><FONT color=#000000>后敲入的是/servlet/HelloServlet；如果我们直接映射为/HelloServlet，即改为&lt;url-pattern&gt; /HelloServlet&lt;/url-pattern&gt;，则在游览器地址栏中敲入的应该是</FONT><A href="http://localhost:5000/mytest/"><A href="http://localhost:5000/mytest/HelloServlet"><FONT color=#0000ff>http://localhost:<FONT color=#3300ff>8080</FONT>/mytest/</FONT></A><FONT color=#009900><FONT color=#0000ff>HelloServlet</FONT></A><BR></FONT><FONT color=#000000><STRONG>5.&nbsp;发布第一个bean(这个例子应用了jsp页面)</STRONG><BR>1)&nbsp;先在C:\Program Files\Apache Software Foundation\Tomcat 5.5\webapps\mytest下建立一个htm文档transPara.htm<BR>内容为：<BR>&lt;html&gt;<BR>&nbsp;&lt;head&gt;<BR>&nbsp;&nbsp;&lt;title&gt;transPara.htm&lt;/title&gt;<BR>&nbsp;&lt;/head&gt;<BR>&lt;body&gt;<BR>&nbsp;&lt;form method="POST" action="acceptPara.jsp"&gt;<BR>&nbsp; &nbsp;&nbsp;&lt;p align="center"&gt;<BR>&nbsp;&nbsp;姓 名：&lt;input type="text" name="name" size="20"&gt;&lt;br&gt; <BR>&nbsp; &nbsp;&nbsp;年 龄：&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;input type="text" name="age" size="15"&gt;&lt;br&gt; <BR>&nbsp; &nbsp;&nbsp;性 别：&amp;nbsp;&amp;nbsp;&amp;nbsp; <BR>&nbsp;&nbsp;&nbsp;&lt;input type="radio" value="male" checked name="sex"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;男&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&nbsp; <BR>&nbsp; &nbsp;&nbsp;&nbsp;&lt;input type="radio" name="sex" value="female"&gt;女&lt;/p&gt; <BR>&nbsp; &nbsp;&nbsp;&lt;p align="center"&gt;<BR>&nbsp;&nbsp;&nbsp;&lt;input type="submit" value="submit" name="submit"&gt; <BR>&nbsp; &nbsp;&nbsp;&nbsp;&lt;input type="reset" value="reset" name="reset"&gt;&lt;/p&gt; <BR>&nbsp;&lt;/form&gt; <BR>&lt;/body&gt; <BR>&lt;/html&gt;<BR>2)&nbsp;在C:\Program Files\Apache Software Foundation\Tomcat 5.5\webapps\mytest下建立一个jsp文档acceptPara.jsp<BR>内容为：<BR>&lt;html&gt;<BR><U>&lt;</U></FONT><A href="mailto:%@ page"><FONT color=#000000>%@ page</FONT></A><FONT color=#000000> import="test.acceptPara" contentType="text/html;charset=gb2312"%&gt;<BR>&lt;jsp:useBean id="atest" class="test.acceptPara"/&gt;<BR>&lt;head&gt;&lt;title&gt;acceptPara.jsp&lt;/title&gt;&lt;/head&gt;<BR>&lt;body&gt;<BR>&lt;jsp:setProperty name="atest" property="*"/&gt;<BR>Value of property "name" : <BR>&lt;jsp:getProperty name="atest" property="name"/&gt;&lt;br&gt;<BR>Value of property "age" : <BR>&lt;jsp:getProperty name="atest" property="age"/&gt;&lt;br&gt;<BR>Value of property "sex" : <BR>&lt;jsp:getProperty name="atest" property="sex"/&gt;&lt;br&gt;<BR>Value of property "submit" :<BR>&lt;jsp:getProperty name="atest" property="submit"/&gt;&lt;br&gt;<BR>&lt;/body&gt;<BR>&lt;/html&gt;<BR>3)&nbsp;在C:\Program Files\Apache Software Foundation\Tomcat 5.5\webapps\mytest\WEB-INF\classes\test下建立bean: acceptPara.java<BR>内容为：<BR>package test; </FONT></P>
<P><FONT color=#000000>public class acceptPara{<BR>&nbsp;String name;<BR>&nbsp;int age;<BR>&nbsp;String sex;<BR>&nbsp;String submit;<BR>&nbsp;<BR>&nbsp;public void setName(String value){<BR>&nbsp;&nbsp;name=value;<BR>&nbsp;}&nbsp;<BR>&nbsp;public String getName(){<BR>&nbsp;&nbsp;return name;<BR>&nbsp;}&nbsp;<BR>&nbsp;public void setAge(int value){<BR>&nbsp;&nbsp;age=value;<BR>&nbsp;}&nbsp;<BR>&nbsp;public int getAge(){<BR>&nbsp;&nbsp;return age;<BR>&nbsp;}&nbsp;<BR>&nbsp;public void setSex(String value){<BR>&nbsp;&nbsp;sex=value;<BR>&nbsp;}&nbsp;<BR>&nbsp;public String getSex(){<BR>&nbsp;&nbsp;return sex;<BR>&nbsp;}&nbsp;<BR>&nbsp;public void setSubmit(String value){<BR>&nbsp;&nbsp;submit=value;<BR>&nbsp;}&nbsp;<BR>&nbsp;public String getSubmit(){<BR>&nbsp;&nbsp;return submit;<BR>&nbsp;}<BR>&nbsp;public void acceptPara(){}<BR>}<BR>编译该bean,之后在游览器地址栏中敲入</FONT><A href="http://localhost:8080/mytest/transPara.htm"><FONT color=#3300ff>http://localhost:8080/mytest/transPara.htm</FONT></A><FONT color=#000000>，我们可以看见有姓名、年龄、性别几个表单，输入各个项后点击submit就可以看到我们刚才输入的结果，大概返回结果如下：<BR>Value of property "name" : Joson<BR>Value of property "age" : 23<BR>Value of property "sex" : male<BR>Value of property "submit" : submit<BR></FONT></P><img src ="http://www.blogjava.net/gufen/aggbug/13988.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gufen/" target="_blank">落花飞雪</a> 2005-09-25 15:17 <a href="http://www.blogjava.net/gufen/archive/2005/09/25/13988.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>