﻿<?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-Flyingis-随笔分类-JavaSE</title><link>http://www.blogjava.net/flyingis/category/4268.html</link><description>Talking and thinking freely !&lt;br&gt;
Flying in the world of Java and GIS !</description><language>zh-cn</language><lastBuildDate>Mon, 28 May 2007 01:29:55 GMT</lastBuildDate><pubDate>Mon, 28 May 2007 01:29:55 GMT</pubDate><ttl>60</ttl><item><title>SuSE 9.1 平台 ArcIMS(JRE) 中文显示解决方案</title><link>http://www.blogjava.net/flyingis/archive/2007/05/28/120386.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Mon, 28 May 2007 01:29:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2007/05/28/120386.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/120386.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2007/05/28/120386.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/120386.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/120386.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 最初以为是操作系统的字体显示问题，但SuSE9.1本身是包含中文字体的，很容易让我们想到了JRE。<br><br>文章标题为《SuSE 9.1 平台 ArcIMS 中文显示解决方案》，ArcIMS运行于JRE环境之上，因此问题的根本在于SuSE9.1平台下JRE运行时环境的中文显示，通过文中介绍的方案可以解决SuSE9.1操作系统中运行于JRE之上的所有应用程序的中文显示问题，如ArcIMS Author打开SDE空间数据库时以中文命名的表无法显示，数据属性字段中的中文显示为乱码等等。&nbsp;&nbsp;<a href='http://www.blogjava.net/flyingis/archive/2007/05/28/120386.html'>阅读全文</a><img src ="http://www.blogjava.net/flyingis/aggbug/120386.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2007-05-28 09:29 <a href="http://www.blogjava.net/flyingis/archive/2007/05/28/120386.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>静态设计</title><link>http://www.blogjava.net/flyingis/archive/2006/12/27/90319.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Wed, 27 Dec 2006 08:16:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2006/12/27/90319.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/90319.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2006/12/27/90319.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/90319.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/90319.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 重新看看静态设计的优劣之处。&nbsp;&nbsp;<a href='http://www.blogjava.net/flyingis/archive/2006/12/27/90319.html'>阅读全文</a><img src ="http://www.blogjava.net/flyingis/aggbug/90319.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2006-12-27 16:16 <a href="http://www.blogjava.net/flyingis/archive/2006/12/27/90319.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Java Puzzlers]表达式随想</title><link>http://www.blogjava.net/flyingis/archive/2006/03/30/38379.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Thu, 30 Mar 2006 15:47:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2006/03/30/38379.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/38379.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2006/03/30/38379.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/38379.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/38379.html</trackback:ping><description><![CDATA[
		<font size="2">    作者：<a class="" title="" href="/flyingis/" target="_blank"><font color="#000080">Flyingis</font></a><br /><br />    前段时间到书店抱了几本书回来，虽说网上有很多电子版的资料，但有时候觉得一些比较经典、自己比较喜欢的书籍还是有必要捧在手上细读的，《Java Puzzlers》就是其中之一，没事的时候就喜欢拿出来翻翻，怕自己像看新闻报纸一样看过就淡忘了，还是略作笔记让自己多份思考。<br /><br />    软件开发人员无论最初是从哪种语言开始学习的，首先都要掌握该语言的编程基础，例如语句、表达式、变量、数据类型、运算符、字符串等等，这些基础性的知识简单，但细节却比较繁琐，不同的编译器也会有不同的编译规则。以前寝室有同学考过的全国计算机等级考试二级C语言的试题中，语言的础规则是出题者最热衷的题形之一，曾经也觉得出题者无聊，只重理论不看实际，毕竟一些表达方法和书写格式可以通过规范来约束简化，但是作为一名程序员，一个专业的开发人员，应该了解自己所使用语言的基础规则，有时候一些程序的BUG就是存在于这些不起眼，或是自己认为应该没有问题的地方。<br /><br />    Java语言的表达式和C/C++比较相近，但也存在一些差异，这些差异不仅仅是那些看得见的差异，还有隐性的，例如相同的表达式，编译的规则不同。因此，我们需要理解Java表达式的一些基础性知识，加深认识。<br /><br />1.  要精确表达一个浮点型变量，应该使用BigDecimal对象来构造这个实例，使用float或double在一般情况下只是提供了在一定精度范围下的一种近似，不能产生精确的结果。常用的数据库中都有与BigDecimal相对应的数据类型，有的更为详细。<br />2.  对于 long value = 30 * 300 * 3000 * 3000; 来说，long类型可以完整保存右边表达式计算的结果，但是右边表达式的计算是按照int类型进行的，只有当右边表达式计算完成后才会转换为long类型，在计算过程中，右边表达式的值就已经超出int范围，因此会出现计算溢出。<br />3.  通常我们使用最多的是十进制计算，和十进制不同的是，当十六进制或八进制常量的最高位被置位时，该常量是负值。<br />4.  注意数据类型之间的相互转换（特别是char类型和其他类型间的转换），以及三目运算符的第二和第三操作数类型不一致的情况处理。<br />5.  在C/C++中，操作符的操作数是从右向左计算，Java中相反。<br />6.  复合赋值操作和简单赋值操作在一般情况下是相同的，例如 x *= y 和 x = x * y ，但是当x和y类型不同时情况有所变化，例如当x为short类型，y为double类型时，x *= y的结果虽然和想象的有些出入，至少可以编译通过，但后者赋值却是非法的。<br /><br />    大家可以继续补充……<br /></font>
<img src ="http://www.blogjava.net/flyingis/aggbug/38379.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2006-03-30 23:47 <a href="http://www.blogjava.net/flyingis/archive/2006/03/30/38379.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java I/O中的对象序列化</title><link>http://www.blogjava.net/flyingis/archive/2006/01/08/27134.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Sun, 08 Jan 2006 05:13:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2006/01/08/27134.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/27134.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2006/01/08/27134.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/27134.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/27134.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p>作者：<A href="/flyingis/"><FONT color=#000080>Flyingis</FONT></A><BR><BR><SPAN lang=EN-US style="FONT-SIZE: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象序列化将那些实现了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Serializable</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口的对象转换成一个字节序列，并能够以后将这个字节序列完全恢复为原来的对象。利用对象的序列化，可以实现轻量级持久性，这意味着一个对象的生存周期并不取决于程序是否正在执行，它可以生存于程序的调用之间。通过将一个序列化对象写入磁盘，然后在重新调用程序时恢复该对象，就能够实现持久性的效果。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">JDO</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Hibernate</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">等中间件为我们提供了更规范、完善的持久化机制，这里所述只是最基本的基于文件</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">I/O</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的持久化。</SPAN></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象序列化主要是为了支持两种主要的特性，一是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">远程方法调用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(RMI)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，另外一个是序列化</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java Beans</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm 7.8pt 18pt; TEXT-INDENT: -18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 18.0pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; 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; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">实现了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Serializable</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口的对象的序列化</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 20pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm; mso-char-indent-count: 2.0"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">要序列化一个对象，首先要创建</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">OutputStream</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象，然后将其封装在一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ObjectOutputStream</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象内。此时，调用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">writeObject()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法将对象序列化并发送给</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">OutputStream</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。在反序列化时，需要将一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">InputStream</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">封装在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ObjectInputStream</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内，然后调用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">readObject()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，得到的结果是一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Object</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象，需要进行转型得到最后所需的对象。<SPAN style="COLOR: blue">需要注意的是，在对一个</SPAN></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue">Serializable</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象进行反序列化的过程中，没有调用任何构造器，包括缺省的构造器，整个对象都是通过从</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue">InputStream</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中取得数据恢复过来的。对象序列化是面向字节的，因此采用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue">InputStream</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue">OutputStream</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">层次结构。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm 7.8pt 18pt; TEXT-INDENT: -18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 18.0pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; 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; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">实现了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Externalizable</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口的对象的序列化</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 20pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm; mso-char-indent-count: 2.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">Externalizable</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口继承了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Serializable</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口，同时添加了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">writeExternal()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">readExternal()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，它们在序列化和反序列化过程中会被自动调用。出于安全的考虑，可以将需要序列化的对象在上述方法中显式处理，否则不用在上述两个方法内考虑。<SPAN style="COLOR: blue">注意，对于实现了</SPAN></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue">Serializable</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口的对象，对象完全以它存储的二进制位为基础来构造，不调用构造器。而对于一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue">Externalizable</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象，所有普通的缺省构造器都会被调用，然后调用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue">readExternal()</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm 7.8pt 18pt; TEXT-INDENT: -18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 18.0pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">3.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">transient</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">关键字</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 20pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm; mso-char-indent-count: 2.0"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在某些情况下，有些特定的子对象不希望</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">序列化机制自动保存与恢复，即使对象中的这些信息是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">private</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的，经过序列化处理，就可以通过读取文件或者拦截网络传输的方式来访问到它。实现了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Externalizable</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口的对象的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">writeExternal()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法可以对需要的对象进行显式的序列化，但是如果我们操作的是一个实现了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Serializable</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口的对象，就只能用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">transient</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">关键字逐个字段的关闭序列化，只需要在字段定义前加上该关键字即可。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm 7.8pt 18pt; TEXT-INDENT: -18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 18.0pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; 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; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">实现了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Serializable</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口的同时，提供两个方法</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 20pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm; mso-char-indent-count: 2.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">private void writeObject(ObjectOutputStream stream) throws IOException<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 20pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm; mso-char-indent-count: 2.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">private void readObject(ObjectInputStream stream) <o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 30pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm; mso-char-indent-count: 3.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">throws IOException, ClassNotFoundException<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 20pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm; mso-char-indent-count: 2.0"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这种方法使用起来比较混乱，仅仅提供了这样的一种功能，绝大多数情况下，使用前面三种方法就能满足需求。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P><img src ="http://www.blogjava.net/flyingis/aggbug/27134.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2006-01-08 13:13 <a href="http://www.blogjava.net/flyingis/archive/2006/01/08/27134.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>文件加锁基础</title><link>http://www.blogjava.net/flyingis/archive/2006/01/07/26973.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Sat, 07 Jan 2006 05:50:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2006/01/07/26973.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/26973.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2006/01/07/26973.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/26973.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/26973.html</trackback:ping><description><![CDATA[<SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21.85pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">作者：<A HREF="/flyingis/"><FONT color=#000080>Flyingis</FONT></A><BR><BR>&nbsp;&nbsp;&nbsp; 文件加锁是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">JDK1.4</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">引入的一种机制，它允许我们同步访问某个作为共享资源的文件。竞争同一文件的两个线程可能在不同的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">虚拟机上，或者一个是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">线程，另一个是操作系统中的某个本地线程。文件锁对其他的操作系统进程是可见的，因为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的文件加锁直接映射到了本地操作系统的加锁工具。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21.85pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通过对</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">FileChannel</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">调用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">tryLock()</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">lock()</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，就可以获得整个文件的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">FileLock</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。特殊的是，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">SocketChannel/DatagramChannel/ServerSocketChannel</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不需要加锁，因为它们是从单进程实体继承而来，我们通常不在两个进程之间共享网络的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">socket</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21.85pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">tryLock()</FONT></SPAN></B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是非阻塞式的，它设法获取锁，但如果不能获得，例如因为其他一些进程已经持有相同的锁，而且不共享时，它将直接从方法调用返回。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21.85pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">lock()</FONT></SPAN></B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是阻塞式的，它要阻塞进程直到锁可以获得，或调用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">lock()</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的线程中断，或调用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">lock()</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的通道关闭。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21.85pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对独占锁和共享锁的支持必须由底层的操作系统提供。锁的类型可以通过</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">FileLock.isShared()</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进行查询。另外，我们不能获取缓冲器上的锁，只能是通道上的。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21.85pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件加锁的实际应用之一：文件映射通常应用于大型的文件，我们可能需要对巨大的文件进行部分加锁，以便其他的进程可以修改文件中未被加锁的部分，数据库就是如此，使得多用户可以访问到未加锁的部分数据。其他的应用还知之甚少。</SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><BR></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p><BR></o:p></SPAN></P><img src ="http://www.blogjava.net/flyingis/aggbug/26973.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2006-01-07 13:50 <a href="http://www.blogjava.net/flyingis/archive/2006/01/07/26973.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java I/O中的数据编码转换</title><link>http://www.blogjava.net/flyingis/archive/2006/01/03/26436.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Tue, 03 Jan 2006 06:02:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2006/01/03/26436.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/26436.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2006/01/03/26436.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/26436.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/26436.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 20pt; mso-char-indent-count: 2.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">作者：<A HREF="/flyingis/"><FONT color=#000080>Flyingis</FONT></A><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JDK1.4</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">开始便引入了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">java.nio.*</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包，其目的在于提高</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">I/O</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的速度，这是因为该类库使用的结构更接近于操作系统执行</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">I/O</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的方式，即通过通道和缓冲器来读写数据。在实际应用中，和我们直接交互的是缓冲器，然后把缓冲器派送到通道，通道要么从缓冲器获得数据，要么向缓冲器发送数据。<BR></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 20pt; mso-char-indent-count: 2.0"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><BR>&nbsp;&nbsp;&nbsp; 在基于</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的各种开发中，字符编码是常见的问题之一，在最基本的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java I/O</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中也存在这种问题。新的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java I/O</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通过通道和缓冲器来读写数据，缓冲器容纳的是普通的字节，为了把它们转换成字符，我们要么在输入的时候对其进行编码，要么在从缓冲器输出时对它们进行解码。<BR></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><BR>import java.io.*;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">import java.nio.*;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">import java.nio.channels.*;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">import java.nio.charset.*;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">public class ByteToCharacter {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>private static final int SIZE = 1024;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public static void main(String[] args) throws Exception {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">FileChannel fc = new FileOutputStream(“Output.txt”).getChannel();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">ByteBuffer buffer = ByteBuffer.allocate(SIZE);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT color=#0000ff>/**<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 25.7pt; mso-char-indent-count: 2.57"><FONT color=#0000ff><SPAN lang=EN-US style="FONT-SIZE: 10pt">* </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在输入的时候进行编码方式一</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 25.7pt; mso-char-indent-count: 2.57"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT color=#0000ff>*/<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">fc.write(ByteBuffer.wrap(“Good holiday!”.getBytes(“UTF-16BE”)));&nbsp;&nbsp;<FONT color=#0000ff>// UTF-16BE可以更换为其他编码方式</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">fc.close();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">fc = new FileInputStream(“Output.txt”).getChannel();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">fc.read(buffer);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">buffer.flip();<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>//</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">准备从缓冲区读取已经写入的数据</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">System.out.println(buffer.asCharBuffer());<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT color=#0000ff>/**<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 25.7pt; mso-char-indent-count: 2.57"><FONT color=#0000ff><SPAN lang=EN-US style="FONT-SIZE: 10pt">* </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在输入的时候进行编码方式二</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 25.7pt; mso-char-indent-count: 2.57"><FONT color=#0000ff><SPAN lang=EN-US style="FONT-SIZE: 10pt">* </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通过</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">asCharBuffer()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法直接以</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">char</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形式将字符写入</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 25.7pt; mso-char-indent-count: 2.57"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT color=#0000ff>*/<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">fc = new FileOutputStream(“Output.txt”).getChannel();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">buffer.clear();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">buffer.asCharBuffer.put(“Good holiday has passed!”);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">fc.write(buffer);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">fc.close();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">fc = new FileInputStream(“Output.txt”).getChannel();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">buffer.clear();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">fc.read(buffer);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">buffer.flip();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">System.out.println(buffer.asCharBuffer());<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT color=#0000ff>/**<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 25.7pt; mso-char-indent-count: 2.57"><FONT color=#0000ff><SPAN lang=EN-US style="FONT-SIZE: 10pt">* </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">从缓冲器输出时进行编码</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 25.7pt; mso-char-indent-count: 2.57"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT color=#0000ff>*/<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">fc = new FileOutputStream(“Output.txt”).getChannel();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">fc.write(ByteBuffer.wrap(“Once again!”.getBytes()));<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">fc.close();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">fc = new FileInputStream(“Output.txt”).getChannel();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">buffer.clear();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">fc.read(buffer);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">buffer.flip();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">String encode = System.getProperty(“file.encoding”);<SPAN style="mso-spacerun: yes">&nbsp; </SPAN><FONT color=#0000ff>// </FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT color=#0000ff>平台缺省字符集，更加通用的方法，跨平台特性的体现之一</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">System.out.println(Charset.forName(encode).decode(buffer));<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<BR><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes"><BR>&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在上述代码中，如果不对从缓冲器写入的数据进行正确编码，那么当再次通过缓冲器读取这些数据时，将不能显示任何所需要的数据。<BR></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 20pt; mso-char-indent-count: 2.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><BR>&nbsp;&nbsp;&nbsp; JDK</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">java.nio.charset.Charset</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类提供了把数据编码成多种不同类型的字符集的工具，满足在各种应用中的编码需求。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P><img src ="http://www.blogjava.net/flyingis/aggbug/26436.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2006-01-03 14:02 <a href="http://www.blogjava.net/flyingis/archive/2006/01/03/26436.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java I/O中的设计模式</title><link>http://www.blogjava.net/flyingis/archive/2005/12/30/26118.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Fri, 30 Dec 2005 13:47:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/12/30/26118.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/26118.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/12/30/26118.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/26118.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/26118.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 20pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm; mso-char-indent-count: 2.0"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">作者：<A href="/flyingis/"><FONT color=#000080>Flyingis</FONT></A><BR><BR>&nbsp;&nbsp;&nbsp; 任何程序语言的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">I/O</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设计都是一项具有挑战的任务，因为数据的传输存在多种可能，这些可能不仅存在于数据发送端和接收端</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件、网络链接等</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，还存在于这些数据的多种存在方式，例如缓冲区数据、顺序存取数据、字符数据、字节数据等等。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">I/O</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用“流”这个抽象的概念，它屏蔽了实际的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">I/O</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设备中处理数据的细节。在实际的应用中，我们很少使用单一的类来创建流对象，而是通过多个对象来提供所需要的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">I/O</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">功能。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">从</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">1.0</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">到</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">1.1</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">到</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">1.4</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">多</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">I/O</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类库作了多次重大修改，具体的可以参考相关的书籍或</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><A href="http://www.sun.com/" target=_blank><FONT color=#a52a2a>Sun<SPAN lang=EN-US style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><SPAN lang=EN-US>官方网站</SPAN></SPAN></FONT></A></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。这里是从模式的角度来分析</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">I/O</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类库的设计。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 10pt">Strategy</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设计模式</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将会发生变化的代码封装在单独的类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(Strategy</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，供其他保持不变的类使用，实现某种算法或应用，这是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Strategy</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设计模式的一般思想。在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java I/O</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，一个典型的应用是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">File</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类，它可以代表一个特定文件的名称，也可以代表一个目录下一组文件的名称。当我们要查询显示一个目录下特定文件类型的所有文件对象信息时，就需要将这个目录下的文件过滤，找到所需要的对象。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P><SPAN lang=EN-US style="FONT-SIZE: 10pt">
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">import java.io.*;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">import java.util.*;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">import java.util.regex.*;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">public class AlphabeticComparator implements Comparator {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">public int compare(Object o1, Object o2) {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>String s1 = (String)o1;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>String s2 = (String)o2;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>return s1.toLowerCase().compareTo(s2.toLowerCase());<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>//</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">比较时不考虑大小写</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10.5pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">public class FruitList {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public static FilenameFilter filter(final String regex) {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">return new FilenameFilter() {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>private Pattern pattern = Pattern.compile(regex);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public boolean accept(File dir, String name) {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>return pattern.matcher(new File(name).getName()).matches();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 30.7pt; mso-char-indent-count: 3.07"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">};<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">public static void main(String[] args) {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>File path = new File(“.”);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>String[] list;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>if (args.length == 0)<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>list = path.list();<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>//</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">搜索出该目录下所有类型的文件</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 20pt; mso-char-indent-count: 2.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">else<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 20pt; mso-char-indent-count: 2.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>list = path.list(filter(args[0]));<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>//</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">搜索出该目录下指定类型的文件</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 20pt; mso-char-indent-count: 2.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">Arrays.sort(list, new AlphabeticComparator());<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 20pt; mso-char-indent-count: 2.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">for (int i = 0; i &lt; list.length; i++)<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 20pt; mso-char-indent-count: 2.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>System.out.println(list[i]);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">}</SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在上述代码中，有两个地方使用了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Strategy</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设计模式，一个是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">AlphabeticComparator</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类，用来在忽略字符串大小写的情况下提供排序的规则，另一个就是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">FilenameFilter</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口，使用了匿名内部类的设计，然后将其中实现的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">accept()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">规则提供给</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">File</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">list</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法使用。这里是用来判断正则表达式</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">regex</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是否和文件名匹配，当运行程序在命令操作符中输入</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">“E.*\.java”</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时，搜索到的是该目录下所有</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">.java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21.75pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">File</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类除了上述用法外，还可以创建或删除目录，查看文件的信息，包括文件大小、最后修改日期，读写状态等，具体的可以参考</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">JDK</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文档。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21.75pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 10pt">Decorator</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设计模式</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21.75pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><A href="http://www.j2eesp.com/" target=_blank><FONT color=#a52a2a>http://www.j2eesp.com</FONT></A></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">上有对</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Decorator</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设计模式的定义：动态给一个对象添加一些额外的职责，就像在墙上刷油漆。使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Decorator</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模式相比用生成子类方式达到功能的扩充显得更为灵活。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Decorator</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模式规定所有封装于初始对象内部的对象具有相同的接口，这使得该模式的应用具有透明性。</SPAN><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21.75pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java I/O</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设计中，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Decorator</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模式主要体现在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">filter</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类的设计上，抽象类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">filter</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是所有</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Decorator</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模式类的基类。但是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Decorator</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模式同样存在缺点：在编写程序时，它在给开发人员提供了灵活性的同时，增加了代码的复杂性，造成了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java I/O</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类操作不便，因为很多</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">I/O</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设计中都需要应用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Decorator</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模式，增加一些类来完成该设计。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21.75pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">例如在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java 1.0</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">FilterInputStream</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">从</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">InputStream</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中读取数据，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">FilterOutPutStream</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">向</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">OutputStream</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中写入数据，在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java 1.1</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，相应的有</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">FilterReader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">FilterWriter(</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">抽象类，没有子类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用于</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Decorator</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模式设计。举个简单的例子：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">import java.io.*;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">public class DecoratorDemo {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public static void main(String[] args) {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21.75pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">BufferedReader in = new BufferedReader(new FileReader(“FruitList.java”));<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21.75pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">String s = new String();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21.75pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">while ((s = in.readLine()) != null)</SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21.75pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>System.out.println(s);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21.75pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">in.close();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 10pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>BufferedReader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">FileReader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">完成了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Decorate</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模式设计，这两个类可以更换为其他具有相同功用的类(在Thinking in Java中称为“修饰器”类)来组合完成特定的任务，正如上文所述，这给开发者提供了多种组合方式，同时也相对的增加了复杂度。</SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&nbsp;&nbsp;&nbsp; <FONT color=#ff1493>最后，祝blogjava所有成员和Java、开源爱好者元旦快乐！幸福安康！</FONT></SPAN></P><img src ="http://www.blogjava.net/flyingis/aggbug/26118.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-12-30 21:47 <a href="http://www.blogjava.net/flyingis/archive/2005/12/30/26118.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java容器分析--Map</title><link>http://www.blogjava.net/flyingis/archive/2005/12/27/25534.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Tue, 27 Dec 2005 02:07:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/12/27/25534.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/25534.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/12/27/25534.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/25534.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/25534.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&nbsp;&nbsp;&nbsp; 作者：<A HREF="/flyingis/"><FONT color=#000080>Flyingis</FONT></A><BR><BR>标准的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类库中包含了几种类型的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Map</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，它们都拥有同样的基本接口</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Map</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，但是行为特性各不相同，主要表现在效率、键值对的保存、元素呈现次序、对象的保存周期和判定键是否等价的策略等方面。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">1.Map</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的功能方法</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">Map(interface): </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">维护</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">value</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的关联性，使得可以通过</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">查找</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">value</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">HashMap: Map</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">基于散列表的实现，取代了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Hashtable</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。插入和查询</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label/value</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的开销是固定的，并且可以通过构造器设置容量和负载因子，以调整容器的性能。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">LinkedHashMap: </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">HashMap</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的基础上做了一些改进，在迭代遍历它时，取得</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label/value</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的顺序是其插入的次序，或者是最近最少使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(LRU)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的次序，速度上比</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">HashMap</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">要慢一点，但在迭代访问时速度会更快，主要原因是它使用了链表维护内部次序。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">TreeMap: </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">查看</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label/value</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时，元素会被排序，其次序由</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Comparable</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Comparator</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">决定，因此查询所得到的结果是经过排序的。另外，它是唯一带有</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">subMap()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Map</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">具体类，即返回一个子树。它也是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">SortedMap</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口的唯一实现，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">subMap()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法也是从该接口继承的。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">WeakHashMap: Weak Key</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">映射，允许释放映射所指向的对象。当映射之外没有引用指向某个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时，此</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以被垃圾收集器回收。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">IdentityHashMap: </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">==</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">代替</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">equals()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进行比较的散列映射。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">2.hashCode()<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当使用标准库中的类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Integer</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">作为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">HashMap</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时，程序能够正常运行，但是使用自己创建的类作为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">HashMap</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时，通常犯一个错误。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">HashMap</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中通过</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">查找</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">value</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时，实际上是计算</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象地址的散列码来确定</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">value</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的。一般情况下，我们是使用基类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Object</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的方法</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">hashCode()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来生成散列码，它默认是使用对象的地址来计算的，因此由第一个对象</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">new Apple(5)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和第二个对象</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">new Apple(5)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">生成的散列码是不同的，不能完成正确的查找。通常，我们可以编写自己的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">hashCode()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法来覆盖基类的原始方法，但与此同时，我们必须同时实现</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">equals()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法来判断当前的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是否与表中存在的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">相同。正确的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">equals()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法满足五个条件：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm 6pt 18pt; TEXT-INDENT: -18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 18.0pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">(1)<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">自反性。对于任意的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">x</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">x.equals(x)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一定返回</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">true</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm 6pt 18pt; TEXT-INDENT: -18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 18.0pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">(2)<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对称性。对于任意的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">x</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">y</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，如果</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">y.equals(x)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">返回</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">true</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，则</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">x.equals(y)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">也返回</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">true</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm 6pt 18pt; TEXT-INDENT: -18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 18.0pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">(3)<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">传递性。对于任意的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">x</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">y</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">z</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，如果有</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">x.equals(y)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">返回</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">true</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">y.equals(z)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">返回</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">true</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，则</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">x.equals(z)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一定返回</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">true</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm 6pt 18pt; TEXT-INDENT: -18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 18.0pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">(4)<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一致性。对于任意的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">x</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">y</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，如果对象中用于等价比较的信息没有改变，那么无论调用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">x.equals(y)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">多少次，返回的结果应该保持一致，要么一直是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">true</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，要么一直是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">false</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm 6pt 18pt; TEXT-INDENT: -18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 18.0pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">(5)<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对任何不是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">null</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">x</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">x.equals(null)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一定返回</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">false</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; TEXT-INDENT: 18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">equals()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">比较的是对象的地址，如果要使用自己的类作为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">HashMap</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，必须同时重载</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">hashCode()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">equals()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; TEXT-INDENT: 18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用散列的目的：想要使用一个对象来查找另一个对象。使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">TreeSet</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">TreeMap</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">也能实现此目的。另外，还可以自己实现一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Map</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，此时，必须提供</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Map.entrySet()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法来生成</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Map.Entry</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Set</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; TEXT-INDENT: 18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用散列的价值：速度，散列使得查询可以快速进行。散列将</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">保存载数组中方便快速查询，因为存储一组元素最快的数据结构是数组，用它来表示</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的信息</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">后面有信息的描述</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，而不是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">本身。通过</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象计算得到一个数字，作为数组的下标，这个数字就是散列码</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">即前面所述的信息</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。该散列码具体是通过定义在基类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Object</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，可能由程序员自定义的类覆盖的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">hashCode()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法，即散列函数生成。为了解决数组容量带来的限制，可以使不同的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">生成相同的下标，保存在一个链表</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">list</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，每一个链表就是数组的一个元素。查询</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时就可以通过对</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">list</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的信息进行查找，当散列函数比较好，数组的每个位置中的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">list</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">长度较短，则可以快速查找到数组元素</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">list</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的某个位置，提高了整体速度。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; TEXT-INDENT: 18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">散列表中的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">slot</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通常称为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">bucket</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，为了使散列分步均匀，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">bucket</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的值一般取质数。但事实证明，质数实际上并不是散列</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">bucket</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的理想容量，近来</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">散列实现都使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">2</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的幂，具体如何验证以后再续。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">3.HashMap</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的性能因子</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">容量</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(capacity): </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">散列表中</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">bucket</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的数量。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">初始化容量</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(initial capacity): </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">创建散列表时</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">bucket</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的数量。可以在构造方法中指定</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">HashMap</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">HashSet</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的初始化容量。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">尺寸</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(size): </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">散列表中记录的数量。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数组的元素个数，非</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">list</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中元素总和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">)<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">负载因子</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(load factor): </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">尺寸</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">/</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">容量。负载因子为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">0</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，表示空的散列表，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">0.5</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表示半满的散列表。轻负载的散列表具有冲突少，适宜插入与查询的特点，但是使用迭代器遍历会比较慢。较高的负载会减少所需空间大小。当负载达到指定值时，容器会自动成倍地增加容量，并将原有的对象重新分配，存入新的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">bucket</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，这个过程称为“重散列”。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">4.</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">重写</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">hashCode()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的关键</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm 6pt 18pt; TEXT-INDENT: -18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 18.0pt; mso-list: l1 level1 lfo2; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">(1)<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对同一个对象调用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">hashCode()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">都应该生成同样的值。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm 6pt 18pt; TEXT-INDENT: -18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 18.0pt; mso-list: l1 level1 lfo2; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">(2)<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">hashCode()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法不要依赖于对象中易变的数据，当数据发生变化时，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">hashCode()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就会生成一个不同的散列码，即产生了一个不同的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">label</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm 6pt 18pt; TEXT-INDENT: -18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 18.0pt; mso-list: l1 level1 lfo2; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">(3)<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">hashCode()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不应依赖于具有唯一性的对象信息，例如对象地址。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm 6pt 18pt; TEXT-INDENT: -18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 18.0pt; mso-list: l1 level1 lfo2; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">(4)<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">散列码应该更关心速度，而不是唯一性，因为散列码不必是唯一的。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm 6pt 18pt; TEXT-INDENT: -18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 18.0pt; mso-list: l1 level1 lfo2; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">(5)<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">好的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">hashCode()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应该产生分步均匀的散列码。在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Effective Java(Addison-Wesley 2001)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Joshua Bloch</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">给</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">hashCode()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">给出了设计指导，可以参考。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">编写正确高效的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">hashCode()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">equals()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">可以参考</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Apache</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Jakarta Commons</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">项目中的工具。<BR><BR>其它相关内容：<BR><A href="/flyingis/archive/2005/12/15/24089.html"><FONT color=#000080>Java容器分析--数组</FONT></A><BR><A href="/flyingis/archive/2005/12/21/24951.html"><FONT color=#000080>Java容器分析--List和Set</FONT></A></SPAN><img src ="http://www.blogjava.net/flyingis/aggbug/25534.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-12-27 10:07 <a href="http://www.blogjava.net/flyingis/archive/2005/12/27/25534.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java容器分析--List和Set</title><link>http://www.blogjava.net/flyingis/archive/2005/12/21/24951.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Wed, 21 Dec 2005 07:06:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/12/21/24951.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/24951.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/12/21/24951.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/24951.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/24951.html</trackback:ping><description><![CDATA[<SPAN lang=EN-US><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&nbsp;&nbsp;&nbsp; 作者：<A HREF="/flyingis/"><FONT color=#000080>Flyingis</FONT></A><BR><BR>&nbsp;&nbsp;&nbsp; 容器类可以大大提高编程效率和编程能力，在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Java2</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，所有的容器都由</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">SUN</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">公司的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Joshua Bloch</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进行了重新设计，丰富了容器类库的功能。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Java2</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">容器类类库的用途是“保存对象”，它分为两类：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><FONT face="Times New Roman"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 10pt">Collection</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt">----</SPAN></FONT><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一组独立的元素，通常这些元素都服从某种规则。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">List</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">必须保持元素特定的顺序，而</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Set</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不能有重复元素。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 6pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Map</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">----</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">一组成对的“键值对”对象，即其元素是成对的对象，最典型的应用就是数据字典，并且还有其它广泛的应用。另外，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Map</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">可以返回其所有键组成的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Set</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">和其所有值组成的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Collection</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">，或其键值对组成的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Set</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">，并且还可以像数组一样扩展多维</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Map</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">，只要让</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Map</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">中键值对的每个“值”是一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Map</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">即可。</SPAN></SPAN></FONT><FONT size=2><BR><BR>1.</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=2>迭代器</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><FONT size=2><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></FONT></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><FONT size=2><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>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>Iterator</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">功能比较简单，并且只能单向移动：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm 7.8pt 18pt; TEXT-INDENT: -18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 18.0pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><FONT size=2><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; </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>iterator()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">要求容器返回一个</SPAN><SPAN lang=EN-US>Iterator</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。第一次调用</SPAN><SPAN lang=EN-US>Iterator</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></FONT></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm 7.8pt 18pt; TEXT-INDENT: -18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 18.0pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><FONT size=2><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; </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>next()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">获得序列中的下一个元素。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm 7.8pt 18pt; TEXT-INDENT: -18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 18.0pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><FONT size=2><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;&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>hasNext()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">检查序列中是否还有元素。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm 7.8pt 18pt; TEXT-INDENT: -18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 18.0pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><FONT size=2><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; </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>remove()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将迭代器新返回的元素删除。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 18pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><FONT size=2><SPAN lang=EN-US>Iterator</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>List</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设计的</SPAN><SPAN lang=EN-US>ListIterator</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">具有更多的功能，它可以从两个方向遍历</SPAN><SPAN lang=EN-US>List</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，也可以从</SPAN><SPAN lang=EN-US>List</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中插入和删除元素。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><FONT size=2><SPAN lang=EN-US>2.List</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的功能方法</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><FONT size=2><SPAN lang=EN-US>List(interface): </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">次序是</SPAN><SPAN lang=EN-US>List</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">最重要的特点；它确保维护元素特定的顺序。</SPAN><SPAN lang=EN-US>List</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为</SPAN><SPAN lang=EN-US>Collection</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">添加了许多方法，使得能够向</SPAN><SPAN lang=EN-US>List</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>LinkedList</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用</SPAN><SPAN lang=EN-US>)</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。一个</SPAN><SPAN lang=EN-US>List</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以生成</SPAN><SPAN lang=EN-US>ListIterator</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，使用它可以从两个方向遍历</SPAN><SPAN lang=EN-US>List</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，也可以从</SPAN><SPAN lang=EN-US>List</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中间插入和删除元素。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><FONT size=2><SPAN lang=EN-US>ArrayList: </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">由数组实现的</SPAN><SPAN lang=EN-US>List</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。它允许对元素进行快速随机访问，但是向</SPAN><SPAN lang=EN-US>List</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中间插入与移除元素的速度很慢。</SPAN><SPAN lang=EN-US>ListIterator</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">只应该用来由后向前遍历</SPAN><SPAN lang=EN-US>ArrayList</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，而不是用来插入和删除元素，因为这比</SPAN><SPAN lang=EN-US>LinkedList</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">开销要大很多。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><FONT size=2><SPAN lang=EN-US>LinkedList: </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对顺序访问进行了优化，向</SPAN><SPAN lang=EN-US>List</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>ArrayList</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>addFirst()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</SPAN><SPAN lang=EN-US>addLast()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</SPAN><SPAN lang=EN-US>getFirst()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</SPAN><SPAN lang=EN-US>getLast()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</SPAN><SPAN lang=EN-US>removeFirst()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</SPAN><SPAN lang=EN-US>removeLast()</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><SPAN lang=EN-US>LinkedList</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以当作堆栈、队列和双向队列使用。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><FONT size=2><SPAN lang=EN-US>3.Set</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的功能方法</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><FONT size=2><SPAN lang=EN-US>Set(interface): </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">存入</SPAN><SPAN lang=EN-US>Set</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的每个元素必须是唯一的，因为</SPAN><SPAN lang=EN-US>Set</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不保存重复元素。加入</SPAN><SPAN lang=EN-US>Set</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</SPAN><SPAN lang=EN-US>Object</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">必须定义</SPAN><SPAN lang=EN-US>equals()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法以确保对象的唯一性。</SPAN><SPAN lang=EN-US>Set</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">与</SPAN><SPAN lang=EN-US>Collection</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有完全一样的接口。</SPAN><SPAN lang=EN-US>Set</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口不保证维护元素的次序。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><FONT size=2><SPAN lang=EN-US>HashSet: </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为快速查找而设计的</SPAN><SPAN lang=EN-US>Set</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。存入</SPAN><SPAN lang=EN-US>HashSet</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的对象必须定义</SPAN><SPAN lang=EN-US>hashCode()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><FONT size=2><SPAN lang=EN-US>TreeSet: </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">保持次序的</SPAN><SPAN lang=EN-US>Set</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，底层为树结构。使用它可以从</SPAN><SPAN lang=EN-US>Set</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中提取有序的序列。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><FONT size=2><SPAN lang=EN-US>LinkedHashSet: </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">具有</SPAN><SPAN lang=EN-US>HashSet</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><SPAN lang=EN-US>Set</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时，结果会按元素插入的次序显示。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><FONT size=2><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>HashSet</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">采用散列函数对元素进行排序，这是专门为快速查询而设计的；</SPAN><SPAN lang=EN-US>TreeSet</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">采用红黑树的数据结构进行排序元素；</SPAN><SPAN lang=EN-US>LinkedHashSet</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内部使用散列以加快查询速度，同时使用链表维护元素的次序，使得看起来元素是以插入的顺序保存的。需要注意的是，生成自己的类时，</SPAN><SPAN lang=EN-US>Set</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">需要维护元素的存储顺序，因此要实现</SPAN><SPAN lang=EN-US>Comparable</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口并定义</SPAN><SPAN lang=EN-US>compareTo()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法。<BR><BR>其它相关内容：<BR><A href="/flyingis/archive/2005/12/15/24089.html"><FONT color=#000080>Java容器分析--数组</FONT></A><BR><A href="/flyingis/archive/2005/12/27/25534.html"><FONT color=#000080>Java容器分析--Map</FONT></A></SPAN></FONT></P><img src ="http://www.blogjava.net/flyingis/aggbug/24951.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-12-21 15:06 <a href="http://www.blogjava.net/flyingis/archive/2005/12/21/24951.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ClassCastException深入分析</title><link>http://www.blogjava.net/flyingis/archive/2005/12/18/24514.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Sun, 18 Dec 2005 10:57:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/12/18/24514.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/24514.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/12/18/24514.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/24514.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/24514.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">作者：<A HREF="/flyingis/"><FONT color=#000080>Flyingis</FONT></A><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ClassCastException</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">JVM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在检测到两个类型间转换不兼容时引发的运行时异常。此类错误通常会终止用户请求。在执行任何子系统的应用程序代码时都有可能发生</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassCastException</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">异常。通过转换，可以指示</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">编译器将给定类型的变量作为另一种变量来处理。对基础类型和用户定义类型都可以转换。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语言规范定义了允许的转换，其中大多数可在编译时进行验证。不过，某些转换还需要运行时验证。如果在此运行时验证过程中检测到不兼容，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">JVM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就会引发</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassCastException</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">异常。例如：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">Fruit f;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">Apple a = (Apple)f;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当出现下列情况时，就会引发</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassCastException</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">异常：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></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="FONT-SIZE: 10pt; 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; </SPAN></SPAN></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Fruit</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Apple</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类不兼容。当应用程序代码尝试将某一对象转换为某一子类时，如果该对象并非该子类的实例，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">JVM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就会抛出</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassCastException</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">异常。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></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="FONT-SIZE: 10pt; 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; </SPAN></SPAN></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Fruit</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Apple</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类兼容，但加载时使用了不同的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassLoader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。这是这种异常发生最常见的原因。在这里，需要了解一下什么是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassLoader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">？<BR></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><BR>ClassLoader<o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>ClassLoader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是允许</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">JVM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">查找和加载类的一种</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">JVM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有内置的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassLoader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。不过，应用程序可以定义自定义的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassLoader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。应用程序定义新的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassLoader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通常出于以下两种原因：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo2; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; 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; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">自定义和扩展</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">JVM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">加载类的方式。例如，增加对新的类库</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">网络、加密文件等</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的支持。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo2; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; 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; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">划分</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">JVM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">名称空间，避免名称冲突。例如，可以利用划分技术同时运行同一应用程序的多个版本</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">基于空间的划分</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。此项技术在应用服务器</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">WebLogic Server)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内的另一个重要用途是启用应用程序热重新部署，即在不重新启动</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">JVM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的情况下启动应用程序的新版本</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">基于时间的划分</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassLoader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">按层级方式进行组织。除系统</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">BootClassLoader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">外，其它</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassLoader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">都必须有父</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassLoader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在理解类加载的时候，需要注意以下几点：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l2 level1 lfo3; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; 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; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">永远无法在同一</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassLoader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中重新加载类。“热重新部署”需要使用新的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassLoader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。每个类对其</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassLoader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的引用都是不可变的：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">this.getClass().getClassLoader()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l2 level1 lfo3; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; 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; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在加载类之前，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassLoader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">始终会先询问其父</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassLoader(</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">委托模型</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。这意味着将永远无法重写“核心”类。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l2 level1 lfo3; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">3.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">同级</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassLoader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">间互不了解。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l2 level1 lfo3; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; 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; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">由不同</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassLoader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">加载的同一类文件也会被视为不同的类，即便每个字节都完全相同。这是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassCastException</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的一个典型原因。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l2 level1 lfo3; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">5.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Thread.setContextClassLoader(a)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassLoader</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">连接到线程的上下文。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">基于以上的基本原理，可以加深大家对</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">ClassCastException</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的理解，和在碰到问题时提供一种解决问题的思路。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">参考文献：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">dev2dev</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">专刊</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 2005</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">年</SPAN><SPAN style="FONT-SIZE: 10pt"> </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">第二期</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">j2sdk-1_5_0-doc</SPAN><img src ="http://www.blogjava.net/flyingis/aggbug/24514.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-12-18 18:57 <a href="http://www.blogjava.net/flyingis/archive/2005/12/18/24514.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java容器分析--数组</title><link>http://www.blogjava.net/flyingis/archive/2005/12/15/24089.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Thu, 15 Dec 2005 12:56:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/12/15/24089.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/24089.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/12/15/24089.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/24089.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/24089.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 作者：<A HREF="/flyingis/"><FONT color=#000080>Flyingis</FONT></A><BR></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><BR>&nbsp;&nbsp;&nbsp; 数组是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语言内置的类型，除此之外，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有多种保存对象引用的方式。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类库提供了一套相当完整的容器类，使用这些类的方法可以保存和操纵对象。下面分别进行讨论，在研究Java容器类之前，先了解一下Java数组的基本功能和特性。</SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">1.&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数组的基本特性</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数组与其它种类的容器</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(List/Set/Map)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">之间的区别在于效率、确定的类型和保存基本类型数据的能力。数组是一种高效的存储和随机访问对象引用序列的方式，使用数组可以快速的访问数组中的元素。但是当创建一个数组对象</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">注意和对象数组的区别</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">后，数组的大小也就固定了，当数组空间不足的时候就再创建一个新的数组，把旧的数组中所有的引用复制到新的数组中。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的数组和容器都需要进行边界检查，如果越界就会得到一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">RuntimeException</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">异常。这点和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">C++</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中有所不同，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">C++</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">vector</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的操作符</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">[]</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不会做边界检查，这在速度上会有一定的提高，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的数组和容器会因为时刻存在的边界检查带来一些性能上的开销。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中通用的容器类不会以具体的类型来处理对象，容器中的对象都是以</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Object</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类型处理的，这是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中所有类的基类。另外，数组可以保存基本类型，而容器不能，它只能保存任意的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一般情况下，考虑到效率与类型检查，应该尽可能考虑使用数组。如果要解决一般化的问题，数组可能会受到一些限制，这时可以使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">提供的容器类。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">2.&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">操作数组的实用功能</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">java.util.Arrays</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类中，有许多</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">static</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">静态方法，提供了操作数组的一些基本功能：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>equals()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">----</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用于比较两个数组是否相等，相等的条件是两个数组的元素个数必须相等，并且对应位置的元素也相等。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>fill()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">----</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用以某个值填充整个数组，这个方法有点笨。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>asList()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">----</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接受任意的数组为参数，将其转变为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">List</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">容器。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>binarySearch()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">----</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用于在已经排序的数组中查找元素，需要注意的是必须是已经排序过的数组。当</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Arrays.binarySearch()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">找到了查找目标时，该方法将返回一个等于或大于</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">0</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的值，否则将返回一个负值，表示在该数组目前的排序状态下此目标元素所应该插入的位置。负值的计算公式是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">“-x<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><st1:chmetcnv UnitName="”" SourceValue="1" HasSpace="False" Negative="True" NumberType="1" TCSC="0" w:st="on">-1”</st1:chmetcnv></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">x</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">指的是第一个大于查找对象的元素在数组中的位置，如果数组中所有的元素都小于要查找的对象，则</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">x = a.size()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。如果数组中包含重复的元素，则无法保证找到的是哪一个元素，如果需要对没有重复元素的数组排序，可以使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">TreeSet</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或者</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">LinkedHashSet</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。另外，如果使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Comparator</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">排序了某个对象数组，在使用该方法时必须提供同样的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Comparator</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类型的参数。需要注意的是，基本类型数组无法使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Comparator</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进行排序。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>sort()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">----</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对数组进行升序排序。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">标准类库中，另有</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">static</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">System.arraycopy()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用来复制数组，它针对所有类型做了重载。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">3.&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数组的排序</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java1.0</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">1.1</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">两个版本中，类库缺少基本的算法操作，包括排序的操作，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java2</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对此进行了改善。在进行排序的操作时，需要根据对象的实际类型执行比较操作，如果为每种不同的类型各自编写一个不同的排序方法，将会使得代码很难被复用。一般的程序设计目标应是“将保持不变的事物与会发改变的事物相分离”。在这里，不变的是通用的排序算法，变化的是各种对象相互比较的方式。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有两种方式来实现比较的功能，一种是实现</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">java.lang.Comparable</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口，该接口只有一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">compareTo()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法，并以一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Object</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类为参数，如果当前对象小于参数则返回负值，如果相等返回零，如果当前对象大于参数则返回正值。另一种比较方法是采用策略</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(strategy)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设计模式，将会发生变化的代码封装在它自己的类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">策略对象</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，再将策略对象交给保持不变的代码中，后者使用此策略实现它的算法。因此，可以为不同的比较方式生成不同的对象，将它们用在同样的排序程序中。在此情况下，通过定义一个实现了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Comparator</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口的类而创建了一个策略，这个策略类有</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">compare()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">equals()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">两个方法，一般情况下实现</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">compare()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法即可。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用上述两种方法即可对任意基本类型的数组进行排序，也可以对任意的对象数组进行排序。再提示一遍，基本类型数组无法使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Comparator</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进行排序。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 7.8pt 0cm; TEXT-INDENT: 21pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm"><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">标准类库中的排序算法针对排序的类型进行了优化——针对基本类型设计了“快速排序”，针对对象设计的“稳定归并排序”。一般不用担心其性能。<BR></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p><BR>其它相关内容：<BR><A HREF="/flyingis/archive/2005/12/21/24951.html"><FONT color=#000080>Java容器分析--List和Set</FONT></A><BR><A HREF="/flyingis/archive/2005/12/27/25534.html"><FONT color=#000080>Java容器分析--Map</FONT></A></o:p></SPAN></P><img src ="http://www.blogjava.net/flyingis/aggbug/24089.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-12-15 20:56 <a href="http://www.blogjava.net/flyingis/archive/2005/12/15/24089.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>浅议类型识别与反射机制</title><link>http://www.blogjava.net/flyingis/archive/2005/12/11/23337.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Sun, 11 Dec 2005 06:43:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/12/11/23337.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/23337.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/12/11/23337.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/23337.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/23337.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&nbsp;&nbsp;&nbsp; 作者：<A HREF="/flyingis/"><FONT color=#000080>Flyingis</FONT></A><BR><BR>&nbsp;&nbsp;&nbsp; 运行时类型识别</SPAN><SPAN lang=EN-US>(Run-time Type Identification, RTTI)</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">主要有两种方式，一种是我们在编译时和运行时已经知道了所有的类型，另外一种是功能强大的“反射”机制。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">要理解</SPAN><SPAN lang=EN-US>RTTI</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>Class</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象”完成的，它包含了与类有关的信息。类是程序的重要组成部分，每个类都有一个</SPAN><SPAN lang=EN-US>Class</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象，每当编写并编译了一个新类就会产生一个</SPAN><SPAN lang=EN-US>Class</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象，它被保存在一个同名的</SPAN><SPAN lang=EN-US>.class</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>(JVM)</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">会确认这个类的</SPAN><SPAN lang=EN-US>Class</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象是否已经加载，如果尚未加载，</SPAN><SPAN lang=EN-US>JVM</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就会根据类名查找</SPAN><SPAN lang=EN-US>.class</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件，并将其载入，一旦这个类的</SPAN><SPAN lang=EN-US>Class</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象被载入内存，它就被用来创建这个类的所有对象。一般的</SPAN><SPAN lang=EN-US>RTTI</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形式包括三种：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><FONT size=2><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; </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>(Apple)Fruit</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”，由</SPAN><SPAN lang=EN-US>RTTI</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">确保类型转换的正确性，如果执行了一个错误的类型转换，就会抛出一个</SPAN><SPAN lang=EN-US>ClassCastException</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">异常。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><FONT size=2><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; </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>Class</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象来获取对象的类型。如</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><SPAN lang=EN-US><FONT size=2>Class c = Class.forName(“Apple”);</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><SPAN lang=EN-US><FONT size=2>Object o = c.newInstance();</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><FONT size=2><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;&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>instanceof</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</SPAN><SPAN lang=EN-US>Class.isInstance()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法来确定对象是否属于某个特定类型的实例，准确的说，应该是</SPAN><SPAN lang=EN-US>instanceof / Class.isInstance()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以用来确定对象是否属于某个特定类及其所有基类的实例，这和</SPAN><SPAN lang=EN-US>equals() / ==</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不一样，它们用来比较两个对象是否属于同一个类的实例，没有考虑继承关系。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p><FONT size=2>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">反射</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></FONT></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果不知道某个对象的类型，可以通过</SPAN><SPAN lang=EN-US>RTTI</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来获取，但前提是这个类型在编译时必须已知，这样才能使用</SPAN><SPAN lang=EN-US>RTTI</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来识别。即在编译时，编译器必须知道所有通过</SPAN><SPAN lang=EN-US>RTTI</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来处理的类。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用反射机制可以不受这个限制，它主要应用于两种情况，第一个是“基于构件的编程”，在这种编程方式中，将使用某种基于快速应用开发</SPAN><SPAN lang=EN-US>(RAD)</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的应用构建工具来构建项目。这是现在最常见的可视化编程方法，通过代表不同组件的图标拖动到图板上来创建程序，然后设置构件的属性值来配置它们。这种配置要求构件都是可实例化的，并且要暴露其部分信息，使得程序员可以读取和设置构件的值。当处理</SPAN><SPAN lang=EN-US>GUI</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时间的构件时还必须暴露相关方法的细细，以便</SPAN><SPAN lang=EN-US>RAD</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>JavaBeans</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">提供了基于构件的编程架构。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">第二种情况，在运行时获取类的信息的另外一个动机，就是希望能够提供在跨网络的远程平台上创建和运行对象的能力。这被成为远程调用</SPAN><SPAN lang=EN-US>(RMI)</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></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Class</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.lang.reflect</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中包含了</SPAN><SPAN lang=EN-US>Field/Method/Constructor</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类，每个类都实现了</SPAN><SPAN lang=EN-US>Member</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口。这些类型的对象都是由</SPAN><SPAN lang=EN-US>JVM</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在运行时创建的，用来表示未知类里对应的成员。如可以用</SPAN><SPAN lang=EN-US>Constructor</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类创建新的对象，用</SPAN><SPAN lang=EN-US>get()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US>set()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法读取和修改与</SPAN><SPAN lang=EN-US>Field</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象关联的字段，用</SPAN><SPAN lang=EN-US>invoke()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法调用与</SPAN><SPAN lang=EN-US>Method</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象关联的方法。同时，还可以调用</SPAN><SPAN lang=EN-US>getFields()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</SPAN><SPAN lang=EN-US>getMethods()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</SPAN><SPAN lang=EN-US>getConstructors()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">等方法来返回表示字段、方法以及构造器的对象数组。这样，未知的对象的类信息在运行时就能被完全确定下来，而在编译时不需要知道任何信息。</SPAN></FONT></P><FONT size=2><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">另外，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">RTTI</SPAN><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">有时能解决效率问题。当程序中使用多态给程序的运行带来负担的时候，可以使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">RTTI</SPAN><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">编写一段代码来提高效率。<BR><BR><FONT color=#0000ff>Happy Birthday to myself!</FONT></SPAN></FONT><img src ="http://www.blogjava.net/flyingis/aggbug/23337.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-12-11 14:43 <a href="http://www.blogjava.net/flyingis/archive/2005/12/11/23337.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java虚拟机简介[转载]</title><link>http://www.blogjava.net/flyingis/archive/2005/12/05/22603.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Mon, 05 Dec 2005 08:26:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/12/05/22603.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/22603.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/12/05/22603.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/22603.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/22603.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一、什么是Java虚拟机&nbsp;Java虚拟机是一个想象中的机器,在实际的计算机上通过软件模拟来实现。Java虚拟机有自己想象中的硬件,如处理器、堆栈、寄存器等,还具有相应的指令系统。&nbsp;1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 为什么要使用Java虚拟机Java语言的一个非常重要的特点就是与平台的无关性。而使用Jav...&nbsp;&nbsp;<a href='http://www.blogjava.net/flyingis/archive/2005/12/05/22603.html'>阅读全文</a><img src ="http://www.blogjava.net/flyingis/aggbug/22603.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-12-05 16:26 <a href="http://www.blogjava.net/flyingis/archive/2005/12/05/22603.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关键字new和newInstance方法区别</title><link>http://www.blogjava.net/flyingis/archive/2005/12/03/22345.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Sat, 03 Dec 2005 08:48:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/12/03/22345.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/22345.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/12/03/22345.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/22345.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/22345.html</trackback:ping><description><![CDATA[<P><FONT size=2>&nbsp;&nbsp;&nbsp; 作者：<A HREF="/flyingis/"><FONT color=#000080>Flyingis</FONT></A><BR><BR>&nbsp;&nbsp;&nbsp; 在初始化一个类，生成一个实例的时候，newInstance()方法和new关键字除了一个是方法，一个是关键字外，最主要有什么区别？它们的区别在于创建对象的方式不一样，前者是使用类加载机制，后者是创建一个新类。那么为什么会有两种创建对象方式？这主要考虑到软件的可伸缩、可扩展和可重用等软件设计思想。 </FONT></P>
<P><FONT size=2>&nbsp;&nbsp;&nbsp; Java中工厂模式经常使用newInstance()方法来创建对象，因此从为什么要使用工厂模式上可以找到具体答案。 例如：<BR>&nbsp;&nbsp;&nbsp; class c = Class.forName(“Example”);<BR>&nbsp;&nbsp;&nbsp; factory = (ExampleInterface)c.newInstance(); </FONT></P>
<P><FONT size=2>&nbsp;&nbsp;&nbsp; 其中ExampleInterface是Example的接口，可以写成如下形式： <BR>&nbsp;&nbsp;&nbsp; String className = "Example";<BR>&nbsp;&nbsp;&nbsp; class c = Class.forName(className);<BR>&nbsp;&nbsp;&nbsp; factory = (ExampleInterface)c.newInstance();</FONT></P>
<P><FONT size=2>&nbsp;&nbsp;&nbsp; 进一步可以写成如下形式：<BR>&nbsp;&nbsp;&nbsp; String className = readfromXMlConfig;//从xml 配置文件中获得字符串<BR>&nbsp;&nbsp;&nbsp; class c = Class.forName(className);<BR>&nbsp;&nbsp;&nbsp; factory = (ExampleInterface)c.newInstance();</FONT></P>
<P><FONT size=2>&nbsp;&nbsp;&nbsp; 上面代码已经不存在Example的类名称，它的优点是，无论Example类怎么变化，上述代码不变，甚至可以更换Example的兄弟类Example2 , Example3 , Example4……，只要他们继承ExampleInterface就可以。</FONT></P>
<P><FONT size=2>&nbsp;&nbsp;&nbsp; 从JVM的角度看，我们使用关键字new创建一个类的时候，这个类可以没有被加载。但是使用newInstance()方法的时候，就必须保证：1、这个类已经加载；2、这个类已经连接了。而完成上面两个步骤的正是Class的静态方法forName()所完成的，这个静态方法调用了启动类加载器，即加载java API的那个加载器。</FONT></P>
<P><FONT size=2>&nbsp;&nbsp;&nbsp; 现在可以看出，newInstance()实际上是把new这个方式分解为两步，即首先调用Class加载方法加载某个类，然后实例化。 这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性，提供给了一种降耦的手段。</FONT></P>
<P><FONT size=2>&nbsp;&nbsp;&nbsp; 最后用最简单的描述来区分new关键字和newInstance()方法的区别：<BR>&nbsp;&nbsp;&nbsp; newInstance: 弱类型。低效率。只能调用无参构造。 <BR>&nbsp;&nbsp;&nbsp; new: 强类型。相对高效。能调用任何public构造。</FONT></P><img src ="http://www.blogjava.net/flyingis/aggbug/22345.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-12-03 16:48 <a href="http://www.blogjava.net/flyingis/archive/2005/12/03/22345.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vector &amp; ArrayList 哪一个更好？为什么？[转载]</title><link>http://www.blogjava.net/flyingis/archive/2005/11/21/20760.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Mon, 21 Nov 2005 06:18:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/11/21/20760.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/20760.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/11/21/20760.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/20760.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/20760.html</trackback:ping><description><![CDATA[<FONT size=2>有的时候 Vector更好一些;有的时候ArrayList 更好一些；有的时候你一个也不想用。但愿，你不是在期望一个简单明了的答案，因为答案因你在用他们做什么而定。下面是要考虑的四个方面： </FONT>
<P><FONT size=2>API <BR>同步-Synchronization <BR>数据增长-Data growth <BR>使用方法-Usage patterns </FONT></P>
<P><FONT size=2>让我一个一个来解释吧。 </FONT></P>
<P><FONT size=2><STRONG>API </STRONG><BR>在The Java Programming Language (Addison-Wesley, June 2000) 中Ken Arnold, James Gosling, 和 David Holmes 是这样描述Vector的，它是更ArrayList类似的一个东西，所以从API的观点来看，它们俩是很相似的。但是，它们之间还是有些微的差别的。 </FONT></P>
<P><FONT size=2><STRONG>Synchronization </STRONG><BR>Vectors是可同步化的，意思就是说，任何操作Vector的内容的方法都是线程安全的，相反的，另一方面，ArrayList是不可同步化的，所以也不是线程安全的。如果你知道了这些的话，你就会发现，Vector的同步会让它在性能发方面有一些小问题。所以，如果你不需要线程安全的话，那么就使用ArrayList吧。为什么要为没有必要的同步付出代价呢？ </FONT></P>
<P><FONT size=2><STRONG>Data growth</STRONG> <BR>实际上，不管是ArrayList还是Vector，在它们内部都是使用一个Array来保存数据的。编程过程中，在使用它们任何一个的时候，你都需要记住这一点。你在往一个ArrayList或者Vector里插入一个元素的时候，如果内部数组空间不够了，这个对象(译者按：指的是你使用的ArrayList或者Vector)就要扩展它的大小。Vector在默认情况下是产生一个双倍大小，而ArrayList增加50%的大小。只要你合理的使用这些类，你就可以结束你在增加新的元素的时候所付出的性能代价。把对象(译者按：指的是你使用的ArrayList或者Vector)的初始化容量指定为你编程过程中所能用到的最大的容量总是最好的办法。仔细的指定容量，你可以避免以后改变内部Array容量，所要付出的代价。如果你并不知道到底有多少个数据，当是你知道数据的增长率，Vector确实有一点点优势，因为你可以指定增加值(译者按，如果没有猜错的话，作者说的方法应该是setSize(int newSize)&nbsp; Sets the size of this vector.)。 </FONT></P>
<P><FONT size=2><STRONG>Usage patterns</STRONG> <BR>ArrayList和Vector在从指定位置取得元素，从容器的末尾增加和删除元素都非常的有效，所有的这些操作都能在一个常数级的时间(O(1))内完成。但是从一个其他的位置增加和删除一个元素就显得颇为费时，差不多需要的时间为O(n-i)，这里的n代表元素个数，i代表要增加和删除的元素所在的位置。这些操作需花费更多的时间，因为你需要挨个移动i和更高位置的元素。那么，以上这些到底说明了什么呢？ </FONT></P>
<P><FONT size=2>这意味着，如果你取得一个元素，或者从数组末尾增加或删除一个元素的话，随便你使用Vector和ArrayList。如果你想要对数组内容做其他操作的话，那么就为自己好另一个容器吧。比喻说，LinkedList可以在常数级时间(O(1))内为任意一个位置的元素增加和删除。但是，取得一个元素，会稍微慢一点，时间要用O(i) ，这个i是元素的位置。通过ArrayList也是很简单的，因为你可以简单使用一个索引，而不是构造一个iterator 。LinkedList也为每个插入的元素建立一个内部对象。所以，你也必须知道，同时产生了垃圾对象。 </FONT></P>
<P><FONT size=2>最后，Practical Java (Addison-Wesley, Feb. 2000) Peter Haggar 里的“实践41“建议你使用一个普通的原始的数组来代替Vector和ArrayListe，特别是对效率优先的代码来说。通过使用数组(array)，你可以避免同步，额外的方法调用，非理想化的大小改变。你付出的只是额外的开发时间。<BR><BR>原文链接：<A href="http://www.javaworld.com/javaworld/javaqa/2001-06/03-qa-0622-vector.html"><FONT color=#000080>http://www.javaworld.com/javaworld/javaqa/2001-06/03-qa-0622-vector.html</FONT></A></FONT></P><img src ="http://www.blogjava.net/flyingis/aggbug/20760.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-11-21 14:18 <a href="http://www.blogjava.net/flyingis/archive/2005/11/21/20760.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>挖掘Jakarta Commons中隐藏的宝贝(三)[转载]</title><link>http://www.blogjava.net/flyingis/archive/2005/11/09/18959.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Wed, 09 Nov 2005 04:27:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/11/09/18959.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/18959.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/11/09/18959.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/18959.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/18959.html</trackback:ping><description><![CDATA[<FONT size=2><SPAN style="FONT-SIZE: 16px"><FONT color=#0000ff>(文章转自CSDN)</FONT><BR><BR><STRONG>3. 使用XPath语法来查询对象和集合</STRONG></SPAN><BR>Commons JXPath是一种让人很吃惊地（非标准的）对XML标准的使用。XPath一段时间以来一直是作为在一个XSL样式表中选择结点或结点集的一种方法。如果你用过XML，你会很熟悉用这样的语法/foo/bar来从foo文档元素中选择bar子元素。<BR><BR>Jakarta Commons JXPath增加了一种有趣的手法：你可以用JXPath来从bean和集合中选择对象，其中如servlet上下文和DOM文档对象。考虑一个包含了Person对象的列表。每一个Person对象有一个属性的类型为Job，每一个Job对象有一个salary(薪水)属性，类型为int。Person对象也有一个coountry属性，它是两个字符的国家代码。使用JXPath，你可以很容易地选出所有国家为美国，薪水超过一百万美元的Person对象。下面是设置一个由JXPath过滤地bean的List的代码:<BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2>// Person的构造器设置姓和国家代码<BR>Person person1 = new Person( "Tim", "US" );<BR>Person person2 = new Person( "John", "US" );<BR>Person person3 = new Person( "Al",&nbsp;&nbsp;"US" );<BR>Person person4 = new Person( "Tony", "GB" );<BR><BR>// Job的构造器设工作名称和薪水<BR>person1.setJob( new Job( "Developer", 40000 ) );<BR>person2.setJob( new Job( "Senator", 150000 ) );<BR>person3.setJob( new Job( "Comedian", 3400302 ) );<BR>person4.setJob( new Job( "Minister", 2000000 ) );<BR><BR>Person[] personArr = <BR>&nbsp;&nbsp;new Person[] { person1, person2, <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; person3, person4 };<BR><BR>List people = Arrays.asList( personArr );</FONT></PRE><BR><BR><FONT size=2>people List包含了四个bean: Tim, John, Al, 和George。Tim是一个挣4万美元的开发者，John是一个挣15万美元的参议员，Al是一个挣340万美元的喜剧演员，Tony是一个挣200万欧元的部长。我们的任务很简单：遍历这个List,打印出每一个挣钱超过100百万美元的美国公民的名字。记住people是一个由Person对象构成的ArrayList,让我们先看一下没有利用JXPath便利的解决方案：<BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2>Iterator peopleIter = people.getIterator();<BR>while( peopleIter.hasNext() ) {<BR>&nbsp;&nbsp;Person person = (Person) peopleIter.next();<BR><BR>&nbsp;&nbsp;if( person.getCountry() != null &amp;&amp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;person.getCountry().equals( "US" ) &amp;&amp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;person.getJob() != null &amp;&amp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;person.getJob().getSalary() &gt; 1000000 ) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print( person.getFirstName() + " "<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; person.getLastName() );<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}<BR>}</FONT></PRE><BR><BR><FONT size=2>上面的例子是繁重的，并有些容易犯错。为了发现合适的Person对象，你必须首先遍历每一个Person对象并且检查conuntry的属性。如果country属性不为空并且符合要求，那么你就要检查job属性并看一下它是否不为空并且salary属性的值大于100万。上面的例子的代码行数可以被Java 1.5的语法大大减少，但是，哪怕是Java 1.5，你仍旧需要在两层上作两次比较。<BR><BR>如果你想对内存中的一组Person对象也做一些这样的查询呢？如果你的应用想显示所有在英格兰的名叫Tony的人呢？喔，如果你打印出每一个薪水少于2万的工作的名称呢？<BR><BR>如果你将这些对象存储到关系数据库中，你可以用一个SQL查询来解决问题，但你正在处理的是内存中的对象，你可以不必那么奢侈。虽然XPath主要是用在XML上面，但你可以用它来写一个针对对象集合的“查询”，将对象作为元素和，把bean属性作为子元素。是的，这是一种对XPath奇怪的应用，但请先看一下下面的例子如何在people上，一个由Person对象构成的ArrayList，实现这三种查询：<BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2>import org.apache.commons.jxpath.JXPathContext;<BR><BR>public List queryCollection(String xpath,<BR>&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;Collection col) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;List results = new ArrayList();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;JXPathContext context = <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JXPathContext.newContext( col );<BR> <BR>&nbsp;&nbsp;&nbsp;&nbsp;Iterator matching = <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.iterate( xpath );<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;while( matching.hasNext() ) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;results.add( matching.getNext() );<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;return results;<BR>}<BR><BR>String query1 =<BR>&nbsp;&nbsp; ".[@country = 'US']/job[@salary &gt; 1000000]/..";&nbsp;&nbsp;<BR>String query2 =<BR>&nbsp;&nbsp; ".[@country = 'GB' and @name = 'Tony']";&nbsp;&nbsp;<BR>String query3 = <BR>&nbsp;&nbsp; "./job/name";<BR><BR>List richUsPeople = <BR>&nbsp;&nbsp;&nbsp;&nbsp;queryCollection( query1, people );<BR>List britishTony = <BR>&nbsp;&nbsp;&nbsp;&nbsp;queryCollection( query2, people );<BR>List jobNames = <BR>&nbsp;&nbsp;&nbsp;&nbsp;queryCollection( query3, people );</FONT></PRE>
<P><BR><BR><FONT size=2>queryCollection()方法使用了一个XPath表达式，将它应用到一个集合上。XPath表达式被JXPathContext求值， JXPathContext由JXPathContext.newContext()调用创建，并将它传入要执行查询的集合中。凋用context.iterate()来在集合中的每一个元素上应用XPath表达式，返回包含所有符合条件的“节点”（这里是“对象”）的Iterator。上例中执行的第一个查询，query1,执行了和不使用JXPath的例子相同的查询。query2选择所有国家为GB并且名字属性为Tony的Person对象，query3返回了一个String对象的List,包含了所有Job对象的name属性。<BR><BR>当我第一次看到Commons JXPath, 它是一个坏思想的想法触动了我。为什么要把XPath表达式应用到对象上?有点感觉不对。把XPath作为一个bean的集合的查询语言的这种意想不到的用法，在过去几年中已经好多次给我带来了便利。如果你发现你在list中循环来查找符合条件的元素，请考虑一下JXPath。更多的信息，请参考Jakarta Commons Cookbook的第12章，“查找和过滤”，它讨论了Commons JXPath和与Commons Digester配对的Jakarta Lucene。<BR><BR><B><SPAN style="FONT-SIZE: 16px">还有更多</SPAN></B><BR>对Jakarta Commons纵深地探索仍然在调试中。在这一系列的下面几部分中，我会介绍一些相关的工具和功能。在Commons Collections中设置操作，在collection中使用Predicate对象，使用Commons Configuration来配置一个应用和使用Commons Betwixt来读写XML。能从Jakarta Commons得到的东西还有很多，不能在几千字中表达，所以我建议你看一下Jakarta Commons Cookbook。许多功能可能会，一眼看上去，有点普通，但Jakarta Commons的能量就蕴藏在这些工具的相互组合和与你的系统的集成当中。<BR><BR>Timothy M. O'Brien是一个专业的独立的开发者，在Chicago地区工作和生活。<BR><BR><B>资源</B><BR>·onjava.com:</FONT><A href="http://www.onjava.com/" target=_new><FONT size=2>onjava.com</FONT></A><BR><FONT size=2>·Matrix-Java开发者社区:</FONT><A href="http://www.matrix.org.cn/" target=_new><FONT size=2>http://www.matrix.org.cn/</FONT></A><BR><FONT size=2>·APACHE:</FONT><A href="http://www.apache.org/" target=_new><FONT size=2>APACHE.org</FONT></A><BR></P><img src ="http://www.blogjava.net/flyingis/aggbug/18959.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-11-09 12:27 <a href="http://www.blogjava.net/flyingis/archive/2005/11/09/18959.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>挖掘Jakarta Commons中隐藏的宝贝(二)[转载]</title><link>http://www.blogjava.net/flyingis/archive/2005/11/09/18958.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Wed, 09 Nov 2005 04:21:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/11/09/18958.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/18958.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/11/09/18958.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/18958.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/18958.html</trackback:ping><description><![CDATA[<FONT size=2><SPAN style="FONT-SIZE: 16px"><FONT color=#0000ff><FONT size=2>(文章转自CSDN)</FONT><BR></FONT><BR><STRONG>2．Commons Collections中的算子</STRONG></SPAN><BR>算子成为Commons Collections 3.1中的有趣的部分有两个原因：它们没有得到应得的重视并且它们有改变你编程的方式的潜力。算子只是一个奇特的名字，它代表了一个包装了函数的对象—一个“函数对象”。当然，它们不是一回事。如果你曾经使用过C和C++的方法指针，你就会理解算子的威力。<BR>一个算子是一个对象—一个Predicate,一个Closure, 一个Transformer。<BR><BR>Predicates求对象的值并返回一个boolean，Transformer求对象的值并返回新对象，Closure接受对象并执行代码。算子可以被组合成组合算子来模仿循环，逻辑表达式，和控制结构，并且算子也可以被用来过滤和操作集合中的元素。在这么短的篇幅中解释清楚算子是不可能的，所以跳过介绍，我将会通过使用和不使用算子来解决同一问题（解释算子）。在这个例子中，从一个ArrayList中而来的Student对象会被排序到两个List中，如果他们符合某种标准的话。<BR><BR>成绩为A的学生会被加到honorRollStudents(光荣榜)中，得D和F的学生被加到problemStudents (问题学生)list中。学生分开以后，系统将会遍历每个list，给加入到光荣榜中学生一个奖励，并安排与问题学生的家长谈话的时间表。下面的代码不使用算子实现了这个过程：<BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2>List allStudents = getAllStudents();<BR><BR>// 创建两个ArrayList来存放荣誉学生和问题学生<BR>List honorRollStudents = new ArrayList();<BR>List problemStudents = new ArrayList();<BR><BR>// 遍历所有学生，将荣誉学生放入一个List,问题学生放入另一个<BR>Iterator allStudentsIter = allStudents.iterator();<BR>while( allStudentsIter.hasNext() ) {<BR>&nbsp;&nbsp;Student s = (Student) allStudentsIter.next();<BR><BR>&nbsp;&nbsp;if( s.getGrade().equals( "A" ) ) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;honorRollStudents.add( s );<BR>&nbsp;&nbsp;} else if( s.getGrade().equals( "B" ) &amp;&amp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.getAttendance() == PERFECT) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;honorRollStudents.add( s );<BR>&nbsp;&nbsp;} else if( s.getGrade().equals( "D" ) || <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.getGrade().equals( "F" ) ) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;problemStudents.add( s );<BR>&nbsp;&nbsp;} else if( s.getStatus() == SUSPENDED ) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;problemStudents.add( s );<BR>&nbsp;&nbsp;}<BR>}<BR><BR>// 对于的有荣誉学生，增加一个奖励并存储到数据库中<BR>Iterator honorRollIter = <BR>&nbsp;&nbsp;&nbsp;&nbsp;honorRollStudents.iterator();<BR>while( honorRollIter.hasNext() ) {<BR>&nbsp;&nbsp;Student s = (Student) honorRollIter.next();<BR>&nbsp;&nbsp; <BR> // 给学生记录增加一个奖励<BR>&nbsp;&nbsp;s.addAward( "honor roll", 2005 );<BR>&nbsp;&nbsp;Database.saveStudent( s );<BR>}<BR><BR>// 对所有问题学生，增加一个注释并存储到数据库中<BR>Iterator problemIter = problemStudents.iterator();<BR>while( problemIter.hasNext() ) {<BR>&nbsp;&nbsp;Student s = (Student) problemIter.next();<BR><BR>&nbsp;&nbsp;// 将学生标记为需特殊注意<BR>&nbsp;&nbsp;s.addNote( "talk to student", 2005 );<BR>&nbsp;&nbsp;s.addNote( "meeting with parents", 2005 );<BR>&nbsp;&nbsp;Database.saveStudent( s );<BR>}</FONT></PRE><BR><BR><FONT size=2>上述例子是非常过程化的;要想知道Student对象发生了什么事必须遍历每一行代码。例子的第一部分是基于成绩和考勤对Student对象进行逻辑判断。<BR><BR>第二部分对Student对象进行操作并存储到数据库中。像上述这个有着50行代码程序也是大多程序所开始的—可管理的过程化的复杂性。但是当需求变化时，问题出现了。一旦判断逻辑改变，你就需要在第一部分中增加更多的逻辑表达式。<BR><BR>举例来说，如果一个有着成绩B和良好出勤记录，但有五次以上的留堂记录的学生被判定为问题学生，那么你的逻辑表达式将会如何处理?或者对于第二部分中，只有在上一年度不是问题学生的学生才能进入光荣榜的话，如何处理？当例外和需求开始改变进而影响到过程代码时，可管理的复杂性就会变成不可维护的面条式的代码。<BR><BR>从上面的例子中回来，考虑一下那段代码到底在做什么。它在一个List遍历每一个对象，检查标准，如果适用该标准，对此对象进行某些操作。上述例子可以进行改进的关键一处在于从代码中将标准与动作解藕开来。下面的两处代码引用以一种非常不同的方法解决了上述的问题。首先，荣誉榜和问题学生的标准被两个Predicate对象模型化了，并且加之于荣誉学生和问题学生上的动作也被两个Closure对象模型化了。这四个对象如下定义： <BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2>import org.apache.commons.collections.Closure;<BR>import org.apache.commons.collections.Predicate;<BR><BR>// 匿名的Predicate决定一个学生是否加入荣誉榜<BR>Predicate isHonorRoll = new Predicate() {<BR>&nbsp;&nbsp;public boolean evaluate(Object object) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;Student s = (Student) object;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;return( ( s.getGrade().equals( "A" ) ) ||<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;( s.getGrade().equals( "B" ) &amp;&amp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.getAttendance() == PERFECT ) );<BR>&nbsp;&nbsp;}<BR>};<BR><BR>//匿名的Predicate决定一个学生是否是问题学生<BR>Predicate isProblem = new Predicate() {<BR>&nbsp;&nbsp;public boolean evaluate(Object object) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;Student s = (Student) object;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;return ( ( s.getGrade().equals( "D" ) || <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.getGrade().equals( "F" ) ) ||<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.getStatus() == SUSPENDED );<BR>&nbsp;&nbsp;}<BR>};<BR><BR>//匿名的Closure将一个学生加入荣誉榜<BR>Closure addToHonorRoll = new Closure() {<BR>&nbsp;&nbsp;public void execute(Object object) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;Student s = (Student) object;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>// 对学生增加一个荣誉记录<BR>&nbsp;&nbsp;&nbsp;&nbsp;s.addAward( "honor roll", 2005 );<BR>&nbsp;&nbsp;&nbsp;&nbsp;Database.saveStudent( s );<BR>&nbsp;&nbsp;}<BR>};<BR><BR>// 匿名的Closure将学生标记为需特殊注意<BR>Closure flagForAttention = new Closure() {<BR>&nbsp;&nbsp;public void execute(Object object) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;Student s = (Student) object;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>// 标记学生为需特殊注意<BR>&nbsp;&nbsp;&nbsp;&nbsp;s.addNote( "talk to student", 2005 );<BR>&nbsp;&nbsp;&nbsp;&nbsp;s.addNote( "meeting with parents", 2005 );<BR>&nbsp;&nbsp;&nbsp;&nbsp;Database.saveStudent( s );<BR>&nbsp;&nbsp;}<BR>};</FONT></PRE><BR><BR><FONT size=2>这四个匿名的Predicate和Closure是从作为一个整体互相分离的。flagForAttention(标记为注意)并不知道什么是确定一个问题学生的标准 。现在需要的是将正确的Predicate和正确的Closure结合起来的方法，这将在下面的例子中展示：<BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2>import org.apache.commons.collections.ClosureUtils;<BR>import org.apache.commons.collections.CollectionUtils;<BR>import org.apache.commons.collections.functors.NOPClosure;<BR><BR>Map predicateMap = new HashMap();<BR><BR>predicateMap.put( isHonorRoll, addToHonorRoll );<BR>predicateMap.put( isProblem, flagForAttention );<BR>predicateMap.put( null, ClosureUtils.nopClosure() );<BR><BR>Closure processStudents = <BR>&nbsp;&nbsp;&nbsp;&nbsp;ClosureUtils.switchClosure( predicateMap );<BR><BR>CollectionUtils.forAllDo( allStudents, processStudents );</FONT></PRE><BR><BR><FONT size=2>在上面的代码中，predicateMap将Predicate与Closure进行了配对;如果一个学生满足作为键值的Predicate的条件，那么它将把它的值传到作为Map的值的Closure中。通过提供一个NOPClosure值和null键对，我们将把不符合任何Predicate条件的Student对象传给由ClosureUtils调用创建的“不做任何事”或者“无操作”的NOPClosure。<BR><BR>一个SwitchClosure, processStudents，从predicateMap中创建。并且通过使用CollectionUtils.forAllDo()方法，将processStudents Closure应用到allStudents中的每一个Student对象上。这是非常不一样的处理方法;记住，你并没有遍历任何队列。而是通过设置规则和因果关系，以及CollectionUtils和SwitchClosur来完成了这些操作。<BR><BR>当你将使用Predicate的标准与使用Closure的动作将分离开来时，你的代码的过程式处理就少了，而且更容易测试了。isHonorRoll Predicate能够与addToHonorRoll Closure分离开来进行独立的单元测试，它们也可以合起来通过使用Student类的模仿对象进行测试。第二个例子也会演示CollectionUtils.forAllDo()，它将一个Closure应用到了一个Collection的每一个元素中。<BR><BR>你也许注意到了使用算子并没用减少代码行数，实际上，使用算子还增加了代码量。但是，通过算子，你得到了将到了标准与动作的模块性与封装性的好处。如果你的代码题已经接近于几百行，那么请考虑一下更少过程化处理，更多面向对象的解决方案—通过使用算子。<BR><BR>Jakarta Commons Cookbook中的第四章“算子”介绍了Commons Collections中可用的算子，在第五章，“集合”中，向你展示了如何使用算子来操作Java 集合类API。<BR><BR>所有的算子-- Closure, Predicate, 和 Transformer—能够被合并为合并算子来处理任何种类的逻辑问题。switch, while和for结构能够被SwitchClosure, WhileClosure, 和 ForClosure模型化。<BR>复合的逻辑表达式可以被多个Predicate构建，通过使用OrPredicate, AndPredicate, AllPredicate, 和 NonePredicate将它们相互联接。Commons BeanUtils也包含了算子的实现被用来将算子应用到bean的属性中-- BeanPredicate, BeanComparator, 和 BeanPropertyValueChangeClosure。算子是考虑底层的应用架构的不一样的方法，它们可以很好地改造你编码实现的方法。<BR><BR>&gt;&gt;&gt;&gt;<A HREF="/flyingis/archive/2005/11/09/18959.html">下一篇</A></FONT><img src ="http://www.blogjava.net/flyingis/aggbug/18958.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-11-09 12:21 <a href="http://www.blogjava.net/flyingis/archive/2005/11/09/18958.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>挖掘Jakarta Commons中隐藏的宝贝(一)[转载]</title><link>http://www.blogjava.net/flyingis/archive/2005/11/09/18957.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Wed, 09 Nov 2005 04:18:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/11/09/18957.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/18957.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/11/09/18957.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/18957.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/18957.html</trackback:ping><description><![CDATA[<FONT size=2><FONT color=#0000ff>(文章转自CSDN)</FONT><BR><BR>如果你不熟悉Jakarta Commons话，那么很有可能你已经重新发明了好几个轮子。在你编写更多的普通的框架或工具之前，体验一下Commons吧。它将会大大地节约你的时间。太多的人自己写一个，其实是与Commons Lang中的StringUtils重复的StringUtils类，或者，开发者不知道从Commons Collections中重新创建工具，哪怕commons-collections.jar已经在classpath中可用了。<BR><BR>真的，请停一下。看看Commons Collections API，然后再回到你的任务中;我发誓你会发现一些简单有用的东西可以帮你在明年节省一周的时间。如果大家花一点时间看看Jakarta Commons，我们将会得到更少的重复代码—我们将在重用的宗旨下真正做一些有用的事情。<BR><BR>我确实看到这样的情况发生过：一些人研究了一下Commons BeanUtils或者Commons Collections，然后总是有“啊，如果我那时知道这个的话，我就不会写那一万行的代码了”这样的时刻。Jakarta Commons仍有一部分保持相当的神秘;比如，许多人还没有听说过Commons CLI和Commons Configuration，并且大多数人还没有注意到Commons Collections中的functors(算子)包的价值。在这一系列中，我会专门强调一些Jakarta Commons中较少得到重视的工具和功能。<BR><BR>在这一系列的第一部分，我将探索定义在Commons Digester中的XML规则，Commons Collections中的功能，和使用一个有趣的应用，Commons JXPath，来查询一个对象的List。Jakarta Commons包含的功能目的在于帮助你解决低层次的编程问题：遍历集合，解析XML和从List中检出对象。我建议你花一些时间在这些小功能上，学习Jakarta Commons真的会为你节省不少时间。<BR><BR>并不简单地是学习使用Commons Digester来解析XML或者使用CollectionUtils的Predicate来过滤一个集合，而是当你一旦意识到如何将这些功能组合起来使用并且如何将Commons集成到你的项目中去的时候，你才会真正地看到它的好处。如果你这样做地话，你将会把commons-lang.jar, commons-beanutils.jar,和 commons-digester.jar当成JVM本身来看待。<BR><BR>如果你对Jakarta Commons更深的内容感兴趣的话，可以看一下Jakarta Commons Cookbook。这本书给你很多方法来更好的使用Commons，并告诉你如何将Jakarta Commons与其它的小的开源组件集成，如Velocity, FreeMarker, Lucene, 和 Jakarta Slide。这本书，我介绍了一组广泛的工具从Commons Lang中的简单工具到组合了Commons Digester, Commons Collections, 和Jakarta Lucene来搜索威廉.莎士比亚的著作。我希望这一系列和Jakarta Commons Cookbook这本书能够提供给你一些有趣的低层次的编程问题的解决方案。<BR><BR><B><SPAN style="FONT-SIZE: 16px">1. 用于Commons Digester的基于XML的规则集</SPAN></B><BR>Commons Digester 1.6提供了将XML转化为对象的最简单的方法。Digester已经由O'Reilly网站上的两篇文章介绍过了:“学习和使用Jakarta Digester”，作者是Philipp K. Janert,和“使用Jakarta Commons, 第二部分”，作者是Vikram Goyal。两篇文章都演示了XML规则集的使用，但如何在XML中定义规则集并没有理解。大多所见到的Digester的使用是程序化地定义规则集，以已编译的形式。你应该避免硬编码的Digester规则，特别是当你可以将映射信息存储在外部文件中或一个类路径资源中时。外部化一个Digester规则可以更好地适应一个演化中的XML文档结构或者说一个演化中的对象模型。<BR><BR>为了演示在XML中定义规则集与硬编码的规则集之间的区别，考虑系统解析XML给一个Person bean，包括在下面定义的属性—id, name和age。<BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2>package org.test;<BR><BR>public class Person {<BR>&nbsp;&nbsp;public String id;<BR>&nbsp;&nbsp;public String name;<BR>&nbsp;&nbsp;public int age;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;public Person() {}<BR><BR>&nbsp;&nbsp;public String getId() { return id; }<BR>&nbsp;&nbsp;public void setId(String id) { <BR>&nbsp;&nbsp;&nbsp;&nbsp;this.id = id;<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;public String getName() { return name; }<BR>&nbsp;&nbsp;public void setName(String name) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;this.name = name;<BR>&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;public int getAge() { return age; }<BR>&nbsp;&nbsp;public void setAge(int age) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;this.age = age;<BR>&nbsp;&nbsp;}<BR>}</FONT></PRE><BR><BR><FONT size=2>确认你的应用需要解析一个包含了多个person元素的XML文件。下面的XML文件，data.xml,包含了两个person元素，你想要把它们解析到Person对象中：<BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2><PEOPLE><BR>&nbsp;&nbsp;<PERSON id=1><BR>&nbsp;&nbsp;&nbsp;&nbsp;<NAME>Tom Higgins</NAME><BR>&nbsp;&nbsp;&nbsp;&nbsp;<AGE>25</AGE><BR>&nbsp;&nbsp;</PERSON><BR>&nbsp;&nbsp;<PERSON id=2><BR>&nbsp;&nbsp;&nbsp;&nbsp;<NAME>Barney Smith</NAME><BR>&nbsp;&nbsp;&nbsp;&nbsp;<AGE>75</AGE><BR>&nbsp;&nbsp;</PERSON><BR>&nbsp;&nbsp;<PERSON id=3><BR>&nbsp;&nbsp;&nbsp;&nbsp;<NAME>Susan Shields</NAME><BR>&nbsp;&nbsp;&nbsp;&nbsp;<AGE>53</AGE><BR>&nbsp;&nbsp;</PERSON><BR></PEOPLE></FONT></PRE><BR><BR><FONT size=2>你希望如果结构和XML文件的内容在未来几个月中变化，你不需要在已编译的Java代码中硬编码XML文件的结构。为了做到这一点，你需要在一个XML文件中定义Digester的规则，并且它可以作为一种资源从类路径中装入。下面的XML文档，person-rules.xml,映射person元素到Person bean：<BR></FONT><PRE class=overflow title="pre code"><FONT size=2><DIGESTER-RULES><BR>&nbsp;&nbsp;<PATTERN value="people/person"><BR>&nbsp;&nbsp;&nbsp;&nbsp;<OBJECT-CREATE-RULE classname="org.test.Person" /><BR>&nbsp;&nbsp;&nbsp;&nbsp;<SET-NEXT-RULE <BR methodname="add">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;paramtype="java.lang.Object"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<SET-PROPERTIES-RULE /><BR>&nbsp;&nbsp;&nbsp;&nbsp;<BEAN-PROPERTY-SETTER-RULE pattern="name" /><BR>&nbsp;&nbsp;&nbsp;&nbsp;<BEAN-PROPERTY-SETTER-RULE pattern="age" /><BR>&nbsp;&nbsp;</PATTERN><BR></DIGESTER-RULES></FONT></PRE><BR><BR><FONT size=2>上述所做的是指示Digester创建一个新的Person实例，当它遇到一个person元素时，调用add()来将Person对象加入到一个ArrayList中，设置person元素中相匹配的属性，并从下一级元素name和age中设置name和age的属性。<BR><BR>现在你已经看到了Person类，会被解析的文档，和以XML的形式定义的Digester规则。现在你需要创建一个由person-rules.xml定义了规则的Digester的实例。下面的代码创建 了一个Digester，通过将person-rules.xml的URL传递给DigesterLoader<BR><BR>既然person-rules.xml文件是与解析它的类在同一个包内的类路径资源，URL可以通过getClass().getResource()来得到。DigesterLoader然后解析规则并将它加到新创建的Digester上：<BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2>import org.apache.commons.digester.Digester;<BR>import org.apache.commons.digester.xmlrules.DigesterLoader;<BR><BR>// 从XML规则集中配置Digester<BR>URL rules = getClass().getResource("./person-rules.xml");<BR>Digester digester = <BR>&nbsp;&nbsp;&nbsp;&nbsp;DigesterLoader.createDigester(rules);<BR><BR>// 将空的List推入到Digester的堆栈<BR>List people = new ArrayList();<BR>digester.push( people );<BR><BR>// 解析XML文档<BR>InputStream input = new FileInputStream( "data.xml" );<BR>digester.parse( input );</FONT></PRE><BR><BR><FONT size=2>一旦Digester完成对data.xml的解析，三个Person对象将会在ArrayList people中。<BR>与将规则定义在XML不同的方法是使用简便的方法将它们加入到一个Digester实例中。大多数文章和例子都用这种方法，使用addObjectCreate() 和 addBeanPropertySetter()这样的方法来将规则加入中Digester上。下面的代码加入了与定义在person-rules.xml中相同的规则:<BR><BR></FONT><PRE class=overflow title="pre code"><FONT size=2>digester.addObjectCreate("people/person", Person.class);<BR>digester.addSetNext("people/person", "add", "java.lang.Object");<BR>digester.addBeanPropertySetter("people/person", "name");<BR>digester.addBeanPropertySetter("people/person", "age");</FONT></PRE>
<P><BR><BR><FONT size=2>如果你曾经发现自己正在用一个有着2500行代码的类，用SAX来解析一个巨大的XML文档，或者使用DOM或JDOM的完整的一个集合类，你就会理解XML的解析比它应该做的要复杂的多，就大多数情况来说。如果你正在建一个有着严格的速度和内存要求的高效的系统，你会需要SAX解析器的速度。如果你需要DOM级别3的复杂度，你会需要像Apache Xerces的解析器。但如果你只是简单的试图将几个XML文档解析到对象中去的话，看一下Commons Digester, 并把你的规则定义在一个XML文件中。<BR><BR>任何时候你都应该将配置信息从硬编码中移出来。我会建议你在一个XML文件中定义规则并从文件系统或类路径中装入它。这样可以使你的程序更好地适应XML文档以及对象模型的变化。有关在XML文件中定义Digester规则的更多的资料，参看Jakarta Commons Cookbook一书的6.2节,“将XML文档转换为对象”<BR><BR>&gt;&gt;&gt;&gt;<A HREF="/flyingis/archive/2005/11/09/18958.html">下一章</A></FONT></P><img src ="http://www.blogjava.net/flyingis/aggbug/18957.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-11-09 12:18 <a href="http://www.blogjava.net/flyingis/archive/2005/11/09/18957.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用Java实现自动在数据库表中生成ID号(改进算法)[原创]</title><link>http://www.blogjava.net/flyingis/archive/2005/11/06/18471.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Sun, 06 Nov 2005 09:04:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/11/06/18471.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/18471.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/11/06/18471.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/18471.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/18471.html</trackback:ping><description><![CDATA[<FONT size=2>&nbsp;&nbsp;&nbsp;&nbsp;作者：<A HREF="/flyingis/"><FONT color=#000080>Flyingis</FONT></A><BR><BR>&nbsp;&nbsp;&nbsp; 在前面的一篇日志里面，我设计了在数据库表中自动生成ID号的一种算法(</FONT><A HREF="/flyingis/archive/2005/10/31/17522.html" target=_blank><FONT size=2>点击这里查看</FONT></A><FONT size=2>)，这个算法主要应用于字典表的修改中。字典表的ID号是这样设计的：A01、A05、A28等等，即一位字母+两位数字。由于每个字典表的ID号的第一个字母对于一个字典表来说是固定的，这样做的目的在于在其它表中查看数据的时候可以很容易分辨字典项的ID号是属于哪一个数据字典的，因此这就限制了每个字典表的数据不能超过99条，当数据量大于99条的时候，那个算法就不再适用。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;因此这里给出了一个改进的算法(其实只作了一点点改进)，可以满足数据在1～999条之间的数据字典，这对于绝大多数应用来说已经是绰绰有余了。下面就给出具体的方法：<BR><BR>/*&nbsp;<BR>&nbsp;*&nbsp;功能：增加字典信息时，自动生成最小的ID号码<BR>&nbsp;*&nbsp;参数：String&nbsp;字典表名称 first&nbsp;字典ID的首字母，代表唯一的字典<BR>&nbsp;*&nbsp;返回：String&nbsp;生成的最小ID号码<BR>&nbsp;*/<BR>public&nbsp;String&nbsp;getId(String&nbsp;table,&nbsp;String&nbsp;first)&nbsp;{<BR><BR>//&nbsp;所有除去首字母后的ID号码--整型，例如：11<BR>int[]&nbsp;sid;<BR>//&nbsp;所有原始ID号码，例如：A011<BR>String[]&nbsp;rid;<BR>//&nbsp;除去首字母后最小的ID号码--字符串<BR>String&nbsp;sid_new&nbsp;=&nbsp;null;<BR>//&nbsp;程序返回的最小的原始ID号码<BR>String&nbsp;rid_new&nbsp;=&nbsp;null;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;循环参数<BR>int&nbsp;i&nbsp;=&nbsp;0;<BR>int&nbsp;k&nbsp;=&nbsp;0;<BR><BR>con&nbsp;=&nbsp;DatabaseConnection.getConnection("jdbc/wutie";<BR>Statement&nbsp;stm&nbsp;=&nbsp;null;<BR>ResultSet&nbsp;rst&nbsp;=&nbsp;null;<BR>RowSet&nbsp;rowRst&nbsp;=&nbsp;null;<BR>String&nbsp;sql&nbsp;=&nbsp;"SELECT&nbsp;*&nbsp;FROM&nbsp;"&nbsp;+&nbsp;table&nbsp;+&nbsp;"&nbsp;order&nbsp;by&nbsp;id";<BR><BR>try&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(con.isClosed())&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;IllegalStateException("error.sql.unexpected";<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;stm&nbsp;=&nbsp;con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,&nbsp;ResultSet.CONCUR_UPDATABLE);<BR>&nbsp;&nbsp;&nbsp;&nbsp;rst&nbsp;=&nbsp;stm.executeQuery(sql);<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(rst.next())&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;k++;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;sid&nbsp;=&nbsp;new&nbsp;int[k];<BR>&nbsp;&nbsp;&nbsp;&nbsp;rid&nbsp;=&nbsp;new&nbsp;String[k];<BR>&nbsp;&nbsp;&nbsp;&nbsp;rst&nbsp;=&nbsp;stm.executeQuery(sql);<BR>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果不存在结果集，则直接在first字母后面加001，例如first="A",rid_new=A001<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!rst.first())&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rid_new&nbsp;=&nbsp;first.concat("001";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;rid_new;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果存在结果集，则将表中所有ID号存入数组中，并转换为整型数据<BR>&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*<BR>&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(rst.next())&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rid[i]&nbsp;=&nbsp;rst.getString("id";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sid[i]&nbsp;=&nbsp;Integer.parseInt(rid[i].substring(1));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i++;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(rst.previous();&nbsp;rst.next();&nbsp;i++)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rid[i]&nbsp;=&nbsp;rst.getString("id";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sid[i]&nbsp;=&nbsp;Integer.parseInt(rid[i].substring(1));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果第一条记录ID号不为fisrt+001，例如A003、A018、A109等，则返回新增数据的ID号为A001<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(sid[0]&nbsp;!=&nbsp;1)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rid_new&nbsp;=&nbsp;first.concat("001";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;rid_new;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果第一条记录ID号为first+001，即A001，则执行下面语句<BR>&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果总记录数只有一条，例如A001，则返回新增数据为A002<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(i&nbsp;==&nbsp;1)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rid_new&nbsp;=&nbsp;first.concat("002";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;rid_new;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;j&nbsp;=&nbsp;1;&nbsp;j&nbsp;&lt;&nbsp;k;&nbsp;j++)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果相邻两条记录ID号的整数位相差1，则保存新增数据ID号整数位是前一位ID号整数位加1<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(sid[j]&nbsp;==&nbsp;sid[j-1]&nbsp;+&nbsp;1)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(sid[j]&nbsp;&lt;&nbsp;9)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sid_new&nbsp;=&nbsp;String.valueOf(sid[j]&nbsp;+&nbsp;1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rid_new&nbsp;=&nbsp;first.concat("00".concat(sid_new);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if&nbsp;(sid[j]&gt;9&nbsp;&amp;&amp;&nbsp;sid[j]&lt;100){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sid_new&nbsp;=&nbsp;String.valueOf(sid[j]&nbsp;+&nbsp;1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rid_new&nbsp;=&nbsp;first.concat("0").concat(sid_new);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sid_new&nbsp;=&nbsp;String.valueOf(sid[j]&nbsp;+&nbsp;1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rid_new&nbsp;=&nbsp;first.concat(sid_new);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>//&nbsp;如果相邻两条记录ID号的整数位相差非1，则返回新增数据ID号整数位是前一位ID号整数位加1<BR>if&nbsp;(sid[j]&nbsp;!=&nbsp;sid[j-1]&nbsp;+&nbsp;1)&nbsp;{<BR>if&nbsp;(sid[j-1]&nbsp;&lt;&nbsp;9)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;sid_new&nbsp;=&nbsp;String.valueOf(sid[j-1]&nbsp;+&nbsp;1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;rid_new&nbsp;=&nbsp;first.concat("00".concat(sid_new);<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;rid_new;<BR>}<BR>else&nbsp;if&nbsp;(sid[j]&gt;9&nbsp;&amp;&amp;&nbsp;sid[j]&lt;100){<BR>&nbsp;&nbsp;&nbsp;&nbsp;sid_new&nbsp;=&nbsp;String.valueOf(sid[j-1]&nbsp;+&nbsp;1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;rid_new&nbsp;=&nbsp;first.concat("0").concat(sid_new);<BR>}<BR>else&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;sid_new&nbsp;=&nbsp;String.valueOf(sid[j-1]&nbsp;+&nbsp;1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;rid_new&nbsp;=&nbsp;first.concat(sid_new);<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;rid_new;<BR>}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;rid_new;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>}<BR>catch&nbsp;(SQLException&nbsp;e)&nbsp;{<BR>e.printStackTrace();<BR>throw&nbsp;new&nbsp;RuntimeException("error.sql.runtime";<BR>}<BR>finally&nbsp;{<BR>try&nbsp;{<BR>stm.close();<BR>con.close();<BR>}<BR>catch&nbsp;(SQLException&nbsp;e1)&nbsp;{<BR>e1.printStackTrace();<BR>throw&nbsp;new&nbsp;RuntimeException("error.sql.runtime";<BR>}<BR>}<BR><BR>}<BR><BR><FONT color=#0000ff>注意</FONT>：之所以生成A01而不是A1，是因为在SQLServer2000中根据ID号正确排序的需要，如果按照升序排列，A1后面是A10、A11等，而不是A2。另外，在Hibernate中有多种自动生成ID字段的方法，但是这个项目比较小，我没有使用Hibernate中间件，这里提供的只是生成字典ID字段的一种简单思路，相比<A HREF="/flyingis/archive/2005/10/31/17522.html"><FONT color=#0000ff>原有算法</FONT></A>改进了一点，可以适用于字典项不多于1000项的情况，一般情况下，字典项是不可能超过1000项了，在我参与的这个小项目中已经是完全够用了。还有什么更好的方法和思路还请大家多指教！</FONT><img src ="http://www.blogjava.net/flyingis/aggbug/18471.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-11-06 17:04 <a href="http://www.blogjava.net/flyingis/archive/2005/11/06/18471.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>内部类的作用</title><link>http://www.blogjava.net/flyingis/archive/2005/11/05/18271.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Sat, 05 Nov 2005 04:11:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/11/05/18271.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/18271.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/11/05/18271.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/18271.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/18271.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&nbsp;&nbsp;&nbsp; 作者：<A HREF="/flyingis/"><FONT color=#000080>Flyingis</FONT></A><BR><BR>&nbsp;&nbsp;&nbsp; 内部类的功能在于，每个内部类都能独立的继承一个接口的实现，所以无论外围类是否已经继承了某个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">实现，对于内部类都没有影响。内部类使得多重继承的解决方案变得完整，并且内部类允许继承多个非接口类型</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类或抽象类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">interface Sa {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>void today();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>void yesterday();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>boolean check();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">public class Sab {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>private i = 10;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>private Sab_inner implements Sa {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">void today() {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>return i;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">void yesterday() {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>return --i;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">Boolean check() {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>return i = = 0;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">public Sa getSa() {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>return new Sab_inner();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">从上面这段代码可以看出，如果我们只是声明外围类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Sab</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">实现接口</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Sa</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，那么对于某个特定的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Sab</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象只能有一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Sa</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。但是如果使用了内部类，我们就可以通过方法</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">getSa()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来获得一个实现</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Sa</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口的序列，这样就增加了应用上的灵活性。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">在控制框架，特别是图形用户界面的设计中更能体现内部类的价值，具体的可以参考这方面的资料。</SPAN><img src ="http://www.blogjava.net/flyingis/aggbug/18271.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-11-05 12:11 <a href="http://www.blogjava.net/flyingis/archive/2005/11/05/18271.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>理解Java内部类的基本特性(二)</title><link>http://www.blogjava.net/flyingis/archive/2005/11/04/18182.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Fri, 04 Nov 2005 10:55:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/11/04/18182.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/18182.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/11/04/18182.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/18182.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/18182.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">作者：<A HREF="/flyingis/"><FONT color=#000080>Flyingis</FONT></A><BR><BR>4.&nbsp; </FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内部类拥有其外围类的所有元素的访问权，当某个外围类的对象创建了一个内部类对象时，此内部类对象必定会保存一个指向那个外围类对象的引用。然后，在访问此外围类的成员时，就是用那个“隐藏”的引用来选择外围类的成员。这与</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">C++</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">嵌套类的设计非常不同，在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">C++</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中只是单纯的名字隐藏机制，与外围对象没有联系，也没有隐含的访问权。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 
<P></P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; 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-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">
<P></P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">5.&nbsp; </FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中实现</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">C++</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的嵌套类功能也是通过嵌套类的机制来实现的，区别是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">C++</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的嵌套类不能访问私有成员，在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中则可以。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 
<P></P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，使用嵌套类可以使得内部类对象与其外围类对象之间有联系，语法上是将内部类声明为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">static</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。而在普通的内部类中是不能有</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">static</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">static</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">字段和嵌套类的。通常，我们可以在一个普通的内部类中，通过一个特殊的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">this</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">引用链接到其外围类对象，如外围类是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Fruit</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，那么在内部类中应该通过</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Fruit.this</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; 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-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">
<P></P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">6.&nbsp; </FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内部类的继承比较特殊，我通过一个例子来向大家展示：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 
<P></P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">class Fruit { 
<P></P></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>class Inner {} 
<P></P></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">} 
<P></P></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">public class Apple extends Fruit.Inner { 
<P></P></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Apple(Fruit f) { 
<P></P></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>f.super(); //</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为什么要这样使用我也不明白</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 
<P></P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">} 
<P></P></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">public static void main(String[] args) { 
<P></P></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Fruit f = new Fruit(); 
<P></P></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Apple a = new Apple(f); 
<P></P></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">} 
<P></P></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">} 
<P></P></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">其中为什么要外围类调用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">super()</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; 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-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">
<P></P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">7.&nbsp; </FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当继承某个外围类的时候，内部类并没有发生任何改变，基类和继承类中的两个内部类是完全独立的实体，各自在自己的命名空间内。如果明确继承某个内部类，则会覆盖原来的内部类。如：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 
<P></P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">public class A extends Atop { 
<P></P></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public Inner extends Atop.Inner {} 
<P></P></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">}</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">
<P></P></FONT></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">8.&nbsp; </FONT></SPAN><SPAN style="FONT-SIZE: 10pt; 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-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">
<P></P></SPAN>
<P></P><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">9.&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">内部类标识符是外围类的名字＋</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">$</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">＋内部类的名字，如果内部类是匿名的，则会由编译器产生一个数字作为其标识符。</SPAN><img src ="http://www.blogjava.net/flyingis/aggbug/18182.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-11-04 18:55 <a href="http://www.blogjava.net/flyingis/archive/2005/11/04/18182.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>理解Java内部类的基本特性(一)</title><link>http://www.blogjava.net/flyingis/archive/2005/11/04/18168.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Fri, 04 Nov 2005 09:11:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/11/04/18168.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/18168.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/11/04/18168.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/18168.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/18168.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&nbsp;&nbsp;&nbsp; 作者：<A HREF="/flyingis/"><FONT color=#000080>Flyingis</FONT></A><BR><BR>&nbsp;&nbsp;&nbsp; 内部类是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语言一个重要的基本特性，在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">开发的许多领域都会经常用到。内部类的定义说简单一点就是将一个类定义在另外一个类的内部。内部类允许你把一些逻辑相关的类组织在一起，控制内部类代码的可视性，它和类的组合是完全不同的概念。内部类主要有以下比较关键的特性：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">1.&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">普通的非内部类不能被声明为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">private</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">protected</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，否则就失去了创建该类的意义。但是内部类通常可以被声明为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">private</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">protected</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类型，因为这样可以防止他人对该内部类实现的功能进行修改，达到隐藏实现细节的目的。例如：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">class Fruit {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>private class Weight {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">private String i;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">private Weight(String j) {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>i = j;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">public String read() {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>return i;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">class test {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public static void main(String[] args) {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">Fruit f = new Fruit();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">f.Weight w = f.new Weight(); //</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不能访问</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">private</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类，如果</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Weight</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">protected</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类型则可以</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">2.&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在方法或某控制语句</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">(if/for/while</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">等</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的作用域内定义内部类，将只能在该范围内调用内部类的方法和成员变量。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">3.&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">匿名内部类是一种特殊的内部类，如果希望它使用一个在其外部定义的对象，那么编译器会要求其参数引用是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">final</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">public class Fruit {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public Tea cont(final int j) {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">return new Tea() {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>private int i = j;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public int read() {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>return i;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 30.7pt; mso-char-indent-count: 3.07"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}; //</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">注意这里的分号</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">public static void main(String[] args) {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Fruit f = new Fruit();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Tea t = f.cont;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">而当方法</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">cont(final int j)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的参数</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">j</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">只是被传递到匿名类中的构造器时，可以不用被声明为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">final</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类型，如</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">return new Tea(j)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。这里提到了匿名内部类的构造器，那么它是怎么被初始化的呢？</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">public class Fruit {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp;</SPAN><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>public Tea cont(int j) {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">return new Tea(j) {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">System.out.println(j);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}; <o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">还可以这样初始化匿名内部类：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">public class Fruit {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public Tea cont(final int j) {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">return new Tea(j) {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>int i;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>// </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">初始化匿名内部类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>i = j;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>System.out.print(i);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 30.7pt; mso-char-indent-count: 3.07"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}; <o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">方法</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">cont()</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">可以被称为实例初始化方法，使得匿名内部类通过构造器而被初始化，在实际应用中，我们不能重载实例初始化方法，因为匿名内部类只能有一个构造方法。</SPAN><img src ="http://www.blogjava.net/flyingis/aggbug/18168.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-11-04 17:11 <a href="http://www.blogjava.net/flyingis/archive/2005/11/04/18168.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java接口特性学习</title><link>http://www.blogjava.net/flyingis/archive/2005/11/02/17879.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Wed, 02 Nov 2005 13:18:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/11/02/17879.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/17879.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/11/02/17879.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/17879.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/17879.html</trackback:ping><description><![CDATA[<FONT size=2><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt">
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">作者：<A HREF="/flyingis/"><FONT color=#000080>Flyingis</FONT></A><BR><BR>&nbsp;&nbsp;&nbsp; 在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中看到接口，第一个想到的可能就是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">C++</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的多重继承和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的另外一个关键字</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">abstract</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。从另外一个角度实现多重继承是接口的功能之一，接口的存在可以使</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的对象可以向上转型为多个基类型，并且和抽象类一样可以防止他人创建该类的对象，因为接口不允许创建对象。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">interface</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">关键字用来声明一个接口，它可以产生一个完全抽象的类，并且不提供任何具体实现。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">interface</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的特性整理如下：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></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="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">1.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></FONT></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口中的方法可以有参数列表和返回类型，但不能有任何方法体。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></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="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">2.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></FONT></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口中可以包含字段，但是会被隐式的声明为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">static</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">final</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></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="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">3.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></FONT></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口中的字段只是被存储在该接口的静态存储区域内，而不属于该接口。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></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="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">4.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></FONT></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口中的方法可以被声明为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">public</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或不声明，但结果都会按照</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">public</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类型处理。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></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="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">5.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></FONT></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当实现一个接口时，需要将被定义的方法声明为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">public</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类型的，否则为默认访问类型，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">编译器不允许这种情况。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></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="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">6.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></FONT></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果没有实现接口中所有方法，那么创建的仍然是一个接口。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></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="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">7.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></FONT></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">扩展一个接口来生成新的接口应使用关键字</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">extends</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，实现一个接口使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">implements</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">interface</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在某些地方和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">abstract</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有相似的地方，但是采用哪种方式来声明类主要参照以下两点：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo2; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">1.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></FONT></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果要创建不带任何方法定义和成员变量的基类，那么就应该选择接口而不是抽象类。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo2; tab-stops: list 18.0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">2.<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></FONT></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果知道某个类应该是基类，那么第一个选择的应该是让它成为一个接口，只有在必须要有方法定义和成员变量的时候，才应该选择抽象类。因为抽象类中允许存在一个或多个被具体实现的方法，只要方法没有被全部实现该类就仍是抽象类。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p><FONT face="Times New Roman">&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">以上就是接口的基本特性和应用的领域，但是接口绝不仅仅如此，在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语法结构中，接口可以被嵌套，既可以被某个类嵌套，也可以被接口嵌套。这在实际开发中可能应用的不多，但也是它的特性之一。需要注意的是，在实现某个接口时，并不需要实现嵌套在其内部的任何接口，而且，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">private</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口不能在定义它的类之外被实现。</SPAN></P>
<P></SPAN></FONT>&nbsp;</P><img src ="http://www.blogjava.net/flyingis/aggbug/17879.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-11-02 21:18 <a href="http://www.blogjava.net/flyingis/archive/2005/11/02/17879.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多态学习心得</title><link>http://www.blogjava.net/flyingis/archive/2005/10/31/17579.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Mon, 31 Oct 2005 11:28:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/10/31/17579.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/17579.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/10/31/17579.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/17579.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/17579.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">作者：<A HREF="/flyingis/"><FONT color=#000080>Flyingis</FONT></A><BR><BR>&nbsp;&nbsp;&nbsp; 这几天我在重新复习</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语言基础，虽然和团队一起，自己个人都进行了实际项目的开发，但越往上面走越觉得自己应该花点时间看看</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的基础知识，巩固一下基础。今天复习的是多态，同时写下自己的学习心得。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 
<P></P></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据抽象、继承和多态是面向对象程序设计语言的三大特性。多态，我觉得它的作用就是用来将接口和实现分离开，改善代码的组织结构，增强代码的可读性。在某些很简单的情况下，或许我们不使用多态也能开发出满足我们需要的程序，但大多数情况，如果没有多态，就会觉得代码极其难以维护。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 
<P></P></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，谈论多态就是在讨论方法调用的绑定，绑定就是将一个方法调用同一个方法主体关联起来。在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">C</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语言中，方法</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">(</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">C</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中称为函数</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">)</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的绑定是由编译器来实现的，在英文中称为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">early binding(</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">前期绑定</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">)</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，因此，大家自然就会想到相对应的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">late binding(</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">后期绑定</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">)</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，这在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中通常叫做</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">run-time binding(</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">运行时绑定</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">)</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，我个人觉得这样称呼更贴切，运行时绑定的目的就是在代码运行的时候能够判断对象的类型。通过一个简单的例子说明：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 
<P></P></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">/** 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>* </FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">定义一个基类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 
<P></P></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>*/ 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">public Class Parents { 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public void print() { 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>System.out.println(“parents”); 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">} 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">} 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">/** 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>* </FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">定义两个派生类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 
<P></P></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>*/ 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">public Class Father extends Parents { 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public void print() { 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>System.out.println(“father”); 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">} 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">} 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">public Class Mother extends Parents { 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public void print() { 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;</SPAN>System.out.println(“mother”); 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">} 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">} 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">/** 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>* </FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">测试输出结果的类</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 
<P></P></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>*/ 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">public Class Test { 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public void find(Parents p) { 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>p.print(); 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">} 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">public static void main(String[] args) { 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Test t = new Test(); 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Father f = new Father(); 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Mother m = new Mother(); 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>t.find(f); 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>t.find(m); 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">} 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">} 
<P></P></FONT></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">最后的输出结果分别是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">father</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">mother</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，将派生类的引用传给基类的引用，然后调用重写方法，基类的引用之所以能够找到应该调用那个派生类的方法，就是因为程序在运行时进行了绑定。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 
<P></P></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">学过</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">基础的人都能很容易理解上面的代码和多态的原理，但是仍有一些关键的地方需要注意的，算是自己对多态的一个小结：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 
<P></P></SPAN>
<P><FONT size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><FONT face="Times New Roman"><SPAN lang=EN-US style="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">1.<SPAN style="FONT: 7pt 'Times New Roman'"><FONT size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN></FONT><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中除了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">static</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">final</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法外，其他所有的方法都是运行时绑定的。在我另外一篇文章中说到</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">private</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法都被隐式指定为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">final</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的，因此</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">final</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的方法不会在运行时绑定。当在派生类中重写基类中</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">static</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">final</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、或</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">private</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法时，实质上是创建了一个新的方法。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 
<P></P></SPAN>
<P><FONT size=2></FONT></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="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">2.<SPAN style="FONT: 7pt 'Times New Roman'"><FONT size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></FONT></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在派生类中，对于基类中的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">private</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法，最好采用不同的名字。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 
<P></P></SPAN>
<P><FONT size=2></FONT></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="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">3.<SPAN style="FONT: 7pt 'Times New Roman'"><FONT size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></FONT></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包含抽象方法的类叫做抽象类。注意定义里面包含这样的意思，只要类中包含一个抽象方法，该类就是抽象类。抽象类在派生中就是作为基类的角色，为不同的子类提供通用的接口。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 
<P></P></SPAN>
<P><FONT size=2></FONT></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="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">4.<SPAN style="FONT: 7pt 'Times New Roman'"><FONT size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></FONT></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象清理的顺序和创建的顺序相反，当然前提是自己想手动清理对象，因为大家都知道</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">Java</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">垃圾回收器。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 
<P></P></SPAN>
<P><FONT size=2></FONT></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="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">5.<SPAN style="FONT: 7pt 'Times New Roman'"><FONT size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></FONT></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在基类的构造方法中小心调用基类中被重写的方法，这里涉及到对象初始化顺序。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 
<P></P></SPAN>
<P><FONT size=2></FONT></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="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">6.<SPAN style="FONT: 7pt 'Times New Roman'"><FONT size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></FONT></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">构造方法是被隐式声明为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><FONT face="Times New Roman">static</FONT></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"> 
<P></P></SPAN>
<P><FONT size=2></FONT></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="FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">7.<SPAN style="FONT: 7pt 'Times New Roman'"><FONT size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></FONT></SPAN></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用继承表达行为间的差异，用字段表达状态上的变化。</SPAN></P><img src ="http://www.blogjava.net/flyingis/aggbug/17579.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-10-31 19:28 <a href="http://www.blogjava.net/flyingis/archive/2005/10/31/17579.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用Java实现自动在数据库表中生成ID号[原创]</title><link>http://www.blogjava.net/flyingis/archive/2005/10/31/17522.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Mon, 31 Oct 2005 03:37:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/10/31/17522.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/17522.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/10/31/17522.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/17522.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/17522.html</trackback:ping><description><![CDATA[<FONT size=2>&nbsp;&nbsp;&nbsp; 作者：<A HREF="/flyingis/"><FONT color=#000080>Flyingis</FONT></A><BR><BR>&nbsp;&nbsp;&nbsp; 前段时间用Struts开发了一个B/S结构的信息管理系统，其中有一个功能是要求管理员能够对数据字典进行修改，数据字典的表结构基本上都是table(id,&nbsp;name)，id为数据库其它表中所存储的内容，表示方式为A01、A02、A08、B10、B25、C12等等，一个字典就分配一个字母作为其ID号的标识，其实就是为了调试时方便，在其它的表中判断该字典的名称。因此对于一个特定的字典表来说，其ID号排序应该是A01、A02、A03、A04……&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;在对字典内容进行删除的时候并不需要考虑什么，直接使用DELETE语句就可以了。关键是添加字典信息时，管理员需要在表单中填写的是table中的name字段，ID号如何生成就需要自己用代码来实现(包括ID号的01号空缺，中间有断开等情况)。下面是我设计的代码，其中关键的地方都有详细的注释：<BR><BR>/*&nbsp;<BR>&nbsp;*&nbsp;功能：增加字典信息时，自动生成最小的ID号码<BR>&nbsp;*&nbsp;参数：String&nbsp;字典表名称 first&nbsp;字典ID的首字母，代表唯一的字典<BR>&nbsp;*&nbsp;返回：String&nbsp;生成的最小ID号码<BR>&nbsp;*/<BR>public&nbsp;String&nbsp;getId(String&nbsp;table,&nbsp;String&nbsp;first)&nbsp;{<BR><BR>//&nbsp;所有除去首字母后的ID号码--整型，例如：11<BR>int[]&nbsp;sid;<BR>//&nbsp;所有原始ID号码，例如：A11<BR>String[]&nbsp;rid;<BR>//&nbsp;除去首字母后最小的ID号码--字符串<BR>String&nbsp;sid_new&nbsp;=&nbsp;null;<BR>//&nbsp;程序返回的最小的原始ID号码<BR>String&nbsp;rid_new&nbsp;=&nbsp;null;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;循环参数<BR>int&nbsp;i&nbsp;=&nbsp;0;<BR>int&nbsp;k&nbsp;=&nbsp;0;<BR><BR>con&nbsp;=&nbsp;DatabaseConnection.getConnection("jdbc/wutie");<BR>Statement&nbsp;stm&nbsp;=&nbsp;null;<BR>ResultSet&nbsp;rst&nbsp;=&nbsp;null;<BR>RowSet&nbsp;rowRst&nbsp;=&nbsp;null;<BR>String&nbsp;sql&nbsp;=&nbsp;"SELECT&nbsp;*&nbsp;FROM&nbsp;"&nbsp;+&nbsp;table&nbsp;+&nbsp;"&nbsp;order&nbsp;by&nbsp;id";<BR><BR>try&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(con.isClosed())&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;IllegalStateException("error.sql.unexpected");<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;stm&nbsp;=&nbsp;con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,&nbsp;ResultSet.CONCUR_UPDATABLE);<BR>&nbsp;&nbsp;&nbsp;&nbsp;rst&nbsp;=&nbsp;stm.executeQuery(sql);<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(rst.next())&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp; k++;<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;sid&nbsp;=&nbsp;new&nbsp;int[k];<BR>&nbsp;&nbsp;&nbsp;&nbsp;rid&nbsp;=&nbsp;new&nbsp;String[k];<BR>&nbsp;&nbsp;&nbsp;&nbsp;rst&nbsp;=&nbsp;stm.executeQuery(sql);<BR>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果不存在结果集，则直接在first字母后面加01，例如first="A",rid_new=A01<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!rst.first())&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp; rid_new&nbsp;=&nbsp;first.concat("01");<BR>&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp;rid_new;<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果存在结果集，则将表中所有ID号存入数组中，并转换为整型数据<BR>&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(rst.next())&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rid[i]&nbsp;=&nbsp;rst.getString("id");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sid[i]&nbsp;=&nbsp;Integer.parseInt(rid[i].substring(1));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i++;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<BR>&nbsp;&nbsp;&nbsp;&nbsp; for&nbsp;(rst.previous();&nbsp;rst.next();&nbsp;i++)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp; rid[i]&nbsp;=&nbsp;rst.getString("id");<BR>&nbsp;&nbsp;&nbsp;&nbsp; sid[i]&nbsp;=&nbsp;Integer.parseInt(rid[i].substring(1));<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;如果第一条记录ID号不为fisrt+01，例如A03、A05、A18等，则返回新增数据的ID号为A01<BR>&nbsp;&nbsp;&nbsp;&nbsp; if&nbsp;(sid[0]&nbsp;!=&nbsp;1)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp; rid_new&nbsp;=&nbsp;first.concat("01");<BR>&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp;rid_new;<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;如果第一条记录ID号为first+1，即A1，则执行下面语句<BR>&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;如果总记录数只有一条，例如A1，则返回新增数据为A02<BR>&nbsp;&nbsp;&nbsp;&nbsp; if&nbsp;(i&nbsp;==&nbsp;1)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp; rid_new&nbsp;=&nbsp;first.concat("02");<BR>&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp;rid_new;<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;j&nbsp;=&nbsp;1;&nbsp;j&nbsp;&lt;&nbsp;k;&nbsp;j++)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;如果相邻两条记录ID号的整数位相差1，则保存新增数据ID号整数位是前一位ID号整数位加1<BR>&nbsp;&nbsp;&nbsp;&nbsp; if&nbsp;(sid[j]&nbsp;==&nbsp;sid[j-1]&nbsp;+&nbsp;1)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp; if&nbsp;(sid[j]&nbsp;&lt;&nbsp;9)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp; sid_new&nbsp;=&nbsp;String.valueOf(sid[j]&nbsp;+&nbsp;1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;rid_new&nbsp;=&nbsp;first.concat("0").concat(sid_new);<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp; sid_new&nbsp;=&nbsp;String.valueOf(sid[j]&nbsp;+&nbsp;1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;rid_new&nbsp;=&nbsp;first.concat(sid_new);<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>//&nbsp;如果相邻两条记录ID号的整数位相差非1，则返回新增数据ID号整数位是前一位ID号整数位加1<BR>if&nbsp;(sid[j]&nbsp;!=&nbsp;sid[j-1]&nbsp;+&nbsp;1)&nbsp;{<BR>if&nbsp;(sid[j-1]&nbsp;&lt;&nbsp;9)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;sid_new&nbsp;=&nbsp;String.valueOf(sid[j-1]&nbsp;+&nbsp;1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;rid_new&nbsp;=&nbsp;first.concat("0").concat(sid_new);<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;rid_new;<BR>}<BR>else&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;sid_new&nbsp;=&nbsp;String.valueOf(sid[j-1]&nbsp;+&nbsp;1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;rid_new&nbsp;=&nbsp;first.concat(sid_new);<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;rid_new;<BR>}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;rid_new;<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;&nbsp;&nbsp;<BR>}<BR>catch&nbsp;(SQLException&nbsp;e)&nbsp;{<BR>e.printStackTrace();<BR>throw&nbsp;new&nbsp;RuntimeException("error.sql.runtime");<BR>}<BR>finally&nbsp;{<BR>try&nbsp;{<BR>stm.close();<BR>con.close();<BR>}<BR>catch&nbsp;(SQLException&nbsp;e1)&nbsp;{<BR>e1.printStackTrace();<BR>throw&nbsp;new&nbsp;RuntimeException("error.sql.runtime");<BR>}<BR>}<BR><BR>}<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=#0000ff>注意</FONT>：之所以生成A01而不是A1，是因为在SQLServer2000中根据ID号正确排序的需要，如果按照升序排列，A1后面是A10、A11等，而不是A2。另外，在Hibernate中有多种自动生成ID字段的方法，但是这个项目比较小，我没有使用Hibernate中间件，这里提供的只是生成字典ID字段的一种简单思路，只能用于字典项不多于100项的情况，一般的情况可以满足了，但如果超过100项只需简单修改一下代码，不足之处还请大家多指教！</FONT><img src ="http://www.blogjava.net/flyingis/aggbug/17522.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-10-31 11:37 <a href="http://www.blogjava.net/flyingis/archive/2005/10/31/17522.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>小议final关键字</title><link>http://www.blogjava.net/flyingis/archive/2005/10/28/17274.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Fri, 28 Oct 2005 13:50:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/10/28/17274.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/17274.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/10/28/17274.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/17274.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/17274.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">作者：<A HREF="/flyingis/"><FONT color=#000080>Flyingis</FONT></A><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语言中一个很微妙的关键字，而使用它通常出于两种理由：设计与效率。我们可以对数据成员、方法和类使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">final</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">关键字。<BR>&nbsp;&nbsp;&nbsp; </SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">final</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据的声明是为了告诉编译器有一块数据是恒定不变的。对于基本数据类型，编译器可以将该常量值代入任何可能用到它的计算式中去，即可以在编译时执行计算，这样就减轻了一些运行时的负担。在对这个常量进行定义的时候，必须对其进行赋值，当然也可以在类的构造函数中赋值。当对对象引用使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">final</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">声明时，其含义容易让人迷惑，因为对于对象的引用，</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">final</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以使引用恒定不变，它可以使该引用始终指向一个对象，但是，对象自身是可以被修改的，所以在这种情况下感觉</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">final</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">几乎没什么作用，数组也是对象，它也存在这种情况，通过下面这个例子说明：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><BR>class Fruit {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>private final int[] m = {1, 2, 3};<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public static void main(String[] args) {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">Fruit f = new Fruit();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">for(int i = 0; i &lt; m.length(); i++) {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>f.m[i]++;<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>//</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以改变</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">f.m = new int[5];<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>//</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不能指向另外的一个对象，错误！</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><BR>&nbsp;&nbsp;&nbsp; 对基本数据类型的数据使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">final</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的另外一个用处就是可以做到根据对象的不同而使类的功能发生改变，例如：<BR><BR></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">class Apple {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>private final int i;<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>//</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">没有初始化，需要在构造函数中赋值</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>private static Random r = new Random();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>public Apple() {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>i = r.newInt(10);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">public Apple(int j) {<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>i += j;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10pt; mso-char-indent-count: 1.0"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt">}<BR><BR></SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&nbsp;&nbsp;&nbsp; 使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">final</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法，可以把方法锁定，防止继承类修改它。并且使用方法类在一般情况下可以提高效率，让编译器将针对该方法的所有调用都转为内嵌式的调用，即以方法体中的实际代码来代替方法调用的代码，这样就消除了方法调用的开销。但是对于</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">private</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类型的方法而言意义不大，因为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">private</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法都已经被隐式的制定为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">final</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，如果继承类试图将该方法声明为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">public/protected/</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">默认的同名方法，将不能覆盖基类中的方法，这样做是声明了一个新的方法，这是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的多态，但是也说明了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">private</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法将不会起到什么作用。<BR>&nbsp;&nbsp;&nbsp; </SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">final</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类的设计是为了防止以后对该类进行变动，并不希望它有子类，在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">final</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类中所有的方法都隐式指定为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">final</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的，并且这些方法无法被覆盖，而</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">final</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类的字段将保持原义，不受</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">final</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类的影响！<BR><BR>&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这段时间在重新复习</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的基本细节与概念，欢迎拍砖！共同学习！</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt"><o:p></o:p></SPAN></P><img src ="http://www.blogjava.net/flyingis/aggbug/17274.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-10-28 21:50 <a href="http://www.blogjava.net/flyingis/archive/2005/10/28/17274.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Linux下安装JDK及环境设置</title><link>http://www.blogjava.net/flyingis/archive/2005/10/28/17191.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Fri, 28 Oct 2005 07:59:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/10/28/17191.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/17191.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/10/28/17191.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/17191.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/17191.html</trackback:ping><description><![CDATA[<font size="2">作者：<a href="http://www.blogjava.net/flyingis/"><font color="#000080">Flyingis</font></a><br><br>我在Fedora&nbsp;Core&nbsp;3上已经成功安装了jdk(jdk-1_5_0_02-linux-i586.rpm)，其它版本的Linux基本相同，过程如下：<br><br>1.&nbsp;先从网上下载jdk(jdk-1_5_0_02-linux-i586.rpm)&nbsp;，推荐SUN的官方网站www.sun.com，下载后放在/home目录中，当然其它地方也行。<br><br>进入安装目录<br>#cd&nbsp;/home<br>#cp&nbsp;jdk-1_5_0_02-linux-i586.rpm&nbsp;/usr/local<br>#cd&nbsp;/usr/local<br>给所有用户添加可执行的权限<br>#chmod&nbsp;+x&nbsp;jdk-1_5_0_02-linux-i586.rpm.bin<br>#./jdk-1_5_0_02-linux-i586.rpm.bin<br>此时会生成文件jdk-1_5_0_02-linux-i586.rpm，同样给所有用户添加可执行的权限<br>#chmod&nbsp;+x&nbsp;jdk-1_5_0_02-linux-i586.rpm<br>安装程序<br>#rpm&nbsp;-ivh&nbsp;jdk-1_5_0_02-linux-i586.rpm<br>出现安装协议等，按接受即可。<br><br>2.设置环境变量。<br>#vi&nbsp;/etc/profile<br>在最后面加入&nbsp;<br>#set&nbsp;java&nbsp;environment<br>JAVA_HOME=/usr/java/jdk-1_5_0_02<br>CLASSPATH=.:＄JAVA_HOME/lib.tools.jar<br>PATH=＄JAVA_HOME/bin:＄PATH<br>export&nbsp;JAVA_HOME&nbsp;CLASSPATH&nbsp;PATH<br>保存退出。<br><br>要使JDK在所有的用户中使用，可以这样：<br>vi&nbsp;/etc/profile.d/java.sh<br>在新的java.sh中输入以下内容：&nbsp;<br>#set&nbsp;java&nbsp;environment<br>JAVA_HOME=/usr/java/jdk-1_5_0_02<br>CLASSPATH=.:＄JAVA_HOME/lib/tools.jar<br>PATH=＄JAVA_HOME/bin:＄PATH<br>export&nbsp;JAVA_HOME&nbsp;CLASSPATH&nbsp;PATH<br>保存退出，然后给java.sh分配权限：chmod&nbsp;755&nbsp;/etc/profile.d/java.sh<br><br>3.在终端使用echo命令检查环境变量设置情况。<br>#echo&nbsp;＄JAVA_HOME<br>#echo&nbsp;＄CLASSPATH<br>#echo&nbsp;＄PATH<br><br>4.检查JDK是否安装成功。<br>#java&nbsp;-version<br>如果看到JVM版本及相关信息，即安装成功！</font> <img src ="http://www.blogjava.net/flyingis/aggbug/17191.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-10-28 15:59 <a href="http://www.blogjava.net/flyingis/archive/2005/10/28/17191.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java中存储数据的地方</title><link>http://www.blogjava.net/flyingis/archive/2005/10/28/17187.html</link><dc:creator>Flyingis</dc:creator><author>Flyingis</author><pubDate>Fri, 28 Oct 2005 07:48:00 GMT</pubDate><guid>http://www.blogjava.net/flyingis/archive/2005/10/28/17187.html</guid><wfw:comment>http://www.blogjava.net/flyingis/comments/17187.html</wfw:comment><comments>http://www.blogjava.net/flyingis/archive/2005/10/28/17187.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/flyingis/comments/commentRss/17187.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/flyingis/services/trackbacks/17187.html</trackback:ping><description><![CDATA[<FONT size=2><FONT face=宋体>&nbsp;&nbsp;&nbsp;作者：<A HREF="/flyingis/"><FONT color=#000080>Flyingis</FONT></A><BR><BR>&nbsp;&nbsp;&nbsp;在</FONT><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Java</SPAN></FONT><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">程序运行时有</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">6</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">个地方可以存储数据：<BR><BR></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">1.</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">寄存器：这是最快的存储区，因为它位于不同于其他存储区的地方</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">——</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">处理器内部。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><BR>2.</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">堆栈：位于通用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">RAM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">中，但通过</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">“</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">堆栈指针</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">”</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">可以从处理器那里获得直接支持。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><BR>3.</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">堆：一种通用的内存池</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">(</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">也位于</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">RAM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">区</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">，用于存放所有的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">对象。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><BR>4.</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">静态存储：这里的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">“</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">静态</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">”</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">指的是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">“</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">在固定的位置</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">”(</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">尽管也在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">RAM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">里</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">)</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">，存放程序运行时一直存在的数据。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><BR>5.</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">常量存储：常量值通常直接存放在程序代码内部，这样做是安全的，因为它们永远不会被改变。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><BR>6.</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">非</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">RAM</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">存储：如果数据完全存活于程序之外，那么它可以不受程序的任何控制，在程序中没有运行时也可以存在。</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">程序设计时经常用到一系列类型，比如</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">char/byte/int/long/float</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">等等，我们有两种方式创建方式，例如创建一个</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">String</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">类型的引用并初始化为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">“Java”</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">：</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;String&nbsp;s&nbsp;=&nbsp;"Java";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">或</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">&nbsp;String&nbsp;s&nbsp;=&nbsp;new&nbsp;String("Java")<STROKE joinstyle="miter"></STROKE><FORMULAS><F eqn="if lineDrawn pixelLineWidth 0"></F><F eqn="sum @0 1 0"></F><F eqn="sum 0 0 @1"></F><F eqn="prod @2 1 2"></F><F eqn="prod @3 21600 pixelWidth"></F><F eqn="prod @3 21600 pixelHeight"></F><F eqn="sum @0 0 1"></F><F eqn="prod @6 1 2"></F><F eqn="prod @7 21600 pixelWidth"></F><F eqn="sum @8 21600 0"></F><F eqn="prod @7 21600 pixelHeight"></F><F eqn="sum @10 21600 0"></F></FORMULAS><PATH o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></PATH><LOCK aspectratio="t" v:ext="edit"></LOCK></SHAPETYPE><SHAPE id=_x0000_i1025 style="WIDTH: 11.25pt; HEIGHT: 11.25pt; mso-wrap-distance-left: 1.5pt; mso-wrap-distance-top: 1.5pt; mso-wrap-distance-right: 1.5pt; mso-wrap-distance-bottom: 1.5pt" alt="" type="#_x0000_t75"><IMAGEDATA o:href="http://www.blogcn.com/images/wink.gif" src="file:///D:\Temp\msohtml1\01\clip_image001.gif"></IMAGEDATA></SHAPE>;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">采用第一种方式创建了一个并非是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">“</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">引用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">”</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">的变量，它的值为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">“Java”</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">，置于堆栈之中。而第二种方式创建了一个对象，它被存储在堆里，不及在堆栈中高效。因此，当我们需要创建一个很小的、简单的变量时，采用第一种方式更好。这是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Java</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">数据存储的一个细节。</SPAN><img src ="http://www.blogjava.net/flyingis/aggbug/17187.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/flyingis/" target="_blank">Flyingis</a> 2005-10-28 15:48 <a href="http://www.blogjava.net/flyingis/archive/2005/10/28/17187.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>