﻿<?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-我的隐式生活（My Implicit Life）-随笔分类-&lt;b&gt;-=Java API=-&lt;/b&gt;</title><link>http://www.blogjava.net/marco/category/7338.html</link><description>&lt;b&gt;继续搞“对象”，玩OO.&lt;/b&gt;
</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 12:07:43 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 12:07:43 GMT</pubDate><ttl>60</ttl><item><title>JAVA Container Class</title><link>http://www.blogjava.net/marco/archive/2006/09/20/70845.html</link><dc:creator>marco</dc:creator><author>marco</author><pubDate>Wed, 20 Sep 2006 08:53:00 GMT</pubDate><guid>http://www.blogjava.net/marco/archive/2006/09/20/70845.html</guid><wfw:comment>http://www.blogjava.net/marco/comments/70845.html</wfw:comment><comments>http://www.blogjava.net/marco/archive/2006/09/20/70845.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/marco/comments/commentRss/70845.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/marco/services/trackbacks/70845.html</trackback:ping><description><![CDATA[
		<p>Java Collection Framwork中的类的确是最重要的基础api，实现任何算法，基本上都很难离开它。</p>
		<p>因此理解这堆“集合（Collection）类”很有必要。声明一下，以前一直都是叫它们集合类，但是好像Think In Java的作者鄙视了这个说法，严格的说应该叫Container类，而后看了它整整一章书以后，觉得还是人家说的有道理。</p>
		<p>它说这个container类库，包含了两大类，Collection和Map，而Collection又可以分为List和Set。当然这些抽象概念都被定义成了接口。</p>
		<p>话说，这样的分类的确是严格按照类之间的继承关系来说得，但是俺总觉得很别扭，真动手的时候，还是很难选择。当然，Anytime and Anywhere使用ArrayList绝对都能解决问题，但这样做毕竟太农民了一点。</p>
		<p>所以，我自己有了一些想法。先回归到最基本最基本的数据结构的层面，管你是Collection还是Container，反正描述的都是一堆东西吧。数据结构第一章讲了一个结构：在物理上连续分配空间的顺序结构，叫顺序表（希望记性是好的），而离散分配空间的，应该叫做链表，最常用的就是单链表。这两个东西，其实就是很多复杂数据结构的基础，还记得吗，当时就是讲完这些东西，才开始讲栈、队列、二叉树、有向无向图的。所以，这个顺序结构是很基础的。而在JAVA中，顺序表对应的就是List接口，而一般顺序表就是ArrayList（有效进行随机index查找）；而单链表就是LinkedList（有效进行插入和删除），两个的优劣当年都讲烂了，这里就不说了。</p>
		<p>有了这两个结构以后，JAVA就不提供Stack和Queue单独的类了，因为，用户可以用上面两个类轻易的去实现。</p>
		<p>那Set和Map有怎么跟List连上关系呢？</p>
		<p>我认为可以把它们看成是无序和单一的List（Map只是两个有映射关系的List罢了）。</p>
		<p>Set和Map无序和单一的特性，决定了它们天大的需求就是根据关键字（元素对象）检索。so，为了效率，必须hash。</p>
		<p>有了HashSet和HashMap。</p>
		<p>同时，如果非要保持住元素的顺序，有了LinkedHashSet、LinkedHashMap。</p>
		<p>
				<br />结论：</p>
		<p>假如你的需求是<br />1：往Container中放的对象是无序且单一的；<br />2：经常要检索。<br />用HashSet或HashMap吧。</p>
		<p>ps：这两个条件其实是一回事，因为如果是不单一的话，你去检索它干嘛。</p>
		<p>如果进而需要保持元素的顺序，不要让他顺便iteration，那就选择LinkedHashSet和LinkedHashMap。</p>
		<p>假如你的需求不满足以上1&amp;2，那你放心，List肯定能帮你解决，你只要稍微想一下是ArrayList好还是LinkedList好。</p>
		<p>题外话：</p>
		<p>关于Hash，务必记得要让自己的元素对象override hashCode()和 equles() 方法，要不你直接可以洗了睡。</p>
		<p>关于所有这些Container，务必记得有个辅助类叫Interator，遍历尽量要用它。<br /><br />关于一些老的Stack、Vector、HashTable，听说以后不要用了哦。收到啦！！</p>
<img src ="http://www.blogjava.net/marco/aggbug/70845.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/marco/" target="_blank">marco</a> 2006-09-20 16:53 <a href="http://www.blogjava.net/marco/archive/2006/09/20/70845.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 字符串操作小节（Regular Expression）</title><link>http://www.blogjava.net/marco/archive/2006/08/31/66870.html</link><dc:creator>marco</dc:creator><author>marco</author><pubDate>Thu, 31 Aug 2006 07:13:00 GMT</pubDate><guid>http://www.blogjava.net/marco/archive/2006/08/31/66870.html</guid><wfw:comment>http://www.blogjava.net/marco/comments/66870.html</wfw:comment><comments>http://www.blogjava.net/marco/archive/2006/08/31/66870.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/marco/comments/commentRss/66870.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/marco/services/trackbacks/66870.html</trackback:ping><description><![CDATA[
		<p>任何信息，基本都是以文字的形式传播和记录下来的。</p>
		<p>在计算机中，文字就是字符的集合，也就是字符串，C就是因为对字符串设计的不好，才那么容易溢出。而别的一些高级语言，对于这个进行了很多的改进。</p>
		<p>编程的人由于技术方向和应用方向的不同，日常编程的内容差距很大。但是对于字符串的处理，那可是永远都避不开的工作。</p>
		<p>昨天跑步的时候，想了一下，对于字符串的操作有那么多（search，match，split，replace），感觉很烦杂，能不能抓住这些操作的一个基本集？</p>
		<p>不知道对不对，反正想出来了一个，这个基本操作就是search，这里的search的意思是：在输入串中找到目标串的开始位置（start index），和结束位置（end index）。</p>
		<p>有了这个基本集，别的操作都很好衍生出来：</p>
		<p>
				<strong>局部match：</strong>其实就是要求search操作至少返回一个start index。</p>
		<p>
				<strong>全match：</strong>其实要求search操作的至少返回一个start index，并且start index要为零，end index要为输入串的全长。</p>
		<p>
				<strong>split：</strong>其实就是search操作之后，把前一个end index和当前的start index之间的字符串截出来而已。</p>
		<p>
				<strong>replace：</strong>其实就是search操作之后，把start index和end index之间的字符串换成另外的而已。</p>
		<p>所以，归根到底，都是一个search操作的拓展罢了。这么一想，感觉清晰多了。</p>
		<p>这么一来，API对search的能力支持的好坏和效率高低是衡量字符串操作功能的标准，当然，如果有直接支持match，split，replace操作的话就更好了。</p>
		<p>java对字符串search的支持，最基本的就是下面的String的indexOf方法：</p>
		<p>
				<strong>int indexOf(String str) <br />          Returns the index within this string of the first occurrence of the specified substring.</strong>
		</p>
		<p>这里我想说的是，很多时候我们所谓要search的目标串，根本就不是固定单一的，而是变化多样的。如果只有一两种情况，最多用两次上面的方法呗。但是有些情况是近乎不可能罗列的，例如，我们讲的代表email的字符串，我们不可能遍历它吧。</p>
		<p>所以，需要一种能够通用表达字符串格式的语言。这就是Regular Expression（re）。</p>
		<p>假如上面方法indexOf的str参数能支持re做为参数的话，那对于这种多样的search也可以用上面的方法了。</p>
		<p>可惜，indexOf不支持re作为参数。<br /><br />so，以下就介绍java api中可以用re作为参数的字符串操作方法（参数中的regex就是re）。</p>
		<p>－－－－－－－－－－－－－－－－－－－－－&gt;&gt;<br />String类的：</p>
		<p>全match操作：<br /><strong><font face="Courier New"><font color="#0000ff">boolean matches(String regex)</font><br />          Tells whether or not this string matches the given regular expression.</font></strong></p>
		<p>全replace操作：<br /><strong><font face="Courier New"><font color="#0000ff">String replaceAll(String regex, String replacement)</font><br />          Replaces each substring of this string that matches the given regular expression with the given replacement.</font></strong></p>
		<p>
				<font color="#000000">首个replace操作：<br /></font>
				<strong>
						<font face="Courier New">
								<font color="#0000ff">String replaceFirst(String regex, String replacement) <br /></font>          Replaces the first substring of this string that matches the given regular expression with the given replacement.</font>
				</strong>
		</p>
		<p>全split操作：<br /><strong><font face="Courier New"><font color="#0000ff">String[] split(String regex)</font><br />          Splits this string around matches of the given regular expression.</font></strong><br /><br />有限制数的split操作：<br /><strong><font face="Courier New"><font color="#0000ff">String[] split(String regex, int limit)</font><br />          Splits this string around matches of the given regular expression.</font></strong></p>
		<p>&lt;&lt;－－－－－－－－－－－－－－－－－－－－－</p>
		<p>可惜啊，可惜，可惜java的String类里面没有可以支持re的search方法，那如果要用re来search，只好使用java中专门的re类库。</p>
		<p>java中的re类库主要就两个类，一个叫Pattern，顾名思义，代表re的类。一个叫Matcher类，反映当前match状况的类（如存放了当前search到的位置，匹配的字符串等等信息）。</p>
		<p>一般在构造中，“re的表达式”作为参数传递入Pattern类，“输入串（待过滤串）”作为参数传递入Matcher类。</p>
		<p>然后使用Matcher类的字符串search方法就可以了。Matcher真正提供search功能的API叫find。下面列出。<br />－－－－－－－－－－－－－－－－－－－－－&gt;&gt;<br />Matcher类search操作相关的方法：</p>
		<p>
				<strong>
						<font face="Courier New">
								<font color="#0000ff">boolean lookingAt()</font>
								<br />          Attempts to match the input sequence, starting at the beginning, against the pattern. </font>
				</strong>
		</p>
		<p>
				<strong>
						<font face="Courier New">
								<font color="#0000ff">boolean matches()</font>
								<br />          Attempts to match the entire input sequence against the pattern. </font>
				</strong>
		</p>
		<p>
				<strong>
						<font face="Courier New">
								<font color="#0000ff">boolean find()</font>
								<br />          Attempts to find the next subsequence of the input sequence that matches the pattern. </font>
				</strong>
		</p>
		<p>
				<strong>
						<font face="Courier New">
								<font color="#0000ff">String group() <br /></font>          Returns the input subsequence matched by the previous match.</font>
				</strong>
		</p>
		<p>&lt;&lt;－－－－－－－－－－－－－－－－－－－－－</p>
		<p>前三个都是search方法，返回成功与否。第四个是返回当前search上的字符串。<br /><br />ok，至此。使用re的search操作也有眉目了。</p>
		<p>当然，Pattern和Matcher也包含直接使用re进行的match，split，replace操作。</p>
		<p>－－－－－－－－－－－－－－－－－－－－－&gt;&gt;<br />Patter类别的字符串操作方法</p>
		<p>全match操作：<br /><strong><font face="Courier New"><font color="#0000ff">static boolean matches(String regex, CharSequence input)</font><br />          Compiles the given regular expression and attempts to match the given input against it.</font></strong></p>
		<p>全split操作：<br /><font face="Courier New"><strong><font color="#0000ff">String[] split(CharSequence input)</font><br />          Splits the given input sequence around matches of this pattern.</strong></font></p>
		<p>有限制数的split操作：<br /><font face="Courier New"><strong><font color="#0000ff">String[] split(CharSequence input, int limit)</font><br />          Splits the given input sequence around matches of this pattern.</strong></font></p>
		<p>
				<br />Matcher类别的字符串操作方法</p>
		<p>全replace操作：<br /><strong><font face="Courier New"><font color="#0000ff">String replaceAll(String replacement) <br /></font>          Replaces every subsequence of the input sequence that matches the pattern with the given replacement string.</font></strong></p>
		<p>首个replace操作：<br /><strong><font face="Courier New"><font color="#0000ff">String replaceFirst(String replacement) <br /></font>          Replaces the first subsequence of the input sequence that matches the pattern with the given replacement string.</font></strong></p>
		<p>动态replace（replacement可以根据被替代的字符串变化而变化）<br /><font face="Courier New" color="#000000"><strong><font color="#0000ff">Matcher appendReplacement(StringBuffer sb, String replacement)</font><br />          Implements a non-terminal append-and-replace step. </strong></font></p>
		<p>
				<font face="Courier New" color="#000000">
						<strong>
								<font color="#0000ff">StringBuffer appendTail(StringBuffer sb)</font>
								<br />          Implements a terminal append-and-replace step.</strong>
				</font>
		</p>
		<p>&lt;&lt;－－－－－－－－－－－－－－－－－－－－－<br /><br />总结：<br />当必须使用re的时候，search操作就要用到Pattern，Matcher，当然动态的replace操作也要用到这两个类。而别的match，replace，split操作，可以使用pattern，Matcher，当然也可以直接使用String，推荐还是用回咱们的String吧。<br /><br />注：以上都是看jdk1.4以上的文档得出的结论，以前版本不能用不负责任。</p>
<img src ="http://www.blogjava.net/marco/aggbug/66870.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/marco/" target="_blank">marco</a> 2006-08-31 15:13 <a href="http://www.blogjava.net/marco/archive/2006/08/31/66870.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA CODING 基本功 Ⅰ（1）――读 JAVA EFFECTIVE 笔记</title><link>http://www.blogjava.net/marco/archive/2006/07/15/58305.html</link><dc:creator>marco</dc:creator><author>marco</author><pubDate>Sat, 15 Jul 2006 04:35:00 GMT</pubDate><guid>http://www.blogjava.net/marco/archive/2006/07/15/58305.html</guid><wfw:comment>http://www.blogjava.net/marco/comments/58305.html</wfw:comment><comments>http://www.blogjava.net/marco/archive/2006/07/15/58305.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/marco/comments/commentRss/58305.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/marco/services/trackbacks/58305.html</trackback:ping><description><![CDATA[
		<h2>
				<span style="COLOR: blue; FONT-FAMILY: 黑体">创建和销毁对象</span>
				<span lang="EN-US" style="COLOR: blue">
						<?xml:namespace prefix = o /?>
						<o:p>
						</o:p>
				</span>
		</h2>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">重点关注对象的创建和销毁：什么时候、如何创建对象，什么时候、什么条件下应该避免创建对象，如何保证对象在合适的方式下被销毁，如何在销毁对象之前操作一些必须的清理行为。</span>
		</p>
		<h3>
				<span style="FONT-SIZE: 12pt; COLOR: rgb(153,51,102); LINE-HEIGHT: 173%; FONT-FAMILY: 宋体">尝试用静态工厂方法代替构造器</span>
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: rgb(153,51,102); LINE-HEIGHT: 173%">
						<o:p>
						</o:p>
				</span>
		</h3>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">如果一个</span>
				<span lang="EN-US">client</span>
				<span style="FONT-FAMILY: 宋体">要实例化一个对象来使用，傻</span>
				<span lang="EN-US">b</span>
				<span style="FONT-FAMILY: 宋体">都知道应该先调用类的构造器来</span>
				<span lang="EN-US">new</span>
				<span style="FONT-FAMILY: 宋体">一个对象，之后再调用相应的方法。除了这个方式，</span>
				<span lang="EN-US">Java Effective</span>
				<span style="FONT-FAMILY: 宋体">还建议了另一种方法：<b><u>用静态工厂方法来提供一个类的实例</u></b>。以下的例子不反映两者的优劣，只是反映两者在代码实现上的不同，优劣之后再谈：</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">假设咱们要一个颜色为黑色、长度为</span>
				<?xml:namespace prefix = st1 /?>
				<st1:chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="50" unitname="cm">
						<span lang="EN-US">50cm</span>
				</st1:chmetcnv>
				<span style="FONT-FAMILY: 宋体">的锤子，自然就用构造器创建一个</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">Hammer myHammer =<span>  </span>new Hammer(Color.BLACK, 50);</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">而用静态工厂方法来实例化一个对象，如下</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">Hammer myHammer = Hammer.factory(Color.BLACK,50);</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">也可以用专门的一个工厂类来实例化</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">Hammer myHammer = Toolkit.factory(“Hammer”, Color.BLACK,50);</span> <span lang="EN-US"><o:p> </o:p></span></p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">单纯从上面的代码上看，真的只有傻</span>
				<span lang="EN-US">b</span>
				<span style="FONT-FAMILY: 宋体">才会选择静态工厂的方法，完全就是多此一举，直接</span>
				<span lang="EN-US">new</span>
				<span style="FONT-FAMILY: 宋体">又快又爽，搞这么麻烦做莫斯（武汉话“什么”的意思）？</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">别急，别急，你急个莫</span>
				<span lang="EN-US">b</span>
				<span style="FONT-FAMILY: 宋体">（武汉粗话：基本就是“你急个毛”的意思）？</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">下面就说说用静态工厂代替构造器的好处（</span>
				<span lang="EN-US">advantage</span>
				<span style="FONT-FAMILY: 宋体">）和不好处（</span>
				<span lang="EN-US">disadvantage</span>
				<span style="FONT-FAMILY: 宋体">）。</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<b>
						<span style="FONT-FAMILY: 宋体">第一个好处，讲你都不信，行家们认为，构造器有一个不好的地方就是：这个方法的签名（</span>
						<span lang="EN-US">signture</span>
				</b>
				<b>
						<span style="FONT-FAMILY: 宋体">）太固定了。</span>
						<span lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</b>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">构造器的名字是固定的，生个</span>
				<span lang="EN-US">Hammer</span>
				<span style="FONT-FAMILY: 宋体">，构造器的名字就是</span>
				<span lang="EN-US">Hammer</span>
				<span style="FONT-FAMILY: 宋体">（……），唯一能变化的地方就是参数，假设我的这个锤子有两个很变态的构造需要：</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">1</span>
				<span style="FONT-FAMILY: 宋体">：第一个参数是颜色（</span>
				<span lang="EN-US">Color</span>
				<span style="FONT-FAMILY: 宋体">型），第二个参数是锤子头的重量（</span>
				<span lang="EN-US">int</span>
				<span style="FONT-FAMILY: 宋体">型）。</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">Hammer</span>
				<span style="FONT-FAMILY: 宋体">（</span>
				<span lang="EN-US">Color c, int kg</span>
				<span style="FONT-FAMILY: 宋体">）</span>
				<span lang="EN-US">{</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">//remainder omited</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">}</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">2</span>
				<span style="FONT-FAMILY: 宋体">：第一个参数是颜色（</span>
				<span lang="EN-US">Color</span>
				<span style="FONT-FAMILY: 宋体">型），第二个参数是锤子的长度（</span>
				<span lang="EN-US">int</span>
				<span style="FONT-FAMILY: 宋体">型）。</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">Hammer</span>
				<span style="FONT-FAMILY: 宋体">（</span>
				<span lang="EN-US">Color c, int cm</span>
				<span style="FONT-FAMILY: 宋体">）</span>
				<span lang="EN-US">{</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">//remainder omited</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">}</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">感觉满足需要了，但是细心一看，完了，构造器的参数列表类型重复了，肯定编译通不过，这是面向对象构造器天生的缺陷——唯一的变化就是参数，参数都分辨不了，就真的分辨不了。</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">而另外就算参数能分辨的了，构造器一多，它的参数一多，您根本就不知道每个参数是用来干什么的，只能去查阅文档，在您已经眼花缭乱的时候再去查文档，一个一个的对，折磨人的活。</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">这个时候，您就可以考虑用静态工厂方法来实例化对象了。因为静态工厂方法有一个最简单的特点就是：他有可以变化的方法名（构造器的名字变不了）。用名字的不同来代表不同的构造需要，这么简单的普通的特点在这里就是它相对于构造器的</span>
				<span lang="EN-US">advantage</span>
				<span style="FONT-FAMILY: 宋体">。</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">如上面的锤子的例子可以这样：</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">1</span>
				<span style="FONT-FAMILY: 宋体">：</span>
				<span lang="EN-US">Hammer.produceByWeight (Color c, int kg){</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">//remainder omited</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">}</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">2</span>
				<span style="FONT-FAMILY: 宋体">：</span>
				<span lang="EN-US">Hammer.produceByHeight (Color c, int cm){</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">//remainder omited</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">}</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">这是不是一目了然多了。嗯，我是这样认为的。</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<b>
						<span style="FONT-FAMILY: 宋体">第二个好处，“静态工厂方法不需要每次都真的去实例化一个对象”——其实这也是另一些优化方法的前提。</span>
						<span lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</b>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">构造器的每次</span>
				<span lang="EN-US">invoke</span>
				<span style="FONT-FAMILY: 宋体">必定会产生一个新的对象，而静态工厂方法经过一定的控制，完全可以不用每次</span>
				<span lang="EN-US">invoke</span>
				<span style="FONT-FAMILY: 宋体">都生成一个新的对象。</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">为什么不每次都生成一个对象的原因就不必说了，因为原因太明显。这个原因就是为什么要“共享”对象的原因。</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">下面讲讲通常使用的两种共享具体策略，也就是具体方法了：</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">1</span>
				<span style="FONT-FAMILY: 宋体">：单例模式的需要，一旦需要某个对象有单例的需要，必定对于这类对象的构造只能用静态工厂方法了。</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US">2</span>
				<span style="FONT-FAMILY: 宋体">：</span>
				<span lang="EN-US">flyweight</span>
				<span style="FONT-FAMILY: 宋体">模式和不变（</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">immutable</span>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">）</span>
				<span style="FONT-FAMILY: 宋体">模式的需要，这两个模式很多时候都说一起使用的，一旦一些对象我们认为是不变的，那自然就想拿来重用，也就说共享，而</span>
				<span lang="EN-US">flyweight</span>
				<span style="FONT-FAMILY: 宋体">就是用来重用这些小粒度对象的。</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span style="FONT-FAMILY: 宋体">如</span>
				<span lang="EN-US">Boolean.valueOf (boolean)</span>
				<span style="FONT-FAMILY: 宋体">方法：</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US">Boolean a = Boolean.valueOf (100);</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US">Boolean b = Boolean.valueOf (100);</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN-LEFT: 18pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left" align="left"> <span lang="EN-US"><span>a，<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">  </span></span></span><span lang="EN-US">b</span><span style="FONT-FAMILY: 宋体">两个引用都是指向同一个对象。</span></p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span style="FONT-FAMILY: 宋体">这些对象都是不变的，而</span>
				<span lang="EN-US">valueOf</span>
				<span style="FONT-FAMILY: 宋体">的控制就是用的</span>
				<span lang="EN-US">flyweight</span>
				<span style="FONT-FAMILY: 宋体">方法。</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span style="FONT-FAMILY: 宋体">这种一个状态（如上面一个数字）对应的对象只有一个还有一个好处，就是可以直接通过比较“引用”来判断他们是否</span>
				<span lang="EN-US">equel</span>
				<span style="FONT-FAMILY: 宋体">（这里的</span>
				<span lang="EN-US">equel</span>
				<span style="FONT-FAMILY: 宋体">是逻辑相等的意思），以前需要</span>
				<span lang="EN-US">a.equels(b)</span>
				<span style="FONT-FAMILY: 宋体">，而一旦用“</span>
				<span lang="EN-US">flyweight</span>
				<span style="FONT-FAMILY: 宋体">模式和不变（</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">immutable</span>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">）</span>
				<span style="FONT-FAMILY: 宋体">模式”后，避免了产生多余的相同对象，用</span>
				<span lang="EN-US">a==b</span>
				<span style="FONT-FAMILY: 宋体">就可以达到</span>
				<span lang="EN-US">a.equels(b)</span>
				<span style="FONT-FAMILY: 宋体">的目的了。这样当然优化了</span>
				<span lang="EN-US">performance</span>
				<span style="FONT-FAMILY: 宋体">。</span> <span lang="EN-US"><o:p> </o:p></span></p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<b>
						<span style="FONT-FAMILY: 宋体">第三个好处，其实就是工厂方法的核心好处——我把它称为“抽象类型构造器”。它可以为我们提供一个抽象类型的实例，同时必要的隐藏了抽象类型的具体结构。这是</span>
						<span lang="EN-US">new</span>
				</b>
				<b>
						<span style="FONT-FAMILY: 宋体">怎么都达不到的。</span>
						<span lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</b>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span style="FONT-FAMILY: 宋体">这种模式的好处其实就是面向对象的最核心的好处，抽象和具体可以分离，一旦抽象定义好了，具体的东西可以慢慢的变化，慢慢的拓展——开闭原则。</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span style="FONT-FAMILY: 宋体">如</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">Collections Framework API</span>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">，都是描述集合类型的接口，也就是对于客户端来看，只有</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">Collection</span>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">这个类要认识，而实际上，实现这个接口的</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">Collection</span>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">是多种多样的。如果要让用户都知道这些具体实现的</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">Collection</span>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">，就增加了复杂度。</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">这时，通过一个静态工厂方法，就可以隐藏各种</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">Collection</span>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">的具体实现，而让</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">Client</span>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">只使用返回的</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">Collection</span>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">对象就可以了。</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">这里还可以加上一些权限控制，如这些实现只要对于工厂来讲是可以访问的，不用是</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">public</span>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">的，而他们只要通过</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">public</span>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">的工厂就可以提供给用户。非常有利于代码的安全。</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<b>
						<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">静态工厂方法的第一个缺点就是：使用静态工厂方法创建的类的构造器经常都是非公共或非</span>
				</b>
				<b>
						<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">protected</span>
				</b>
				<b>
						<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">的。</span>
				</b>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">这样，以后这些类就没有办法被继承了。不过也有人说，不用继承就用</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">composition</span>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">呗。也是！呵呵。</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<b>
						<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">静态工厂方法的第二个缺点是：在</span>
				</b>
				<b>
						<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">jdk</span>
				</b>
				<b>
						<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">文档里，这些静态工厂方法很难跟别的静态方法相区别。</span>
				</b>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">而文档中，构造器是很容易看到的。</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">为了一定程度解决这个问题，我们可以用一些比较特别的名字来给这类静态工厂方法来命名。最常用的有：</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">valueOf </span>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">——</span>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">
				</span>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">用来放回跟参数“相同值”的对象。</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">getInstance </span>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">——</span>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">
				</span>
				<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">返回一个对象的实例。单例模式中，就是返回单例对象。</span>
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
				<b>
						<span style="FONT-SIZE: 11.5pt; FONT-FAMILY: 宋体">总结：静态工厂方法和构造器都有各自的特点。最好在考虑用构造器之前能先考虑一下静态工厂方法，往往，后者更有用一点。如果权衡了以后也看不出那个好用一些，那就用构造器，毕竟简单本分多了。</span>
				</b>
				<b>
						<span lang="EN-US" style="FONT-SIZE: 11.5pt; FONT-FAMILY: TimesNewRoman">
								<o:p>
								</o:p>
						</span>
				</b>
		</p>
<img src ="http://www.blogjava.net/marco/aggbug/58305.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/marco/" target="_blank">marco</a> 2006-07-15 12:35 <a href="http://www.blogjava.net/marco/archive/2006/07/15/58305.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>