﻿<?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-thinking-随笔分类-J2EE</title><link>http://www.blogjava.net/alinglau36/category/38704.html</link><description>one platform thousands thinking</description><language>zh-cn</language><lastBuildDate>Sat, 26 Jan 2013 19:32:07 GMT</lastBuildDate><pubDate>Sat, 26 Jan 2013 19:32:07 GMT</pubDate><ttl>60</ttl><item><title>http://java.dzone.com/articles/immutability-with-builder-design-pattern</title><link>http://www.blogjava.net/alinglau36/archive/2013/01/25/394783.html</link><dc:creator>lau</dc:creator><author>lau</author><pubDate>Fri, 25 Jan 2013 10:16:00 GMT</pubDate><guid>http://www.blogjava.net/alinglau36/archive/2013/01/25/394783.html</guid><wfw:comment>http://www.blogjava.net/alinglau36/comments/394783.html</wfw:comment><comments>http://www.blogjava.net/alinglau36/archive/2013/01/25/394783.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alinglau36/comments/commentRss/394783.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alinglau36/services/trackbacks/394783.html</trackback:ping><description><![CDATA[<div>http://java.dzone.com/articles/immutability-with-builder-design-pattern</div><img src ="http://www.blogjava.net/alinglau36/aggbug/394783.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alinglau36/" target="_blank">lau</a> 2013-01-25 18:16 <a href="http://www.blogjava.net/alinglau36/archive/2013/01/25/394783.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate中get和load方法的区别</title><link>http://www.blogjava.net/alinglau36/archive/2009/06/10/281088.html</link><dc:creator>lau</dc:creator><author>lau</author><pubDate>Wed, 10 Jun 2009 03:10:00 GMT</pubDate><guid>http://www.blogjava.net/alinglau36/archive/2009/06/10/281088.html</guid><wfw:comment>http://www.blogjava.net/alinglau36/comments/281088.html</wfw:comment><comments>http://www.blogjava.net/alinglau36/archive/2009/06/10/281088.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alinglau36/comments/commentRss/281088.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alinglau36/services/trackbacks/281088.html</trackback:ping><description><![CDATA[<p style="margin: 0cm 0cm 0pt; text-indent: 21pt;"><font size="3"><span style="font-family: 宋体;">这次我们来谈一下</span><font face="Times New Roman"><strong><span style="color: #99cc00;">Hibernate3.2</span></strong> Session</font><span style="font-family: 宋体;">加载数据时</span><font face="Times New Roman">get</font><span style="font-family: 宋体;">和</span><font face="Times New Roman">load</font><span style="font-family: 宋体;">方法的区别，其实这个在网上有很多的论述，可大多语焉不详或经不起实践的推敲，让很多初学者学的满腹疑窦，现在我给大家讲解一下：</span></font></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 17.95pt;"><font size="3"><font face="Times New Roman">1. </font><span style="font-family: 宋体;">对于</span><font face="Times New Roman">get</font><span style="font-family: 宋体;">方法，</span><font face="Times New Roman">hibernate</font><span style="font-family: 宋体;">会确认一下该</span><font face="Times New Roman">id</font><span style="font-family: 宋体;">对应的数据是否存在，首先在</span><font face="Times New Roman">session</font><span style="font-family: 宋体;">缓存中查找，然后在二级缓存中查找，还没有就查询数据库，数据库中没有就返回</span><font face="Times New Roman">null</font><span style="font-family: 宋体;">。这个相对比较简单，也没有太大的争议。主要要说明的一点就是在这个版本中</span><font face="Times New Roman">get</font><span style="font-family: 宋体;">方法也会查找二级缓存！</span></font></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 18pt;"><font size="3"><font face="Times New Roman">2.&nbsp;load</font><span style="font-family: 宋体;">方法加载实体对象的时候，根据映射文件上类级别的</span><font face="Times New Roman">lazy</font><span style="font-family: 宋体;">属性的配置</span><font face="Times New Roman">(</font><span style="font-family: 宋体;">默认为</span><font face="Times New Roman">true)</font><span style="font-family: 宋体;">，分情况讨论：</span></font></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 18pt;"><font size="3"><font face="Times New Roman">(1)</font><span style="font-family: 宋体;">若为</span><font face="Times New Roman">true,</font><span style="font-family: 宋体;">则首先在</span><font face="Times New Roman">Session</font><span style="font-family: 宋体;">缓存中查找，看看该</span><font face="Times New Roman">id</font><span style="font-family: 宋体;">对应的对象是否存在，不存在则使用延迟加载，返回实体的代理类对象</span><font face="Times New Roman">(</font><span style="font-family: 宋体;">该代理类为实体类的子类，由</span><font face="Times New Roman">CGLIB</font><span style="font-family: 宋体;">动态生成</span><font face="Times New Roman">)</font><span style="font-family: 宋体;">。等到具体使用该对象</span><font face="Times New Roman">(</font><span style="font-family: 宋体;">除获取</span><font face="Times New Roman">OID</font><span style="font-family: 宋体;">以外</span><font face="Times New Roman">)</font><span style="font-family: 宋体;">的时候，再查询二级缓存和数据库，若仍没发现符合条件的记录，则会抛出一个</span><font face="Times New Roman">ObjectNotFoundException</font><span style="font-family: 宋体;">。</span></font></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 18pt;"><font size="3"><font face="Times New Roman">(2)</font><span style="font-family: 宋体;">若为</span><font face="Times New Roman">false,</font><span style="font-family: 宋体;">就跟</span><font face="Times New Roman">get</font><span style="font-family: 宋体;">方法查找顺序一样，只是最终若没发现符合条件的记录，则会抛出一个</span><font face="Times New Roman">ObjectNotFoundException</font><span style="font-family: 宋体;">。</span></font></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 18pt;"><font size="3"><span style="font-family: 宋体;">这里</span><font face="Times New Roman">get</font><span style="font-family: 宋体;">和</span><font face="Times New Roman">load</font><span style="font-family: 宋体;">有两个重要区别</span><font face="Times New Roman">:</font></font></p>
<ol style="margin-top: 0cm;" type="1">
    <li style="margin: 0cm 0cm 0pt;"><font size="3"><span style="font-family: 宋体;">如果未能发现符合条件的记录，</span><font face="Times New Roman">get</font><span style="font-family: 宋体;">方法返回</span><font face="Times New Roman">null</font><span style="font-family: 宋体;">，而</span><font face="Times New Roman">load</font><span style="font-family: 宋体;">方法会抛出一个</span><font face="Times New Roman">ObjectNotFoundException</font><span style="font-family: 宋体;">。</span></font></li>
    <li style="margin: 0cm 0cm 0pt;"><font size="3"><font face="Times New Roman">load</font><span style="font-family: 宋体;">方法可返回没有加载实体数据的代理类实例，而</span><font face="Times New Roman">get</font><span style="font-family: 宋体;">方法永远返回有实体数据的对象。</span><font face="Times New Roman">(</font><span style="font-family: 宋体;">对于</span><font face="Times New Roman">load</font><span style="font-family: 宋体;">和</span><font face="Times New Roman">get</font><span style="font-family: 宋体;">方法返回类型：好多书中都说：</span><font face="Times New Roman">&#8220;get</font><span style="font-family: 宋体;">方法永远只返回实体类</span><font face="Times New Roman">&#8221;</font><span style="font-family: 宋体;">，实际上并不正确，</span><font face="Times New Roman">get</font><span style="font-family: 宋体;">方法如果在</span><font face="Times New Roman">session</font><span style="font-family: 宋体;">缓存中找到了该</span><font face="Times New Roman">id</font><span style="font-family: 宋体;">对应的对象，如果刚好该对象前面是被代理过的，如被</span><font face="Times New Roman">load</font><span style="font-family: 宋体;">方法使用过，或者被其他关联对象延迟加载过，那么返回的还是原先的代理对象，而不是实体类对象，如果该代理对象还没有加载实体数据（就是</span><font face="Times New Roman">id</font><span style="font-family: 宋体;">以外的其他属性数据），那么它会查询二级缓存或者数据库来加载数据，但是返回的还是代理对象，只不过已经加载了实体数据。</span><font face="Times New Roman">)</font></font></li>
</ol>
<p style="margin: 0cm 0cm 0pt; text-indent: 18pt;"><font size="3"><strong><span style="color: #99cc00; font-family: 宋体;">总之对于</span><span style="color: #99cc00;"><font face="Times New Roman">get</font></span></strong><strong><span style="color: #99cc00; font-family: 宋体;">和</span><span style="color: #99cc00;"><font face="Times New Roman">load</font></span></strong><strong><span style="color: #99cc00; font-family: 宋体;">的根本区别，一句话，</span><span style="color: #99cc00;"><font face="Times New Roman">hibernate</font></span></strong><strong><span style="color: #99cc00; font-family: 宋体;">对于</span><span style="color: #99cc00;"><font face="Times New Roman">load</font></span></strong><strong><span style="color: #99cc00; font-family: 宋体;">方法认为该数据在数据库中一定存在，可以放心的使用代理来延迟加载，如果在使用过程中发现了问题，只能抛异常；而对于</span><span style="color: #99cc00;"><font face="Times New Roman">get</font></span></strong><strong><span style="color: #99cc00; font-family: 宋体;">方法，</span><span style="color: #99cc00;"><font face="Times New Roman">hibernate</font></span></strong><strong><span style="color: #99cc00; font-family: 宋体;">一定要获取到真实的数据，否则返回</span><span style="color: #99cc00;"><font face="Times New Roman">null</font></span></strong><strong><span style="color: #99cc00; font-family: 宋体;">。</span></strong></font></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt;"><font size="3"><span style="font-family: 宋体;">最后，我们分析下为什么网路上那么多关于二者区别的文章不太准确！首先可能是版本问题，</span><font face="Times New Roman">Hibernate</font><span style="font-family: 宋体;">版
本不同，运行机制不太一样；其次就是很多朋友只是把自己经验所得与人分享，并没有经过全方位代码的检测；最后就是有些技术牛人，表达比较随意。所以我希望
大家以后学习知识的时候不要盲从他人迷信权威，一定要综合多方资料，比较和整理，再经过自己实践检验，这样得到的知识才是真实有效的。</span></font></p>
<img src ="http://www.blogjava.net/alinglau36/aggbug/281088.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alinglau36/" target="_blank">lau</a> 2009-06-10 11:10 <a href="http://www.blogjava.net/alinglau36/archive/2009/06/10/281088.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDK自带的native2ascii工具完全揭密</title><link>http://www.blogjava.net/alinglau36/archive/2009/06/04/280000.html</link><dc:creator>lau</dc:creator><author>lau</author><pubDate>Thu, 04 Jun 2009 05:52:00 GMT</pubDate><guid>http://www.blogjava.net/alinglau36/archive/2009/06/04/280000.html</guid><wfw:comment>http://www.blogjava.net/alinglau36/comments/280000.html</wfw:comment><comments>http://www.blogjava.net/alinglau36/archive/2009/06/04/280000.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alinglau36/comments/commentRss/280000.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alinglau36/services/trackbacks/280000.html</trackback:ping><description><![CDATA[<div>
<div><font size="2"><strong><font size="3" color="#0000ff">背景</font></strong>：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
在做Java开发的时候，常常会出现一些乱码，或者无法正确识别或读取的文件，比如常见的validator验证用的消息资源（properties）文
件就需要进行Unicode重新编码。原因是java默认的编码方式为Unicode，而我们的计算机系统编码常常是GBK等编码。需要将系统的编码转换
为java正确识别的编码问题就解决了。</font></div>
<div><font size="2"><font color="#0000ff"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
1、native2ascii简介</strong></font>：<br />
&nbsp;&nbsp;&nbsp; native2ascii是sun java
sdk提供的一个工具。用来将别的文本类文件（比如*.txt,*.ini,*.properties,*.java等等）编码转为Unicode编码。
为什么要进行转码，原因在于程序的国际化。Unicode编码的定义：Unicode（统一码、万国码、单一码）是一种在计算机上使用的字符编码。它为每
种语言中的每个字符设定了统一并且唯一的二进制编码，以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发，1994年正式公布。随着计算
机工作能力的增强，Unicode也在面世以来的十多年里得到普及。</font></div>
</div>
<div><font size="2"><font color="#0000ff"><strong>2、获取native2ascii</strong></font>：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                        安装了jdk后，假如你是在windows上安装，那么在jdk的安装目录下，会有一个bin目录，其中native2ascii.exe正是。<br />
<br />
</font></div>
<div><br />
</div>
<div><font size="2"><font color="#0000ff"><strong>3、native2ascii的命令行的命名格式</strong></font>：<br />
<font color="#ff00ff">native2ascii -[options] [inputfile
[outputfile]]<br />
</font></font></div>
<div><font size="2"><font color="#228b22"><br />
说明：</font> </font></div>
<div><font size="2" color="#0000ff"><font color="#ff00ff">-[options]：表示命令开关，有两个选项可供选择</font><br />
<font color="#008000">-reverse：将Unicode编码转为本地或者指定编码，不指定编码情况下，将转为本地编码。<br />
-encoding
encoding_name：转换为指定编码，encoding_name为编码名称。</font></font></div>
<div>&nbsp;</div>
<div><font size="2" color="#0000ff"><font color="#ff00ff">[inputfile
[outputfile]]</font><br />
<font color="#008000">inputfile：表示输入文件全名。<br />
outputfile：输出文件名。如果缺少此参数，将输出到控制台。</font></font><br />
<br />
<br />
</div>
<div><br />
</div>
<div><font size="2"><font color="#0000ff"><strong>4、最佳实践</strong></font>：<br />
&nbsp;&nbsp;&nbsp;&nbsp;
首先将JDK的bin目录加入系统变量path。在盘下建立一个test目录，在test目录里建立一个zh.txt文件，文件内容为：&#8220;熔岩&#8221;，打开&#8220;
命令行提示符&#8221;，并进入C:"test目录下。下面就可以按照说明一步一步来操作，注意观察其中编码的变化。<br />
</font></div>
<div><font size="2"><font color="#ff1493"><br />
A：将zh.txt转换为Unicode编码，输出文件到u.txt<br />
</font><font color="#ff00ff"><font color="#008000">native2ascii zh.txt
u.txt</font><br />
</font>打开u.txt，内容为&#8220;"u7194"u5ca9&#8221;。</font></div>
<div><br />
</div>
<div><font size="2" color="#ff1493"><br />
B：将zh.txt转换为Unicode编码，输出到控制台</font></div>
<div><font size="2">C:"test&gt;<font color="#228b22">native2ascii
zh.txt<br />
</font>"u7194"u5ca9<br />
可以看到，控制台输出了&#8220;"u7194"u5ca9&#8221;。</font></div>
<div><br />
</div>
<div><font size="2" color="#ff1493">C：将zh.txt转换为ISO8859-1编码，输出文件到i.txt</font><font size="2"><br />
<font color="#228b22">native2ascii -encoding ISO8859-1 zh.txt
i.txt<br />
</font>打开i.txt文件，内容为&#8220;"u00c8"u00db"u00d1"u00d2&#8221;。</font></div>
<div><font size="2"><font color="#ff1493"><br />
D：将u.txt转换为本地编码，输出到文件u_nv.txt<br />
</font><font color="#228b22">native2ascii -reverse u.txt
u_nv.txt<br />
</font>打开u_nv.txt文件，内容为&#8220;熔岩&#8221;。</font></div>
<div><br />
</div>
<div><font size="2"><font color="#ff1493"><br />
E：将u.txt转换为本地编码，输出到控制台</font><br />
C:"test&gt;<font color="#228b22">native2ascii -reverse
u.txt<br />
</font>熔岩<br />
可以看到，控制台输出了&#8220;熔岩&#8221;。</font></div>
<div><br />
</div>
<div><font size="2"><font color="#ff1493"><br />
F：将i.txt转换为本地编码，输出到i_nv.txt<br />
</font><font color="#228b22">native2ascii -reverse i.txt
i_nv.txt<br />
</font>打开i_nv.txt文件，内容为&#8220;"u00c8"u00db"u00d1"u00d2&#8221;。发现转码前后完全一样的。也就是说，等于没有转，或者说思想糊涂，对命名没有理解。<br />
<br />
</font></div>
<div><font size="2"><font color="#ff1493"><br />
G：将i.txt转换为GBK编码，输出到i_gbk.txt<br />
</font><font color="#32cd32"><font color="#228b22">native2ascii -reverse -encoding GBK
i.txt
i_gbk.txt</font><br />
</font>打开i_gbk.txt文件，内容为&#8220;"u00c8"u00db"u00d1"u00d2&#8221;。发现转码前后完全一样的。也就是说，等于没有转，或者说思想糊涂，对命名没有理解。<br />
<br />
</font></div>
<div><font size="2"><font color="#ff1493"><br />
H：将u_nv.txt转码到本地编码GBK，输出到控制台<br />
</font>C:"test&gt;<font color="#228b22">native2ascii -reverse -encoding ISO8859-1
i.txt<br />
</font>熔岩<br />
从这个结果看，目标达到到了，编码i.txt为ISO8859-1，转为本地编码后内容为&#8220;熔岩&#8221;。从这里应该意识到，native2ascii
-reverse命令中-encoding指定的编码为源文件的编码格式。而在native2ascii
命令中-encoding指定的编码为（生成的）目标文件的编码格式。这一点非常的重要！切记！！<br />
</font></div>
<div><font size="2"><br />
继续探索，新建文件12a.txt，内容&#8220;12axyz&#8221;。看看纯字母数字的编码又如何。<br />
</font></div>
<div><font size="2"><font color="#ff1493"><br />
I：将纯字母数字的文本文件12a.txt转换为Unicode编码</font><br />
<font color="#228b22">native2ascii 12a.txt
12a_nv.txt<br />
</font>打开12a_nv.txt文件，内容为&#8220;12axyz&#8221;。<br />
继续测试，转为ISO8859-1编码看看<br />
</font><font size="2">C:"test&gt;<font color="#228b22">native2ascii -encoding ISO8859-1
12a.txt<br />
</font>12axyz<br />
结果还是没有转码。<br />
<br />
从结果可以得出结论：对于纯数字和字母的文本类型文件（只有<font color="#000000"><font color="#0000ff">ASCII码）</font></font>，转码前后的内容是一样的。<br />
</font></div>
<p><font size="2"><font color="#0000ff"><strong><br />
5、总结</strong></font>：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#000000"><font color="#0000ff">native2ascii是一个非常的好转码工具，并且转码是可逆的！而其真正的含义并非本地编码——&gt;转码为ASCII码，而是一个通用的文本文件编码转换工具。在做编码转换的时候有两类指定编码的情形，分别指输出文件编码和输入文件编码，<font size="2"><font color="#000000">具体可以看看最佳实践部分</font></font>。</font></font></font></p>
<img src ="http://www.blogjava.net/alinglau36/aggbug/280000.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alinglau36/" target="_blank">lau</a> 2009-06-04 13:52 <a href="http://www.blogjava.net/alinglau36/archive/2009/06/04/280000.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>The project cannot be built until build path errors are resolved</title><link>http://www.blogjava.net/alinglau36/archive/2009/05/31/279259.html</link><dc:creator>lau</dc:creator><author>lau</author><pubDate>Sun, 31 May 2009 10:19:00 GMT</pubDate><guid>http://www.blogjava.net/alinglau36/archive/2009/05/31/279259.html</guid><wfw:comment>http://www.blogjava.net/alinglau36/comments/279259.html</wfw:comment><comments>http://www.blogjava.net/alinglau36/archive/2009/05/31/279259.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/alinglau36/comments/commentRss/279259.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alinglau36/services/trackbacks/279259.html</trackback:ping><description><![CDATA[<span style="color: red">问题解决:The project cannot be built until build path errors are resolved<cite class="fav_csdnstylebykimi"><a class="fav_csdnstylebykimi" title="收藏到我的网摘中，并分享给我的朋友" href="javascript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(saveit=window.open('http://wz.csdn.net/storeit.aspx?t='+escape(d.title)+'&amp;u='+escape(d.location.href)+'&amp;c='+escape(t),'saveit','scrollbars=no,width=590,height=300,left=75,top=20,status=no,resizable=yes'));saveit.focus();">收藏</a></cite>
<div class="blogstory"><script>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>
<p>1,看看project -- Build Automatically有没有勾上?如果没有,勾上以后,clean一下,重启eclipse </p>
<p>2,看看你的lib里面有没有不用的jar包,看你的.classpath文件中有没有错误的路径. </p>
<p>3,这是最重要的一点,有problems视图中查看有没有关于本项目的错误信息,一般都会有这样的话:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The project cannot be built until build path errors are resolved 然后下面提示unbound classpath, 一般在.classpath中删除这些path就可以了 </p>
<p>4. 安装Tomcat后,确保{tomcat_home}/common/lib文件夹下有jasper-runtime.jar、jsp-api.jar、servlet-api.jar、jndi.jar几个文件。启动Eclipse,第一次启动会有一个配置过程，选择菜单上的window/preferences，选java/classpath variables，New添加一个名为JDK_TOOLS并指向你的{jdk_home}/lib/tools.jar的环境变量。</p>
</div>
</span>
<img src ="http://www.blogjava.net/alinglau36/aggbug/279259.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alinglau36/" target="_blank">lau</a> 2009-05-31 18:19 <a href="http://www.blogjava.net/alinglau36/archive/2009/05/31/279259.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ClassPathXmlApplicationContext 和FileSystemXmlApplicationContext的区别 </title><link>http://www.blogjava.net/alinglau36/archive/2009/05/26/278050.html</link><dc:creator>lau</dc:creator><author>lau</author><pubDate>Tue, 26 May 2009 09:30:00 GMT</pubDate><guid>http://www.blogjava.net/alinglau36/archive/2009/05/26/278050.html</guid><wfw:comment>http://www.blogjava.net/alinglau36/comments/278050.html</wfw:comment><comments>http://www.blogjava.net/alinglau36/archive/2009/05/26/278050.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alinglau36/comments/commentRss/278050.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alinglau36/services/trackbacks/278050.html</trackback:ping><description><![CDATA[classpath: 前缀是不需要的， 默认就是指项目的classpath路径下面； <br />
&nbsp; 如果要使用绝对路径，需要加上 file: 前缀表示这是绝对路径； <br />
<br />
<br />
&nbsp; 对于<span style="color: #0000ff;">FileSystemXmlApplicationContext</span>: <br />
<br />
&nbsp;&nbsp; 默认表示的是两种： <br />
<br />
&nbsp; 1，没有盘符的是 项目工作路径， 即项目的根目录；<br />
&nbsp; 2，有盘符表示的是 文件绝对路径。 <br />
&nbsp; <br />
&nbsp; 如果要使用classpath路径， 需要前缀 classpath: .&nbsp; <br />
<br />
&nbsp; public class HelloClient { <br />
<br />
&nbsp; protected static final Log log = LogFactory.getLog(HelloClient.class); <br />
<br />
&nbsp; public static void main(String[] args) { <br />
<br />
&nbsp; // Resource resource = new <span style="color: #0000ff;">ClassPathResource</span>("appcontext.xml"); <br />
&nbsp; // BeanFactory factory = new XmlBeanFactory(resource); <br />
<br />
&nbsp; //用classpath路径也可以 <br />
&nbsp; // ApplicationContext factory=new ClassPathXmlApplicationContext("classpath:appcontext.xml"); <br />
&nbsp; // ApplicationContext factory=new ClassPathXmlApplicationContext("appcontext.xml"); <br />
<br />
&nbsp; // ClassPathXmlApplicationContext 使用了file前缀也是可以使用绝对路径的<br />
&nbsp;
// ApplicationContext factory=new
ClassPathXmlApplicationContext("file:G:/1Java实用项目资源/2Spring/1精通Spring全
Jar代码/workspace/workspace/example6/src/appcontext.xml"); <br />
<br />
//用文件系统的路径 默认是指项目的根路径<br />
// ApplicationContext factory=new FileSystemXmlApplicationContext("src/appcontext.xml"); <br />
<br />
//使用了 classpath: 前缀,作为标志, 这样,FileSystemXmlApplicationContext 也能够读入classpath下的相对路径 <br />
// ApplicationContext factory=new FileSystemXmlApplicationContext("classpath:appcontext.xml"); <br />
//
ApplicationContext factory=new
FileSystemXmlApplicationContext("file:G:/1Java实用项目资源/2Spring/1精通Spring全
Jar代码/workspace/workspace/example6/src/appcontext.xml"); <br />
<br />
//也可以不加file前缀<br />
ApplicationContext
factory=new
FileSystemXmlApplicationContext("G:/1Java实用项目资源/2Spring/1精通Spring全Jar代码
/workspace/workspace/example6/src/appcontext.xml"); <br />
<br />
IHelloWorld hw = (IHelloWorld) factory.getBean("helloworldbean"); <br />
log.info(hw.getContent("luoshifei")); <br />
<br />
} <br />
<br />
}
<img src ="http://www.blogjava.net/alinglau36/aggbug/278050.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alinglau36/" target="_blank">lau</a> 2009-05-26 17:30 <a href="http://www.blogjava.net/alinglau36/archive/2009/05/26/278050.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Myeclipse中web.xml中找不到applicationContext.xml</title><link>http://www.blogjava.net/alinglau36/archive/2009/05/26/278036.html</link><dc:creator>lau</dc:creator><author>lau</author><pubDate>Tue, 26 May 2009 08:27:00 GMT</pubDate><guid>http://www.blogjava.net/alinglau36/archive/2009/05/26/278036.html</guid><wfw:comment>http://www.blogjava.net/alinglau36/comments/278036.html</wfw:comment><comments>http://www.blogjava.net/alinglau36/archive/2009/05/26/278036.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alinglau36/comments/commentRss/278036.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alinglau36/services/trackbacks/278036.html</trackback:ping><description><![CDATA[在web.xml中加入这些配置<br />
<br />
&lt;context-param&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;param-name&gt;contextConfigLocation &lt;/param-name&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;param-value&gt;/WEB-INF/classes/applicationContext.xml &lt;/param-value&gt; <br />
&lt;/context-param&gt;<br />
<br />
问题主要由于加载spring的默认配置文件位置一般是在/WEB-INF/下找applicationContext.xml文件。而
Myeclipse文件自动生成的applicationContext文件是放在/WEB-INF/classes
/applicationContext.xml。所以在默认加载中是找不到applicationContext.xml文件的，必须加入上面配置。
<img src ="http://www.blogjava.net/alinglau36/aggbug/278036.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alinglau36/" target="_blank">lau</a> 2009-05-26 16:27 <a href="http://www.blogjava.net/alinglau36/archive/2009/05/26/278036.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Cookie和Session专题（转载）</title><link>http://www.blogjava.net/alinglau36/archive/2009/05/19/271572.html</link><dc:creator>lau</dc:creator><author>lau</author><pubDate>Tue, 19 May 2009 10:21:00 GMT</pubDate><guid>http://www.blogjava.net/alinglau36/archive/2009/05/19/271572.html</guid><wfw:comment>http://www.blogjava.net/alinglau36/comments/271572.html</wfw:comment><comments>http://www.blogjava.net/alinglau36/archive/2009/05/19/271572.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alinglau36/comments/commentRss/271572.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alinglau36/services/trackbacks/271572.html</trackback:ping><description><![CDATA[<span id="articlecontent" class="wenzhang_con" onmouseup="NewHighlight(event)" style="width: 780px;">一、cookie机制和session机制的区别<br />
*************************************************************************************<br />
具体来说cookie机制采用的是在客户端保持状态的方案，而session机制采用的是在服务器端保持状态的方案。<br />
同时我们也看到，由于才服务器端保持状态的方案在客户端也需要保存一个标识，所以session<br />
机制可能需要借助于cookie机制来达到保存标识的目的，但实际上还有其他选择<br />
*************************************************************************************<br />
<br />
二、会话cookie和持久cookie的区别<br />
*************************************************************************************<br />
如果不设置过期时间，则表示这个cookie生命周期为浏览器会话期间，只要关闭浏览器窗口，cookie就消失了。这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。<br />
如果设置了过期时间，浏览器就会把cookie保存到硬盘上，关闭后再次打开浏览器，这些cookie依然有效直到超过设定的过期时间。<br />
存储在硬盘上的cookie可以在不同的浏览器进程间共享，比如两个IE窗口。而对于保存在内存的cookie，不同的浏览器有不同的处理方式。<br />
*************************************************************************************<br />
<br />
三、如何利用实现自动登录<br />
*************************************************************************************<br />
当用户在某个网站注册后，就会收到一个惟一用户ID的cookie。客户后来重新连接时，这个<br />
用户ID会自动返回，服务器对它进行检查，确定它是否为注册用户且选择了自动登录，从而使用户务需给出明确的用户名和密码，就可以访问服务器上的资源。<br />
*************************************************************************************<br />
<br />
四、如何根据用户的爱好定制站点<br />
*************************************************************************************<br />
网站可以使用cookie记录用户的意愿。对于简单的设置，网站可以直接将页面的设置存储在cookie中完成定制。然而对于更复杂的定制，网站只需仅将一个惟一的标识符发送给用户，由服务器端的数据库存储每个标识符对应的页面设置。<br />
*************************************************************************************<br />
<br />
五、cookie的发送<br />
*************************************************************************************<br />
1.创建Cookie对象<br />
2.设置最大时效<br />
3.将Cookie放入到HTTP响应报头<br />
如果你创建了一个cookie，并将他发送到浏览器，默认情况下它是一个会话级别的cookie:存储在浏览器的内存中，用户退出浏览器之后被删除。如果你希望浏览器将该cookie存储在磁盘上，则<br />
需要使用maxAge，并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。<br />
发
送cookie需要使用HttpServletResponse的addCookie方法，将cookie插入到一个Set-Cookie　HTTP请求
报头中。由于这个方法并不修改任何之前指定的Set-Cookie报头，而是创建新的报头，因此我们将这个方法称为是addCookie，而非
setCookie。同样要记住响应报头必须在任何文档内容发送到客户端之前设置。<br />
<br />
六、cookie的读取<br />
*************************************************************************************<br />
1.调用request.getCookie<br />
要获取有浏览器发送来的cookie，需要调用HttpServletRequest的getCookies方法，这个调用返回Cookie对象的数组，对应由HTTP请求中Cookie报头输入的值。<br />
2.对数组进行循环，调用每个cookie的getName方法，直到找到感兴趣的cookie为止<br />
cookie与你的主机(域)相关，而非你的servlet或JSP页面。因而，尽管你的servlet可能只发送了单个cookie，你也可能会得到许多不相关的cookie。<br />
例如：<br />
String&nbsp;cookieName&nbsp;=&nbsp;&#8220;userID&#8221;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;Cookie&nbsp;cookies[]&nbsp;=&nbsp;request.getCookies();<br />
&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(cookies!=null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(int&nbsp;i=0;i&lt;cookies.length;i++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;Cookie&nbsp;cookie&nbsp;=&nbsp;cookies[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(cookieName.equals(cookie.getName())){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doSomethingWith(cookie.getValue());<br />
}<br />
}<br />
}<br />
*************************************************************************************<br />
<br />
七、如何使用cookie检测初访者<br />
*************************************************************************************<br />
A.调用HttpServletRequest.getCookies()获取Cookie数组<br />
B.在循环中检索指定名字的cookie是否存在以及对应的值是否正确<br />
C.如果是则退出循环并设置区别标识<br />
D.根据区别标识判断用户是否为初访者从而进行不同的操作<br />
*************************************************************************************<br />
<br />
八、使用cookie检测初访者的常见错误<br />
*************************************************************************************<br />
不能仅仅因为cookie数组中不存在在特定的数据项就认为用户是个初访者。如果cookie数组为null，客户可能是一个初访者，也可能是由于用户将cookie删除或禁用造成的结果。<br />
但是，如果数组非null,也不过是显示客户曾经到过你的网站或域，并不能说明他们曾经访问过你的servlet。其它servlet、JSP页面以及非Java&nbsp;Web应用都可以设置cookie，依据路径的设置，其中的任何cookie都有可能返回给用户的浏览器。<br />
正确的做法是判断cookie数组是否为空且是否存在指定的Cookie对象且值正确。<br />
*************************************************************************************<br />
<br />
九、使用cookie属性的注意问题<br />
*************************************************************************************<br />
属性是从服务器发送到浏览器的报头的一部分；但它们不属于由浏览器返回给服务器的报头。　<br />
因此除了名称和值之外，cookie属性只适用于从服务器输出到客户端的cookie；服务器端来自于浏览器的cookie并没有设置这些属性。　<br />
因而不要期望通过request.getCookies得到的cookie中可以使用这个属性。这意味着，你不能仅仅通过设置cookie的最大时效，
发出它，在随后的输入数组中查找适当的cookie,读取它的值，修改它并将它存回Cookie，从而实现不断改变的cookie值。<br />
*************************************************************************************<br />
<br />
十、如何使用cookie记录各个用户的访问计数<br />
*************************************************************************************<br />
1.获取cookie数组中专门用于统计用户访问次数的cookie的值<br />
2.将值转换成int型<br />
3.将值加1并用原来的名称重新创建一个Cookie对象<br />
4.重新设置最大时效<br />
5.将新的cookie输出<br />
*************************************************************************************<br />
<br />
十一、session在不同环境下的不同含义<br />
*************************************************************************************<br />
session，中文经常翻译为会话，其本来的含义是指有始有终的一系列动作/消息，比如打电话是从拿起电话拨号到挂断电话这中间的一系列过程可以称之为一个session。<br />
然而当session一词与网络协议相关联时，它又往往隐含了&#8220;面向连接&#8221;和/或&#8220;保持状态&#8221;这样两个含义。<br />
session在Web开发环境下的语义又有了新的扩展，它的含义是指一类用来在客户端与服务器端之间保持状态的解决方案。有时候Session也用来指这种解决方案的存储结构。<br />
*************************************************************************************<br />
<br />
十二、session的机制<br />
*************************************************************************************<br />
session机制是一种服务器端的机制，服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。<br />
但
程序需要为某个客户端的请求创建一个session的时候，服务器首先检查这个客户端的请求里是否包含了一个session标识－称为
session&nbsp;id,如果已经包含一个session&nbsp;id则说明以前已经为此客户创建过session，服务器就按照session&nbsp;id把这个
session检索出来使用(如果检索不到，可能会新建一个，这种情况可能出现在服务端已经删除了该用户对应的session对象，但用户人为地在请求的
URL后面附加上一个JSESSION的参数)。<br />
如果客户请求不包含session&nbsp;id，则为此客户创建一个session并且生成一个与此session相关联的session&nbsp;id，这个session&nbsp;id将在本次响应中返回给客户端保存。<br />
*************************************************************************************<br />
<br />
十三、保存session&nbsp;id的几种方式<br />
*************************************************************************************<br />
A．保存session&nbsp;id的方式可以采用cookie，这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。<br />
B．
由于cookie可以被人为的禁止，必须有其它的机制以便在cookie被禁止时仍然能够把session&nbsp;id传递回服务器，经常采用的一种技术叫做
URL重写，就是把session&nbsp;id附加在URL路径的后面，附加的方式也有两种，一种是作为URL路径的附加信息，另一种是作为查询字符串附加在
URL后面。网络在整个交互过程中始终保持状态，就必须在每个客户端可能请求的路径后面都包含这个session&nbsp;id。<br />
C．另一种技术叫做表单隐藏字段。就是服务器会自动修改表单，添加一个隐藏字段，以便在表单提交时能够把session&nbsp;id传递回服务器。<br />
*************************************************************************************<br />
<br />
十四、session什么时候被创建<br />
*************************************************************************************<br />
一个常见的错误是以为session在有客户端访问时就被创建，然而事实是直到某server端程序(如Servlet)调用HttpServletRequest.getSession(true)这样的语句时才会被创建。<br />
*************************************************************************************<br />
<br />
十五、session何时被删除<br />
*************************************************************************************<br />
session在下列情况下被删除：<br />
A．程序调用HttpSession.invalidate()<br />
B．距离上一次收到客户端发送的session&nbsp;id时间间隔超过了session的最大有效时间<br />
C．服务器进程被停止<br />
<br />
再次注意关闭浏览器只会使存储在客户端浏览器内存中的session&nbsp;cookie失效，不会使服务器端的session对象失效。<br />
*************************************************************************************<br />
<br />
十六、URL重写有什么缺点<br />
*************************************************************************************<br />
对所有的URL使用URL重写，包括超链接，form的action，和重定向的URL。每个引用你的站点的URL，以及那些返回给用户的URL(即使通过间接手段，比如服务器重定向中的Location字段)都要添加额外的信息。<br />
这意味着在你的站点上不能有任何静态的HTML页面(至少静态页面中不能有任何链接到站点动态页面的链接)。因此，每个页面都必须使用servlet
或JSP动态生成。即使所有的页面都动态生成，如果用户离开了会话并通过书签或链接再次回来，会话的信息都会丢失，因为存储下来的链接含有错误的标识信息
－该URL后面的SESSION&nbsp;ID已经过期了。　　<br />
*************************************************************************************<br />
<br />
十七、使用隐藏的表单域有什么缺点<br />
*************************************************************************************<br />
&nbsp;&nbsp;&nbsp;&nbsp;仅当每个页面都是有表单提交而动态生成时，才能使用这种方法。单击常规的&lt;A&nbsp;HREF..&gt;超文本链接并不产生表单提交，因此隐藏的表单域不能支持通常的会话跟踪，只能用于一系列特定的操作中，比如在线商店的结账过程<br />
*************************************************************************************<br />
<br />
十八、会话跟踪的基本步骤<br />
*************************************************************************************<br />
1．访问与当前请求相关的会话对象<br />
2．查找与会话相关的信息<br />
3．存储会话信息<br />
4．废弃会话数据<br />
*************************************************************************************<br />
<br />
十九、getSession()/getSession(true)、getSession(false)的区别<br />
*************************************************************************************<br />
getSession()/getSession(true)：当session存在时返回该session，否则新建一个session并返回该对象<br />
getSession(false)：当session存在时返回该session，否则不会新建session，返回null<br />
*************************************************************************************<br />
<br />
二十、如何将信息于会话关联起来<br />
*************************************************************************************<br />
setAttribute会替换任何之前设定的值；如果想要在不提供任何代替的情况下移除某个值，则应使用removeAttribute。这个方法会触发所有实现了HttpSessionBindingListener接口的值的valueUnbound<br />
方法。<br />
*************************************************************************************<br />
<br />
二十一、会话属性的类型有什么限制吗<br />
*************************************************************************************<br />
通常会话属性的类型只要是Object就可以了。除了null或基本类型，如int,double,boolean。<br />
如果要使用基本类型的值作为属性，必须将其转换为相应的封装类对象<br />
*************************************************************************************<br />
<br />
二十二、如何废弃会话数据<br />
*************************************************************************************<br />
A．只移除自己编写的servlet创建的数据：<br />
&nbsp;&nbsp;&nbsp;调用removeAttribute(&#8220;key&#8221;)将指定键关联的值废弃<br />
B．删除整个会话(在当前Web应用中)：<br />
&nbsp;&nbsp;&nbsp;调用invalidate，将整个会话废弃掉。这样做会丢失该用户的所有会话数据，而非仅仅由我们<br />
servlet或JSP页面创建的会话数据<br />
C．将用户从系统中注销并删除所有属于他(或她)的会话<br />
&nbsp;&nbsp;&nbsp;调用logOut，将客户从Web服务器中注销，同时废弃所有与该用户相关联的会话(每个Web应用至多一个)。这个操作有可能影响到服务器上多个不同的Web应用<br />
*************************************************************************************<br />
<br />
二十三、使用isNew来判断用户是否为新旧用户的错误做法<br />
*************************************************************************************<br />
public&nbsp;boolean&nbsp;isNew()方法如果会话尚未和客户程序(浏览器)发生任何联系，则这个方法返回true，这一般是因为会话是新建的，不是由输入的客户请求所引起的。<br />
但如果isNew返回false，只不过是说明他之前曾经访问该Web应用，并不代表他们曾访问过我们的servlet或JSP页面。<br />
因为session是与用户相关的，在用户之前访问的每一个页面都有可能创建了会话。因此isNew为false只能说用户之前访问过该Web应用，session可以是当前页面创建，也可能是由用户之前访问过的页面创建的。<br />
正确的做法是判断某个session中是否存在某个特定的key且其value是否正确<br />
*************************************************************************************<br />
<br />
二十四、Cookie的过期和Session的超时有什么区别<br />
*************************************************************************************<br />
会话的超时由服务器来维护，它不同于Cookie的失效日期。首先，会话一般基于驻留内存的cookie<br />
不是持续性的cookie，因而也就没有截至日期。即使截取到JSESSIONID&nbsp;cookie，并为它设定一个失效日期发送出去。浏览器会话和服务器会话也会截然不同。<br />
*************************************************************************************<br />
<br />
二十五、session&nbsp;cookie和session对象的生命周期是一样的吗<br />
*************************************************************************************<br />
当用户关闭了浏览器虽然session&nbsp;cookie已经消失，但session对象仍然保存在服务器端<br />
*************************************************************************************<br />
<br />
二十六、是否只要关闭浏览器，session就消失了<br />
*************************************************************************************<br />
程序一般都是在用户做log&nbsp;off的时候发个指令去删除session，然而浏览器从来不会主动在关闭之前通知服务器它将要被关闭，因此服务器根本不会有机会知道浏览器已经关闭。服务器会一直保留这个会话对象直到它处于非活动状态超过设定的间隔为止。<br />
之所以会有这种错误的认识，是因为大部分session机制都使用会话cookie来保存session&nbsp;id，而关闭浏览器后这个session&nbsp;id就消失了，再次连接到服务器时也就无法找到原来的session。<br />
如果服务器设置的cookie被保存到硬盘上，或者使用某种手段改写浏览器发出的HTTP请求报头，把原来的session&nbsp;id发送到服务器，则再次打开浏览器仍然能够找到原来的session。<br />
恰恰是由于关闭浏览器不会导致session被删除，迫使服务器为session设置了一个失效时间，当距离客户上一次使用session的时间超过了这个失效时间时，服务器就可以认为客户端已经停止了活动，才会把session删除以节省存储空间。<br />
由此我们可以得出如下结论：<br />
关闭浏览器，只会是浏览器端内存里的session&nbsp;cookie消失，但不会使保存在服务器端的session对象消失，同样也不会使已经保存到硬盘上的持久化cookie消失。<br />
*************************************************************************************<br />
<br />
<br />
二十七、打开两个浏览器窗口访问应用程序会使用同一个session还是不同的session<br />
*************************************************************************************<br />
通常session&nbsp;cookie是不能跨窗口使用的，当你新开了一个浏览器窗口进入相同页面时，系统会赋予你一个新的session&nbsp;id，这样我们信息共享的目的就达不到了。<br />
此
时我们可以先把session&nbsp;id保存在persistent&nbsp;cookie中(通过设置session的最大有效时间)，然后在新窗口中读出来，就可
以得到上一个窗口的session&nbsp;id了，这样通过session&nbsp;cookie和persistent&nbsp;cookie的结合我们就可以实现了跨窗口的
会话跟踪。<br />
*************************************************************************************<br />
<br />
二十八、如何使用会话显示每个客户的访问次数<br />
*************************************************************************************<br />
由于客户的访问次数是一个整型的变量，但session的属性类型中不能使用int，double，boolean等基本类型的变量，所以我们要用到这些基本类型的封装类型对象作为session对象中属性的值<br />
但像Integer是一种不可修改(Immutable)的数据结构：构建后就不能更改。这意味着每个请求都必须创建新的Integer对象，之后使用setAttribute来代替之前存在的老的属性的值。例如：<br />
HttpSession&nbsp;session&nbsp;=&nbsp;request.getSession();<br />
SomeImmutalbeClass&nbsp;value&nbsp;=&nbsp;(SomeImmutableClass)session.getAttribute(&#8220;SomeIdentifier&#8221;);<br />
if&nbsp;(value=&nbsp;=null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;new&nbsp;SomeImmutableClass(&#8230;);　//&nbsp;新创建一个不可更改对象<br />
}else{<br />
&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;new&nbsp;SomeImmutableClass(calculatedFrom(value));&nbsp;//&nbsp;对value重新计算后创建新的对象<br />
}<br />
session.setAttribute(&#8220;someIdentifier&#8221;,value);&nbsp;//&nbsp;使用新创建的对象覆盖原来的老的对象<br />
*************************************************************************************<br />
<br />
二十九、如何使用会话累计用户的数据<br />
*************************************************************************************<br />
使用可变的数据结构，比如数组、List、Map或含有可写字段的应用程序专有的数据结构。通过这种方式，除非首次分配对象，否则不需要调用setAttribute。例如<br />
<br />
HttpSession&nbsp;session&nbsp;=&nbsp;request.getSession();<br />
SomeMutableClass&nbsp;value&nbsp;=&nbsp;(SomeMutableClass)session.getAttribute(&#8220;someIdentifier&#8221;);<br />
if(value&nbsp;=&nbsp;=&nbsp;null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;new&nbsp;SomeMutableClass(&#8230;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;session.setAttribute(&#8220;someIdentifier&#8221;,value);<br />
}else{<br />
&nbsp;&nbsp;&nbsp;&nbsp;value.updateInternalAttribute(&#8230;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果已经存在该对象则更新其属性而不需重新设置属性<br />
}<br />
*************************************************************************************<br />
<br />
三十、不可更改对象和可更改对象在会话数据更新时的不同处理<br />
*************************************************************************************<br />
不可更改对象因为一旦创建之后就不能更改，所以每次要修改会话中属性的值的时候，都需要<br />
调用setAttribute(&#8220;someIdentifier&#8221;,newValue)来代替原有的属性的值，否则属性的值不会被更新<br />
可更改对象因为其自身一般提供了修改自身属性的方法，所以每次要修改会话中属性的值的时<br />
候，只要调用该可更改对象的相关修改自身属性的方法就可以了。这意味着我们就不需要调<br />
用setAttribute方法了<br />
*************************************************************************************</span>
<img src ="http://www.blogjava.net/alinglau36/aggbug/271572.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alinglau36/" target="_blank">lau</a> 2009-05-19 18:21 <a href="http://www.blogjava.net/alinglau36/archive/2009/05/19/271572.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>How to validate email, SSN, phone number in Java using Regular expressions.</title><link>http://www.blogjava.net/alinglau36/archive/2009/05/14/270638.html</link><dc:creator>lau</dc:creator><author>lau</author><pubDate>Thu, 14 May 2009 08:28:00 GMT</pubDate><guid>http://www.blogjava.net/alinglau36/archive/2009/05/14/270638.html</guid><wfw:comment>http://www.blogjava.net/alinglau36/comments/270638.html</wfw:comment><comments>http://www.blogjava.net/alinglau36/archive/2009/05/14/270638.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alinglau36/comments/commentRss/270638.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alinglau36/services/trackbacks/270638.html</trackback:ping><description><![CDATA[Regular Expressions offer a concise and powerful search-and-replace mechanism. <br />
They are patterns of characters used to perform
search, extract or replace operations on the given text. Regular expressions can
also be used to validate that the input conforms to a given format.
<p>For example, we can use Regular Expression to check whether the user input is
a valid Social Security number, a valid phone number or a valid email number,
etc.</p>
<p>Regular Expressions are supported by many languages. Sun added support for
regualer expression in Java 1.4 by introducing java.util.regex package. This
package provides the necessary classes for using Regular Expressions in a java
application. It consists of following three main classes ,</p>
<ul>
    <li>Pattern
    </li>
    <li>Matcher
    </li>
    <li>PatternSyntaxException </li>
</ul>
<p>The java.util.regex package has several other features for appending, text
replacement, and greedy/non-greedy pattern matching. See the <a onclick="javascript:urchinTracker('/outbound/java.sun.com/j2se/1.4.2/docs/api/java/util/regex/package-summary.html?ref=http_//www.google.cn/search?hl=zh-CN_newwindow=1_q=java+validateEmail_btnG=Google+_E6_90_9C_E7_B4_A2_meta=_aq=f_oq=');" href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/package-summary.html">JDK
Documentation</a> on java.util.regex to learn more about using regular
expressions in Java.</p>
<p>Using this package I created a utility class to validate some commonly used
data elements. My FieldsValidation class has following methods: </p>
<h5 id="toc-1-isemailvalid">1. isEmailValid:</h5>
<p>Validate email address using Java regex<br />
<codecomments><br />
/**
isEmailValid: Validate email address using Java reg ex.<br />
* This method checks
if the input string is a valid email address.<br />
* @param email String. Email
address to validate<br />
* @return boolean: true if email address is valid, false
otherwise.<br />
*/<br />
</codecomments><br />
<code><br />
public static boolean
isEmailValid(String email){<br />
boolean isValid = false;<br />
</code></p>
<p style="color: green;">/*<br />
Email format: A valid email address will have
following format:</p>
<ul>
    <li><strong>[""w"".-]+</strong> : Begins with word characters, (may include
    periods and hypens).
    </li>
    <li><strong>@</strong> : It must have a &#8216;@&#8217; symbol after initial characters.
    </li>
    <li><strong>([""w""-]+"".)+</strong> : &#8216;@&#8217; must follow by more alphanumeric
    characters (may include hypens.).<br />
    This part must also have a &#8220;.&#8221; to separate
    domain and subdomain names.
    </li>
    <li><strong>[A-Z]{2,4}$</strong> : Must end with two to four
    alaphabets.<br />
    (This will allow domain names with 2, 3 and 4 characters e.g pa,
    com, net, wxyz) </li>
</ul>
<p>Examples: Following email addresses will pass validation<br />
abc@xyz.net;
ab.c@tx.gov<br />
*/</p>
<p><code><br />
<codecomments><br />
//Initialize reg ex for email.
</codecomments><br />
String expression =
&#8220;^[""w"".-]+@([""w""-]+"".)+[A-Z]{2,4}$&#8221;;<br />
CharSequence inputStr =
email;<br />
</code><br />
<codecomments><br />
//Make the comparison
case-insensitive.<br />
</codecomments><br />
<code><br />
Pattern pattern =
Pattern.compile(expression,Pattern.CASE_INSENSITIVE);<br />
Matcher matcher =
pattern.matcher(inputStr);<br />
if(matcher.matches()){<br />
isValid =
true;<br />
}<br />
return isValid;<br />
}<br />
</code><br />
<em><strong>Update</strong>:
Read this post for a more thorough <a href="http://www.zparacha.com/ultimate-java-regular-expression-to-validate-email-address/">Java
regular expression to validate email address</a>.</em></p>
<h5 id="toc-2-isphonenumbervalid"><em>2. isPhoneNumberValid:</em></h5>
<p><em>Validate phone number using Java reg ex.<br />
<codecomments><br />
/**
isPhoneNumberValid: Validate phone number using Java reg ex.<br />
* This method
checks if the input string is a valid phone number.<br />
* @param email String.
Phone number to validate<br />
* @return boolean: true if phone number is valid,
false otherwise.<br />
*/<br />
</codecomments><br />
<code><br />
public static boolean
isPhoneNumberValid(String phoneNumber){<br />
boolean isValid =
false;<br />
</code></em></p>
<p style="color: green;"><em>/* Phone Number format: (nnn)nnn-nnnn; nnnnnnnnnn;
nnn-nnn-nnnn</em></p>
<ul>
    <li><em><strong>^""(?</strong> : May start with an option &#8220;(&#8221; .
    </em></li>
    <li><em><strong>(""d{3})</strong>: Followed by 3 digits.
    </em></li>
    <li><em><strong>"")?</strong> : May have an optional &#8220;)&#8221;
    </em></li>
    <li><em><strong>[- ]?</strong> : May have an optional &#8220;-&#8221; after the first 3 digits
    or after optional ) character.
    </em></li>
    <li><em><strong>(""d{3})</strong> : Followed by 3 digits.
    </em></li>
    <li><em><strong>[- ]? </strong>: May have another optional &#8220;-&#8221; after numeric digits.
    </em></li>
    <li><em><strong>(""d{4})$</strong> : ends with four digits. </em></li>
</ul>
<p><em>Examples: Matches following phone numbers:<br />
(123)456-7890, 123-456-7890,
1234567890, (123)-456-7890</em></p>
<p><code>//Initialize reg ex for phone number. <br />
String expression =
&#8220;^""(?(""d{3})"")?[- ]?(""d{3})[- ]?(""d{4})$&#8221;;<br />
CharSequence inputStr =
phoneNumber;<br />
Pattern pattern = Pattern.compile(expression);<br />
Matcher
matcher = pattern.matcher(inputStr);<br />
if(matcher.matches()){<br />
isValid =
true;<br />
}<br />
return isValid;<br />
}<br />
</code>
</p>
<h5 id="toc-3-isvalidssn"><em>3. isValidSSN:</em></h5>
<p><em>Validate Social Security Number (SSN) using Java reg
ex.<br />
<codecomments><br />
/** isSSNValid: Validate Social Security number (SSN)
using Java reg ex.<br />
* This method checks if the input string is a valid
SSN.<br />
* @param email String. Social Security number to validate<br />
* @return
boolean: true if social security number is valid, false
otherwise.<br />
*/<br />
</codecomments><br />
<code><br />
public static boolean
isSSNValid(String ssn){<br />
boolean isValid = false;<br />
</code></em></p>
<p style="color: green;"><em>/*SSN format xxx-xx-xxxx, xxxxxxxxx, xxx-xxxxxx;
xxxxx-xxxx:</em></p>
<ul>
    <li><em><strong>^""d{3}</strong> : Starts with three numeric digits.
    </em></li>
    <li><em><strong>[- ]?</strong> : Followed by an optional &#8220;-&#8221;
    </em></li>
    <li><em><strong>""d{2}</strong> : Two numeric digits after the optional &#8220;-&#8221;
    </em></li>
    <li><em><strong>[- ]?</strong> : May contain an optional second &#8220;-&#8221; character.
    </em></li>
    <li><em><strong>""d{4}</strong> : ends with four numeric digits. </em></li>
</ul>
<p><em>Examples: 879-89-8989; 869878789 etc.<br />
*/</em></p>
<p><code><em><br />
<codecomments><br />
//Initialize reg ex for SSN.
</codecomments><br />
String expression = &#8220;^""d{3}[- ]?""d{2}[-
]?""d{4}$&#8221;;<br />
CharSequence inputStr = ssn;<br />
Pattern pattern =
Pattern.compile(expression);<br />
Matcher matcher =
pattern.matcher(inputStr);<br />
if(matcher.matches()){<br />
isValid =
true;<br />
}<br />
return isValid;<br />
}<br />
</em></code></p>
<h5 id="toc-4-isnumeric"><em>4. isNumeric:</em></h5>
<p><em>Validate a number using Java
regex.<br />
<codecomments><br />
/**<strong>isNumeric: Validate a number using Java
regex.</strong><br />
* This method checks if the input string contains all numeric
characters.<br />
* @param email String. Number to validate<br />
* @return boolean:
true if the input is all numeric, false
otherwise.<br />
*/<br />
</codecomments><br />
<code><br />
public static boolean
isNumeric(String number){<br />
boolean isValid = false;<br />
</code></em></p>
<p style="color: green;"><em>/*Number: A numeric value will have following
format:</em></p>
<ul>
    <li><em><strong>^[-+]?</strong> : Starts with an optional &#8220;+&#8221; or &#8220;-&#8221; sign.
    </em></li>
    <li><em><strong>[0-9]*</strong> : May have one or more digits.
    </em></li>
    <li><em><strong>"".?</strong> : May contain an optional &#8220;.&#8221; (decimal point)
    character.
    </em></li>
    <li><em><strong>[0-9]+$</strong> : ends with numeric digit. </em></li>
</ul>
<p><em>*/</em></p>
<p><code><em><br />
<codecomments><br />
//Initialize reg ex for numeric data.
</codecomments><br />
String expression =
&#8220;^[-+]?[0-9]*"".?[0-9]+$&#8221;;<br />
CharSequence inputStr = number;<br />
Pattern pattern
= Pattern.compile(expression);<br />
Matcher matcher =
pattern.matcher(inputStr);<br />
if(matcher.matches()){<br />
isValid =
true;<br />
}<br />
return isValid;<br />
}<br />
</em></code></p>
<p><em>This example demonstrates how easy it is to validate email address, ssn,
phone number in Java using regular expressions. You can read more about regular
expression format <a onclick="javascript:urchinTracker('/outbound/java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html?ref=http_//www.google.cn/search?hl=zh-CN_newwindow=1_q=java+validateEmail_btnG=Google+_E6_90_9C_E7_B4_A2_meta=_aq=f_oq=');" href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html">here
</a>.</em></p>
<p><em>You can download complete Java code for this class <a href="/examples/FieldsValidation.java">here </a>.</em></p>
<p><em>Feel free to modify and use this class in your projects. Let me know if you
have any questions or comments.</em></p>
<p><em>Enjoy.</em></p>
<div>
<div><em><strong>Share and Enjoy:</strong> </em></div>
<ul>
    <li><em><a title="StumbleUpon" onclick="javascript:urchinTracker('/outbound/www.stumbleupon.com/submit?url=http_3A_2F_2Fwww.zparacha.com_2Fjava_regex_validation_2F_amp_title=How_20to_20validate_20email_2C_20SSN_2C_20phone_20number_20in_20Java_20using_20Regular_20expressions.?ref=http_//www.google.cn/search?hl=zh-CN_newwindow=1_q=java+validateEmail_btnG=Google+_E6_90_9C_E7_B4_A2_meta=_aq=f_oq=');" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fwww.zparacha.com%2Fjava_regex_validation%2F&amp;title=How%20to%20validate%20email%2C%20SSN%2C%20phone%20number%20in%20Java%20using%20Regular%20expressions." rel="nofollow"><img title="StumbleUpon" alt="StumbleUpon" src="http://www.zparacha.com/wp-content/plugins/sociable/images/stumbleupon.png" /></a>
    </em></li>
    <li><em><a title="Digg" onclick="javascript:urchinTracker('/outbound/digg.com/submit?phase=2_amp_url=http_3A_2F_2Fwww.zparacha.com_2Fjava_regex_validation_2F_amp_title=How_20to_20validate_20email_2C_20SSN_2C_20phone_20number_20in_20Java_20using_20Regular_20expressions.?ref=http_//www.google.cn/search?hl=zh-CN_newwindow=1_q=java+validateEmail_btnG=Google+_E6_90_9C_E7_B4_A2_meta=_aq=f_oq=');" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.zparacha.com%2Fjava_regex_validation%2F&amp;title=How%20to%20validate%20email%2C%20SSN%2C%20phone%20number%20in%20Java%20using%20Regular%20expressions." rel="nofollow"><img title="Digg" alt="Digg" src="http://www.zparacha.com/wp-content/plugins/sociable/images/digg.png" /></a>
    </em></li>
    <li><em><a title="del.icio.us" onclick="javascript:urchinTracker('/outbound/del.icio.us/post?url=http_3A_2F_2Fwww.zparacha.com_2Fjava_regex_validation_2F_amp_title=How_20to_20validate_20email_2C_20SSN_2C_20phone_20number_20in_20Java_20using_20Regular_20expressions.?ref=http_//www.google.cn/search?hl=zh-CN_newwindow=1_q=java+validateEmail_btnG=Google+_E6_90_9C_E7_B4_A2_meta=_aq=f_oq=');" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.zparacha.com%2Fjava_regex_validation%2F&amp;title=How%20to%20validate%20email%2C%20SSN%2C%20phone%20number%20in%20Java%20using%20Regular%20expressions." rel="nofollow"><img title="del.icio.us" alt="del.icio.us" src="http://www.zparacha.com/wp-content/plugins/sociable/images/delicious.png" /></a>
    </em></li>
    <li><em><a title="Reddit" onclick="javascript:urchinTracker('/outbound/reddit.com/submit?url=http_3A_2F_2Fwww.zparacha.com_2Fjava_regex_validation_2F_amp_title=How_20to_20validate_20email_2C_20SSN_2C_20phone_20number_20in_20Java_20using_20Regular_20expressions.?ref=http_//www.google.cn/search?hl=zh-CN_newwindow=1_q=java+validateEmail_btnG=Google+_E6_90_9C_E7_B4_A2_meta=_aq=f_oq=');" href="http://reddit.com/submit?url=http%3A%2F%2Fwww.zparacha.com%2Fjava_regex_validation%2F&amp;title=How%20to%20validate%20email%2C%20SSN%2C%20phone%20number%20in%20Java%20using%20Regular%20expressions." rel="nofollow"><img title="Reddit" alt="Reddit" src="http://www.zparacha.com/wp-content/plugins/sociable/images/reddit.png" /></a>
    </em></li>
    <li><em><a title="Sphinn" onclick="javascript:urchinTracker('/outbound/sphinn.com/submit.php?url=http_3A_2F_2Fwww.zparacha.com_2Fjava_regex_validation_2F_amp_title=How_20to_20validate_20email_2C_20SSN_2C_20phone_20number_20in_20Java_20using_20Regular_20expressions.?ref=http_//www.google.cn/search?hl=zh-CN_newwindow=1_q=java+validateEmail_btnG=Google+_E6_90_9C_E7_B4_A2_meta=_aq=f_oq=');" href="http://sphinn.com/submit.php?url=http%3A%2F%2Fwww.zparacha.com%2Fjava_regex_validation%2F&amp;title=How%20to%20validate%20email%2C%20SSN%2C%20phone%20number%20in%20Java%20using%20Regular%20expressions." rel="nofollow"><img title="Sphinn" alt="Sphinn" src="http://www.zparacha.com/wp-content/plugins/sociable/images/sphinn.gif" /></a>
    </em></li>
    <li><em><a title="blinkbits" onclick="javascript:urchinTracker('/outbound/www.blinkbits.com/bookmarklets/save.php?v=1_amp_source_url=http_3A_2F_2Fwww.zparacha.com_2Fjava_regex_validation_2F_amp_title=How_20to_20validate_20email_2C_20SSN_2C_20phone_20number_20in_20Java_20using_20Regular_20expressions._amp_body=How_20to_20validate_20email_2C_20SSN_2C_20phone_20number_20in_20Java_20using_20Regular_20expressions.?ref=http_//www.google.cn/search?hl=zh-CN_newwindow=1_q=java+validateEmail_btnG=Google+_E6_90_9C_E7_B4_A2_meta=_aq=f_oq=');" href="http://www.blinkbits.com/bookmarklets/save.php?v=1&amp;source_url=http%3A%2F%2Fwww.zparacha.com%2Fjava_regex_validation%2F&amp;title=How%20to%20validate%20email%2C%20SSN%2C%20phone%20number%20in%20Java%20using%20Regular%20expressions.&amp;body=How%20to%20validate%20email%2C%20SSN%2C%20phone%20number%20in%20Java%20using%20Regular%20expressions." rel="nofollow"><img title="blinkbits" alt="blinkbits How to validate email, SSN, phone number in Java using Regular expressions." src="http://www.zparacha.com/wp-content/plugins/sociable/images/blinkbits.png" /></a>
    </em></li>
    <li><em><a title="NewsVine" onclick="javascript:urchinTracker('/outbound/www.newsvine.com/_tools/seed_amp_save?u=http_3A_2F_2Fwww.zparacha.com_2Fjava_regex_validation_2F_amp_h=How_20to_20validate_20email_2C_20SSN_2C_20phone_20number_20in_20Java_20using_20Regular_20expressions.?ref=http_//www.google.cn/search?hl=zh-CN_newwindow=1_q=java+validateEmail_btnG=Google+_E6_90_9C_E7_B4_A2_meta=_aq=f_oq=');" href="http://www.newsvine.com/_tools/seed&amp;save?u=http%3A%2F%2Fwww.zparacha.com%2Fjava_regex_validation%2F&amp;h=How%20to%20validate%20email%2C%20SSN%2C%20phone%20number%20in%20Java%20using%20Regular%20expressions." rel="nofollow"><img title="NewsVine" alt="NewsVine" src="http://www.zparacha.com/wp-content/plugins/sociable/images/newsvine.png" /></a>
    </em></li>
    <li><em><a title="Smarking" onclick="javascript:urchinTracker('/outbound/smarking.com/editbookmark/?url=http_3A_2F_2Fwww.zparacha.com_2Fjava_regex_validation_2F_amp_title=How_20to_20validate_20email_2C_20SSN_2C_20phone_20number_20in_20Java_20using_20Regular_20expressions.?ref=http_//www.google.cn/search?hl=zh-CN_newwindow=1_q=java+validateEmail_btnG=Google+_E6_90_9C_E7_B4_A2_meta=_aq=f_oq=');" href="http://smarking.com/editbookmark/?url=http%3A%2F%2Fwww.zparacha.com%2Fjava_regex_validation%2F&amp;title=How%20to%20validate%20email%2C%20SSN%2C%20phone%20number%20in%20Java%20using%20Regular%20expressions." rel="nofollow"><img title="Smarking" alt="Smarking" src="http://www.zparacha.com/wp-content/plugins/sociable/images/smarking.png" /></a>
    </em></li>
    <li><em><a title="Yahoo! Buzz" onclick="javascript:urchinTracker('/outbound/buzz.yahoo.com/submit/?submitUrl=http_3A_2F_2Fwww.zparacha.com_2Fjava_regex_validation_2F_amp_submitHeadline=How_20to_20validate_20email_2C_20SSN_2C_20phone_20number_20in_20Java_20using_20Regular_20expressions._amp_submitSummary=_0D_0ARegular_20Expressions_20offer_20a_20concise_20and_20powerful_20search-and-replace_20mechanism._20_09_0D_0AThey_20are_20patterns_20of_20characters_20used_20to_20perform_20_20search_2C_20extract_20or_20replace_20operations_20on_20the_20given_20text._20Regular_20expressions_20can_20also_20be_20used_20to_20validate_20that_20the_20in_amp_submitCategory=science_amp_submitAssetType=text?ref=http_//www.google.cn/search?hl=zh-CN_newwindow=1_q=java+validateEmail_btnG=Google+_E6_90_9C_E7_B4_A2_meta=_aq=f_oq=');" href="http://buzz.yahoo.com/submit/?submitUrl=http%3A%2F%2Fwww.zparacha.com%2Fjava_regex_validation%2F&amp;submitHeadline=How%20to%20validate%20email%2C%20SSN%2C%20phone%20number%20in%20Java%20using%20Regular%20expressions.&amp;submitSummary=%0D%0ARegular%20Expressions%20offer%20a%20concise%20and%20powerful%20search-and-replace%20mechanism.%20%09%0D%0AThey%20are%20patterns%20of%20characters%20used%20to%20perform%20%20search%2C%20extract%20or%20replace%20operations%20on%20the%20given%20text.%20Regular%20expressions%20can%20also%20be%20used%20to%20validate%20that%20the%20in&amp;submitCategory=science&amp;submitAssetType=text" rel="nofollow"><img title="Yahoo! Buzz" alt="Yahoo! Buzz" src="http://www.zparacha.com/wp-content/plugins/sociable/images/yahoobuzz.gif" /></a>
    </em></li>
</ul>
</div>
<p><em><em>If you enjoyed this post, make sure you <a href="http://www.zparacha.com/feed/">subscribe to my RSS feed</a>!</em></em></p>
<p><span style="font-weight: bold;"><em>Related posts:</em></span>
</p>
<ul>
    <li><em><a title="Permanent Link: #1 Programming Language - Java" href="http://www.zparacha.com/java-remains-1-programming-language/" rel="bookmark">#1 Programming Language - Java</a>
    </em></li>
    <li><em><a title="Permanent Link: (Ultimate) Java Regular Expression to validate (any) email address." href="http://www.zparacha.com/ultimate-java-regular-expression-to-validate-email-address/" rel="bookmark">(Ultimate) Java Regular Expression to validate (any) email
    address.</a>
    </em></li>
    <li><em><a title="Permanent Link: Edit and Test Regular expressions online using RegExr." href="http://www.zparacha.com/regular-expressions-tool/" rel="bookmark">Edit and
    Test Regular expressions online using RegExr.</a>
    </em></li>
    <li><em><a title="Permanent Link: Extract substring from end of a Java String" href="http://www.zparacha.com/extract-substring-from-end-of-a-java-string/" rel="bookmark">Extract substring from end of a Java String</a>
    </em></li>
    <li><em><a title="Permanent Link: How to read properties file in Java." href="http://www.zparacha.com/read-java-properties-file/" rel="bookmark">How to
    read properties file in Java.</a></em></li>
</ul>
<p><em>Jan 10, 2008</em><em><br />
Filed under: <a title="View all posts in Java" href="http://www.zparacha.com/category/java/" rel="category tag">Java</a><br />
Tags: <a href="http://www.zparacha.com/tag/java/" rel="tag">Java</a>, <a href="http://www.zparacha.com/tag/phone-number/" rel="tag">Phone number</a>, <a href="http://www.zparacha.com/tag/regex/" rel="tag">RegEx</a>, <a href="http://www.zparacha.com/tag/regular-expression/" rel="tag">Regular Expression</a>, <a href="http://www.zparacha.com/tag/ssn/" rel="tag">SSN</a>, <a href="http://www.zparacha.com/tag/utility/" rel="tag">utility</a>, <a href="http://www.zparacha.com/tag/validate-email/" rel="tag">Validate email</a></em></p>
<div id="comments">
<h3 id="comments-count"><em>12 Responses</em></h3>
<ol>
    <li id="comment-29">
    <p><em><strong>haro</strong>:</em></p>
    <p><em>This explanation is very helpful. Very.<br />
    One minor question: It seems that
    the email validation accepts an underscore (&#8221;_&#8221;). I would have expected the
    validation to reject the character, because it is not specified in
    expression.</em></p>
    <p><em>Posted on <a title="" href="#comment-29">January 23rd,
    2008 at 12:29 pm</a></em></p>
    </li>
    <li id="comment-31">
    <p><em><strong><a onclick="javascript:urchinTracker('/file/?ref=http_//www.google.cn/search?hl=zh-CN_newwindow=1_q=java+validateEmail_btnG=Google+_E6_90_9C_E7_B4_A2_meta=_aq=f_oq=');" href="http://www.zparacha.com/">zparacha</a></strong>:</em></p>
    <p><em>Haro, the regular expression for email validation has a &#8216;"w&#8217;. "w stands for
    &#8220;word character&#8221; and that includes [A-Z], [a-z], [0-9] and the &#8220;underscore (_)&#8221;
    character. That is why if you have an &#8220;_&#8221; in your email address it will pass
    this validation.<br />
    Hope that clears it a bit.</em></p>
    <p><em>Posted on <a title="" href="#comment-31">January 24th,
    2008 at 2:41 pm</a></em></p>
    </li>
    <li id="comment-41">
    <p><em><strong>GDD</strong>:</em></p>
    <p><em>Really nice article</em></p>
    <p><em>Posted on <a title="" href="#comment-41">January 27th,
    2008 at 1:06 am</a></em></p>
    </li>
    <li id="comment-77">
    <p><em><strong><a onclick="javascript:urchinTracker('/outbound/linoleum.leapster.org/archives/24-Regular-expressions-in-Java.html?ref=http_//www.google.cn/search?hl=zh-CN_newwindow=1_q=java+validateEmail_btnG=Google+_E6_90_9C_E7_B4_A2_meta=_aq=f_oq=');" href="http://linoleum.leapster.org/archives/24-Regular-expressions-in-Java.html">Linoleum</a></strong>:</em></p>
    <p><em><strong>Regular expressions in Java&#8230;</strong></em></p>
    <p><em>Confused by regular expressions in Java? This brief tutorial by zparacha may
    help shed some light on them&#8230;&#8230;</em></p>
    <p><em>Posted on <a title="" href="#comment-77">January 31st,
    2008 at 2:43 am</a></em></p>
    </li>
    <li id="comment-82">
    <p><span><em><strong><a onclick="javascript:urchinTracker('/outbound/deliggit.com/2008/02/01/how-to-essentials-regular-expressions-in-java/?ref=http_//www.google.cn/search?hl=zh-CN_newwindow=1_q=java+validateEmail_btnG=Google+_E6_90_9C_E7_B4_A2_meta=_aq=f_oq=');" href="http://deliggit.com/2008/02/01/how-to-essentials-regular-expressions-in-java/">Deliggit.com
    | The social sites' most interesting urls</a></strong>:</em></span></p>
    <p><em><strong>How To essentials - Regular expressions in Java |
    Deliggit.com&#8230;</strong></em></p>
    <p><em>zparacha.com</em></p>
    <p><em>How to validate email, SSN, phone number in Java using Regular
    expressions.</em></p>
    <p><em>This&#8230;</em></p>
    </li>
</ol>
</div>
<img src ="http://www.blogjava.net/alinglau36/aggbug/270638.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alinglau36/" target="_blank">lau</a> 2009-05-14 16:28 <a href="http://www.blogjava.net/alinglau36/archive/2009/05/14/270638.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring 的MVC I18N－国际化相关配置</title><link>http://www.blogjava.net/alinglau36/archive/2009/05/08/269609.html</link><dc:creator>lau</dc:creator><author>lau</author><pubDate>Fri, 08 May 2009 06:58:00 GMT</pubDate><guid>http://www.blogjava.net/alinglau36/archive/2009/05/08/269609.html</guid><wfw:comment>http://www.blogjava.net/alinglau36/comments/269609.html</wfw:comment><comments>http://www.blogjava.net/alinglau36/archive/2009/05/08/269609.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alinglau36/comments/commentRss/269609.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alinglau36/services/trackbacks/269609.html</trackback:ping><description><![CDATA[<p>
<font color="#ffa500">一、基于浏览器语言的国际化配置</font> <br />
<br />
使用Spring的MVC，并且配置中有配置Resource<span onclick="tagshow(event)" href="http://www.diybl.com/course/3_program/java/javajs/2008224/tag.php?name=%CE%C4%BC%FE">文件</span> <br />
<br />
<table style="width: 98%;" class="t_table" bgcolor="#999999" cellspacing="0">
    <tbody>
        <tr>
            <td>&lt;!-- <span onclick="tagshow(event)" href="http://www.diybl.com/course/3_program/java/javajs/2008224/tag.php?name=%D7%CA%D4%B4">资源</span>文件绑定器 --&gt;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<br />
            &lt;bean id=<font color="#ff0000">"messageSource"</font> class=<font color="#ff0000">"org.<span onclick="tagshow(event)" href="http://www.diybl.com/course/3_program/java/javajs/2008224/tag.php?name=spring">spring</span>framework.cont<span onclick="tagshow(event)" href="http://www.diybl.com/course/3_program/java/javajs/2008224/tag.php?name=ext">ext</span>.support.ResourceBundleMessageSource"</font>&gt;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <br />
            <br />
            &lt;property name=<font color="#ff0000">"basename"</font> value=<font color="#ff0000">"message-info"</font> /&gt;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
            &lt;property name=<font color="#ff0000">"useCodeAsDefaultMessage"</font> value=<font color="#ff0000">"true"</font> /&gt;&nbsp; &nbsp;&nbsp; &nbsp; <br />
            <br />
            &lt;/bean&gt;<br />
            </td>
        </tr>
    </tbody>
</table>
<br />
其中，<font color="#ff0000">message-info</font>是你的properties文件的通用名。如：我的配置文件叫message-info.properties,message-info_zh_CN.properties等等 <br />
<br />
只要有了这个配置，然后配置JSP渲染器为JSTL支持的，那么在你的JSP文件中使用fmt标记就可以实现客户浏览器语言国际化了。 <br />
如：&lt;fmt:message key="info.login.title" /&gt; <br />
其中的info.login.title和你的资源文件对应 <br />
<br />
<font color="#ffa500">二、基于动态加载的国际化配置</font> <br />
<br />
<font color="#008080">1、基于请求的国际化配置</font> <br />
<br />
基于请求的国际化配置是指，在当前请求内，国际化配置生效，否则自动以浏览器为主。 <br />
<br />
配置方式如下： <br />
首先配置拦截器 <br />
<table style="width: 98%;" class="t_table" bgcolor="#999999" cellspacing="0">
    <tbody>
        <tr>
            <td>&lt;!-- 国际化操作 拦截器 必需配置，可以和其它国际化方式通用 --&gt;&nbsp; &nbsp;&nbsp; &nbsp; <br />
            <br />
            &lt;bean id=<font color="#ff0000">"<font color="#ff0000">localeChangeInterceptor</font>"</font> class=<font color="#ff0000">"org.springframework.<span onclick="tagshow(event)" href="http://www.diybl.com/course/3_program/java/javajs/2008224/tag.php?name=web">web</span>.<span onclick="tagshow(event)" href="http://www.diybl.com/course/3_program/java/javajs/2008224/tag.php?name=servlet">servlet</span>.i18n.LocaleChangeInterceptor"</font> /&gt; <br />
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
这个配置呢，是不论请求级别的国际化，还是Cookie级别的国际化，再或者Session级别的国际化，都<font color="#ff0000">必需有配置这个拦截器</font>，否则会不能使用。 <br />
<br />
配好上面的拦截器之后，就将拦截器注入到你的UrlHandlerMapping中，例如: <br />
<table style="width: 98%;" class="t_table" bgcolor="#999999" cellspacing="0">
    <tbody>
        <tr>
            <td>&lt;bean id=<font color="#ff0000">"defaultUrlMapping"</font> class=<font color="#ff0000">"org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"</font>&gt;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <br />
            <br />
            &lt;property name=<font color="#ff0000">"<font color="#ff0000">interceptors</font>"</font> ref=<font color="#ff0000">"<font color="#ff0000">localeChangeInterceptor</font>"</font> /&gt;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <br />
            <br />
            &lt;property name=<font color="#ff0000">"order"</font>&gt;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
            &lt;value&gt;<font color="#ff0000">1</font>&lt;/value&gt;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
            &lt;/property&gt;&nbsp; &nbsp;&nbsp; &nbsp; <br />
            <br />
            &lt;/bean&gt;<br />
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
这个时候，但凡有了符合UrlMapping的请求，就会被拦截，并且开始配置国际化参数 <br />
<table style="width: 98%;" class="t_table" bgcolor="#999999" cellspacing="0">
    <tbody>
        <tr>
            <td>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&lt;bean id=<font color="#ff0000">"localeResolver"</font> class=<font color="#ff0000">"org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver"</font>&gt;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&lt;/bean&gt;</td>
        </tr>
    </tbody>
</table>
<br />
<br />
默认的参数名为<font color="#ff0000">locale</font>主意大小写。里面放的就是你的提交参数。如:en_US，zh_CN之类的，这个时候，你在页面上加一句
<table style="width: 98%;" class="t_table" bgcolor="#999999" cellspacing="0">
    <tbody>
        <tr>
            <td>&lt;a href=<font color="#ff0000">"?locale=zh_CN"</font>&gt;简体中文&lt;/a&gt;</td>
        </tr>
    </tbody>
</table>
如果你的资源中，饱含建议中文的配置，那么就会变成你确定的简体中文拉。 <br />
<br />
<font color="#008080">2、基于Session的国际化配置</font> <br />
<br />
拦截器和基于请求的相同 <br />
<br />
Session的配置如下： <br />
<table style="width: 98%;" class="t_table" bgcolor="#999999" cellspacing="0">
    <tbody>
        <tr>
            <td>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&lt;bean id=<font color="#ff0000">"<font color="#ff0000">localeResolver</font>"</font> class=<font color="#ff0000">"org.springframework.web.servlet.i18n.SessionLocaleResolver"</font>&gt;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&lt;/bean&gt; </td>
        </tr>
    </tbody>
</table>
<br />
<br />
在你的处理的Controller中，将提交上来的locale字段信息生成真正的Locale对象，然后将对象保存在Session中，默认保存的ID是
<table style="width: 98%;" class="t_table" bgcolor="#999999" cellspacing="0">
    <tbody>
        <tr>
            <td>SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME</td>
        </tr>
    </tbody>
</table>
</p>
<p><br />
<br />
这样，当你的Session不过期，那么语言种类始终保持正确的说。我一直是这样子用的，我觉得还是Session的好，老外们用了很满意。 <br />
<br />
<font color="#008080">3、基于Cookie的国际化配置</font> <br />
<br />
这个我就不说了，反正用的不多，至少我做的项目能不用Cookie就不用Cookie，所以，基于Cookie的国际化配置我就不细说了，如果想知道怎么配置，那么<span onclick="tagshow(event)" href="http://www.diybl.com/course/3_program/java/javajs/2008224/tag.php?name=%CF%C2%D4%D8">下载</span>一个Spring，其中的例子程序就是用Cookie配置的，你自己读代码就OK了。 <br />
<br />
<font color="#ffa500">三、注意事项</font> <br />
<br />
如果不用默认的浏览器语言国际化方式，那么拦截器一定要配置，如果你有多个UrlMapping，那么就每个都配上拦截器。 <br />
至于配置的LocaleResolver的名字，一定要用上面的配置中的名字<font color="#ff0000">localeResolver</font>当然了，这个是默认的名字来的，自己设置成别的也可以，但是就是麻烦，反正我用默认的就感觉不错 <br />
</p>
<img src ="http://www.blogjava.net/alinglau36/aggbug/269609.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alinglau36/" target="_blank">lau</a> 2009-05-08 14:58 <a href="http://www.blogjava.net/alinglau36/archive/2009/05/08/269609.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>BeanFactory与Application的区别</title><link>http://www.blogjava.net/alinglau36/archive/2009/05/06/269270.html</link><dc:creator>lau</dc:creator><author>lau</author><pubDate>Wed, 06 May 2009 09:27:00 GMT</pubDate><guid>http://www.blogjava.net/alinglau36/archive/2009/05/06/269270.html</guid><wfw:comment>http://www.blogjava.net/alinglau36/comments/269270.html</wfw:comment><comments>http://www.blogjava.net/alinglau36/archive/2009/05/06/269270.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alinglau36/comments/commentRss/269270.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alinglau36/services/trackbacks/269270.html</trackback:ping><description><![CDATA[<div>
<a id="viewpost1_TitleUrl" class="postTitle2" href="../../pdw2009/archive/2007/09/28/149382.html">BeanFactory与Application的区别</a>
</div>
自从年初看了李刚写的那本《Spring2.0宝典》，好久没看过Spring任何资料，对于《Spring2.0宝典》的评价，我只能说一句话垃圾中的垃圾。我已经不敢再买国内作家写的书了。<br />
<p>在Spring中，两个最基本最重要的包是 <tt>org.springframework.beans</tt> 和 <tt>org.springframework.context</tt>. 这两个包中的代码为Spring的<em>反向控制</em> 特性（也叫作<em>依赖注射</em>）提供了基础。 <tt><a href="http://www.springframework.org/docs/api/org/springframework/beans/factory/BeanFactory.html" target="_top">BeanFactory</a></tt>提供了一种先进的配置机制来管理任何种类bean(对象)，这种配置机制考虑到任何一种可能的存储方式。 <a href="http://www.springframework.org/docs/api/org/springframework/context/ApplicationContext.html" target="_top">ApplicationContext</a>建立在BeanFactory之上，并增加了其他的功能,比如更容易同Spring AOP特性整合， 消息资源处理（用于国际化），事件传递，以声明的方式创建ApplicationContext， 可选的父上下文和与应用层相关的上下文（比如<tt>WebApplicationContext</tt>），以及其他方面的增强。 </p>
<p>简而言之，<tt>BeanFactory</tt>提供了配置框架和基本的功能， 而 <tt>ApplicationContext</tt>为
它增加了更强的功能，这些功能中的一些或许更加接近J2EE并且围绕企业级应用。一般来说，ApplicationContext是
BeanFactory的完全超集， 任何BeanFactory功能和行为的描述也同样被认为适用于ApplicationContext</p>
<p>用户有时不能确定BeanFactory和ApplicationContext中哪一个在特定场合下更适合。 通常大部分在J2EE环境的应用中，<em>最好选择使用ApplicationContext</em>，
因为它不仅提供了BeanFactory所有的特性以及它自己附加的特性，而且还提供以声明的方式使用一些功能，
这通常是令人满意的。BeanFactory主要是在非常关注内存使用的情况下
（比如在一个每kb都要计算的applet中）使用，而且你也不需要用到ApplicationContext的所有特性。 </p>
<p>这一章粗略地分为两部分，第一部分包括对BeanFactory和ApplicationContext都适用的一些基本原则。第二部分包括仅仅适用于ApplicationContext的一些特性</p>
<br />
生成BeanFactory的方法<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><span style="color: #000000;">InputStream&nbsp;is&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;FileInputStream(</span><span style="color: #000000;">"</span><span style="color: #000000;">beans.xml</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
XmlBeanFactory&nbsp;factory&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;XmlBeanFactory(is);<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">或者<br />
ClassPathResource res = new ClassPathResource("beans.xml");<br />
XmlBeanFactory factory = new XmlBeanFactory(res);</span></div>
<br />
生成ApplicationContext方法<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98.18%; height: 85px; background-color: #eeeeee;"><span style="color: #000000;">ClassPathXmlApplicationContext&nbsp;appContext&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ClassPathXmlApplicationContext(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;String[]&nbsp;{</span><span style="color: #000000;">"</span><span style="color: #000000;">applicationContext.xml</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">applicationContext-part2.xml</span><span style="color: #000000;">"</span><span style="color: #000000;">});<br />
<br />
<br />
ClassPathXmlApplicationContext&nbsp;appContext&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ClassPathXmlApplicationContext(</span><span style="color: #000000;">""</span><span style="color: #000000;">);</span></div>
<br />
applicationContxt是可以转换成beanFactory的<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><span style="color: #000000;">BeanFactory&nbsp;factory&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(BeanFactory)&nbsp;appContext;</span></div>
<br />
<p>Beans被定义为两种部署模式中的一种：singleton或non-singleton。 （后一种也别叫作prototype，尽管这个名词用的不精确因为它并不是非常适合）。 如果一个bean是singleton形态的，那么就只有一个<em>共享的</em>实例存在， 所有和这个bean定义的id符合的bean请求都会返回这个唯一的、特定的实例。 </p>
<p>如果bean以non-singleton，prototype模式部署的话，对这个bean的每次请求都会<em>创建一个新的bean实例</em>。这对于例如每个user需要一个独立的user对象这样的情况是非常理想的。 </p>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><span style="color: #000000;">&lt;</span><span style="color: #000000;">bean&nbsp;id</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">exampleBean</span><span style="color: #000000;">"</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">examples.ExampleBean</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;singleton</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">false</span><span style="color: #000000;">"</span><span style="color: #000000;">/&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">bean&nbsp;name</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">yetAnotherExample</span><span style="color: #000000;">"</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">examples.ExampleBeanTwo</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;singleton</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">true</span><span style="color: #000000;">"</span><span style="color: #000000;">/&gt;</span></div>
<img src ="http://www.blogjava.net/alinglau36/aggbug/269270.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alinglau36/" target="_blank">lau</a> 2009-05-06 17:27 <a href="http://www.blogjava.net/alinglau36/archive/2009/05/06/269270.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java中的异常处理--转载</title><link>http://www.blogjava.net/alinglau36/archive/2009/04/21/266772.html</link><dc:creator>lau</dc:creator><author>lau</author><pubDate>Tue, 21 Apr 2009 08:02:00 GMT</pubDate><guid>http://www.blogjava.net/alinglau36/archive/2009/04/21/266772.html</guid><wfw:comment>http://www.blogjava.net/alinglau36/comments/266772.html</wfw:comment><comments>http://www.blogjava.net/alinglau36/archive/2009/04/21/266772.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alinglau36/comments/commentRss/266772.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alinglau36/services/trackbacks/266772.html</trackback:ping><description><![CDATA[<font size="2" color="#808080">
Java编程中的异常处理是一个很常见的话题了，几乎任何一门介绍性的Java课程都会提到异常处理。不过，我认为很多人其实并没有真正掌握正确处理异常
情况的方法和策略，最多也就不过了解个大概，知道点概念。本文就对三种不同程度和质量的Java异常处理进行了讨论，所阐述的处理异常的方式按手法的高下
分为： </font><font size="2" color="#808080">好，不好和恶劣三种。</font>
<p><font size="2" color="#808080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  同时向你提供了一些解决这些问题的技巧。 </font></p>
<p><font size="2" color="#808080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  首先解释一些Java异常处理中必须搞清楚的定义和机制。Java语言规范将自Error类或RuntimeException类衍生出来的任何违例都称作&#8220;不可检查&#8221;(Unchecked)异常；其他所有异常则称作&#8220;可检查&#8221;(Checked)异常。 </font></p>
<p><font size="2" color="#808080">所谓可检查异常，是指我们应该自行处理的异常。至于处理的手段，要么加以控制(try catch)，要么通告(throws)他们有可能产生。通常，应捕捉那些已知如何处理的异常，而通告那些不知如何处理的异常。 </font></p>
<p><font size="2" color="#808080">而对那些不可检查异常来说，他们要么在我们的控制之外(Error)，要么是我们首先就不该允许的情况(RuntimeException)。 </font></p>
<p><font size="2" color="#808080">至于异常的指定，Java的规则非常简单：一个方法必须通告自己可能产生的所有可
检查异常。编写自己的方法时，并不一定要通告出方法实际可能产生的每一个异常对象，要想理解什么时候必须要方法的throws丛句来通告异常，就必须知道
对一个异常来说，他只有可能在下面四种情况下才会产生： </font></p>
<p><font size="2" color="#808080">1、调用了可能产生异常的方法。比如BufferedReader类的readLine方法。该方法通告java.io.IOException异常。</font></p>
<p><font size="2" color="#808080">2、侦测到一个错误，并用throw语句产生异常。 </font></p>
<p><font size="2" color="#808080">3、出现一个编程错误。比如a[-1] = 0。 </font></p>
<p><font size="2" color="#808080">4、Java产生内部错误。 </font></p>
<p><font size="2" color="#808080">如果出现头两种情况之一，必须告诉打算使用自己方法的人：假如使用这个方法，可能造成一个异常的产生(即在方法头上使用throws)，一个简单的记忆方法： </font></p>
<p><font size="2" color="#808080">只要含有throw，就要通告throws。如果一个方法必须同时处理多个异常，就必须在头内指出所有异常。就像下例展示的那样，用逗号对他们进行分割： </font></p>
<p><font size="2" color="#808080">1234567 class Animation { public Image loadImage(Strint s)&nbsp;&nbsp;  throws EOFException,MalformedURLException{ 　&#8230;&#8230;&#8230;&#8230; } }<br />
</font></p>
<p><br />
<font size="2" color="#808080">然而，我们不需要通告内部java错误，也不应该通告自RuntimeException衍生出来的异常。 </font></p>
<p><font size="2" color="#ff0000"><strong>好的异常处理 </strong></font></p>
<p><font size="2" color="#808080">好异常处理提供了处理程序错误的统一机制。事实上，Java语言通过向调用者提出
异常警告的方式而显著地提升了软件开发中的异常处理能力。这种方式把Java语言中的&#8220;方法（method）&#8221;进行了扩展和增强，使之包括了自身的错误条
件。下面就让我们看一个例子，这个例子说明了这种情况。 </font></p>
<p><font size="2" color="#808080">以下是FileInputStream构造器之一的原型： </font></p>
<p><font size="2" color="#808080">public FileInputStream(String name) throws FileNotFoundException Java<br />
</font></p>
<p><br />
<font size="2" color="#808080">的方法和构造器必须声明他们在被调用时可能&#8220;扔出&#8221;的异常，采用的关键字就是&#8220;throws&#8221;。这种在方法原型中出现的异常提示增加了编程的可靠性。 </font></p>
<p><font size="2" color="#808080">显而易见，这种方式是向方法的调用者提示了可能出现的异常条件，这样调用者就可以对这些异常作出适当的相应处理。以下代码示意我们是如何捕获并且处理FileNotFoundException 这一异常的： </font></p>
<p><font size="2" color="#808080">1234567891011 try {&nbsp;&nbsp; FileInputStream
fis = new FileInputStream(args[0]);&nbsp;&nbsp;&nbsp;&nbsp; // other code here ...&nbsp;&nbsp; }
catch (FileNotFoundException fnfe) { System.out.println("File: " +
args[0] + " not found. Aborting."); System.exit(1); }<br />
</font></p>
<p><br />
<font size="2" color="#808080">Java异常处理还有其他一些优秀的特性，这就是可检查异常、用户定义异常和在JDK
1.4中推出的新型Java记录API（Java Logging
API）。java.lang.Exception的所有子类都属于可检查异常。可检查异常（checked
exception）是扔出该异常的方法所必须提示的异常，这种异常必须被捕获或者向调用者提示。用户定义异常（User-defined
exceptions）是定制的异常类，这种异常类扩展了java.lang.Exception类。优良的Java程序规定定制异常封装、报告和处理他
们自己独有的情况。最新的Java记录API（logging API）则可以集中记录异常。</font></p>
<p><font size="2" color="#ff0000"><strong>不好的Java异常处理 </strong></font></p>
<p><font size="2" color="#808080">不好的一面包括两种情况：滥用不可检查异常（unchecked exceptions）和滥用catchall构造器等。这两种方式都使得问题变得复杂起来。 </font></p>
<p><font size="2" color="#808080">有一种类别的异常属于RuntimeException的子类，这种异常不会受到
编译器的检查。比如，NullPointerException和
ArrayStoreException就是这种类型异常的实例。程序员可以对RuntimeException进行子类化以回避检查异常的限制，从而便
于产生这些异常的方法为其调用者所使用。 </font></p>
<p><font size="2" color="#808080">专业的开发团队应当只允许在很少的情况下才可以这样做。 </font></p>
<p><font size="2" color="#808080">第二种异常处理的陋习是catchall构造器。所谓的&#8220;catchall 构造器&#8221;就是一种异常捕获代码模块，它可以处理所有扔给它的可能异常。 </font></p>
<p><font size="2" color="#808080">以下是catchall处理器的实例： </font></p>
<p><font size="2" color="#808080">123456789&nbsp;&nbsp;  try { // code here with checked exceptions } catch (Throwable t) { t.printStackTrace(); }<br />
</font></p>
<p><br />
<font size="2" color="#808080">我得承认，我自己在编写一般程序的时候就曾经用过这种技术；但是，在编写关键程序的时候这种类型的构造器一定要避免使用，除非他们被授权可以和中央错误处理器联合使用才可以这样做。 </font></p>
<p><font size="2" color="#808080">除此之外，catchall构造器不过只是一种通过避免错误处理而加快编程进度的机制。 </font></p>
<p><font size="2" color="#808080">异常处理的一个不足之处是难以采用优良的错误处理策略。从低容内存状态恢复、写入错误和算法错误等异常情况都不是轻易能得到解决的。你可以尝试一下循环、垃圾收集和提醒用户等常用技术来应付以上的局面。 </font></p>
<p><font size="2"><font color="#ff0000"><strong>恶劣的处理方法</strong> </font></font></p>
<p><font size="2" color="#808080">和许多Java特性及其API类似，Java的异常处理机制也有&#8220;霸王硬上弓&#8221;类的滑稽错误。比方说，为了扔出某个异常竟然毫不犹豫地用&#8220;new&#8221;关键词为其分配内存就是这样的例子。 </font></p>
<p><font size="2" color="#808080">我自己不知道有多少次就因为犯了这种错误而在严肃的编译器面前屡屡碰壁。在这种情况下，我们其实都是在伺候语言而不是让语言为我们所用。还有我们碰到的OutOfMemoryErrors就是异常处理的缺陷。这一处理过程是： </font></p>
<p><font size="2" color="#808080">使用finally模块关闭文件，解析异常以得到出现问题的方法和代码行。在这一
过程之内最大的缺陷是需要捕获OutOfMemoryError，而这一异常却并不是可检查异常！想想看，内存耗尽是相当常见的情况。任何与内存使用状态
紧密相关的程序都应当捕获和处理这一错误。 </font></p>
<p><font size="2"><font color="#ff0000"><strong>使用异常时的一些建议</strong> </font></font></p>
<p><font size="2" color="#808080">1、异常控制的设计宗旨并不是用来代替一些简单的测试。只有在异常情况下才使用异常！ </font></p>
<p><font size="2" color="#808080">2、不要过分细化异常。不要在每个语句上都加上异常处理，最好将整个任务都放在try块内。如果其中有一项操作失败，可以随即放弃任务。 </font></p>
<p><font size="2" color="#808080">3、不要&#8220;压制&#8221;异常。对于需要通告异常的方法，我们可以改用捕捉的方法来将异常强行关闭，如果真的出现异常，那个异常会被&#8220;静悄悄&#8221;的忽略。如果觉得产生的异常会非常重要，就必须多费些功夫，对其进行正确的控制。 </font></p>
<p><font size="2" color="#808080">4、不要介意异常的传递。如果调用的方法会产生异常，比如readLine方法，他们天生就能捕捉自己可能产生的异常，在这种情况下，一种更好地做法是将这些异常传递出去，而不是自己动手来捕捉它。</font></p>
<img src ="http://www.blogjava.net/alinglau36/aggbug/266772.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alinglau36/" target="_blank">lau</a> 2009-04-21 16:02 <a href="http://www.blogjava.net/alinglau36/archive/2009/04/21/266772.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 配置Spring数据源</title><link>http://www.blogjava.net/alinglau36/archive/2009/04/17/266167.html</link><dc:creator>lau</dc:creator><author>lau</author><pubDate>Fri, 17 Apr 2009 07:29:00 GMT</pubDate><guid>http://www.blogjava.net/alinglau36/archive/2009/04/17/266167.html</guid><wfw:comment>http://www.blogjava.net/alinglau36/comments/266167.html</wfw:comment><comments>http://www.blogjava.net/alinglau36/archive/2009/04/17/266167.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alinglau36/comments/commentRss/266167.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alinglau36/services/trackbacks/266167.html</trackback:ping><description><![CDATA[配置一个数据源&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;Spring在第三方依赖包中包含了两个数据源的实现类包，其一是Apache的DBCP，其二是&nbsp;C3P0。可以在Spring配置文件中利用这两者中任何一个配置数据源。<br />
<br />
&nbsp;DBCP数据源&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;DBCP
类包位于&nbsp;/lib/jakarta-commons/commons-dbcp.jar，DBCP是一个依赖&nbsp;Jakarta&nbsp;commons-
pool对象池机制的数据库连接池，所以在类路径下还必须包括/lib/jakarta-&nbsp;commons/commons-pool.jar。下面是使
用DBCP配置MySql数据源的配置片断：<br />
<br />
xml&nbsp;代码<br />
<div>
<div>
<div><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div>
</div>
<ol start="1">
    <li>&lt;bean&nbsp;id="dataSource"&nbsp;class="org.apache.commons.dbcp.BasicDataSource"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;destroy-method="close"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="driverClassName"&nbsp;value="com.mysql.jdbc.Driver"&nbsp;/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="url"&nbsp;value="jdbc:mysql://localhost:3309/sampledb"&nbsp;/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="username"&nbsp;value="root"&nbsp;/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="password"&nbsp;value="1234"&nbsp;/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&lt;/bean&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
</ol>
</div>
<textarea style="display: none;" name="code" class="xml">&lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"&gt;
&lt;property name="driverClassName" value="com.mysql.jdbc.Driver" /&gt;
&lt;property name="url" value="jdbc:mysql://localhost:3309/sampledb" /&gt;
&lt;property name="username" value="root" /&gt;
&lt;property name="password" value="1234" /&gt;
&lt;/bean&gt;
</textarea><br />
BasicDataSource提供了close()方法关闭数据源，所以必须设定destroy-method=&#8221;close&#8221;属性，&nbsp;以便Spring容器关闭时，数据源能够正常关闭。除以上必须的数据源属性外，还有一些常用的属性：&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;defaultAutoCommit：设置从数据源中返回的连接是否采用自动提交机制，默认值为&nbsp;true；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;defaultReadOnly：设置数据源是否仅能执行只读操作，&nbsp;默认值为&nbsp;false；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;maxActive：最大连接数据库连接数，设置为0时，表示没有限制；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;maxIdle：最大等待连接中的数量，设置为0时，表示没有限制；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;maxWait：最大等待秒数，单位为毫秒，&nbsp;超过时间会报出错误信息；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;validationQuery：用于验证连接是否成功的查询SQL语句，SQL语句必须至少要返回一行数据，&nbsp;如你可以简单地设置为：&#8220;select&nbsp;count(*)&nbsp;from&nbsp;user&#8221;；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;removeAbandoned：是否自我中断，默认是&nbsp;false&nbsp;；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;removeAbandonedTimeout：几秒后数据连接会自动断开，在removeAbandoned为true，提供该值；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;logAbandoned：是否记录中断事件，&nbsp;默认为&nbsp;false；&nbsp;<br />
<br />
C3P0数据源&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;C3P0
是一个开放源代码的JDBC数据源实现项目，它在lib目录中与Hibernate一起发布，实现了JDBC3和JDBC2扩展规范说明
的&nbsp;Connection&nbsp;和Statement&nbsp;池。C3P0类包位于/lib/c3p0/c3p0-0.9.0.4.jar。下面是使用C3P0配置
一个&nbsp;oracle数据源：<br />
<br />
xml&nbsp;代码<br />
<div>
<div>
<div><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div>
</div>
<ol start="1">
    <li>&lt;bean&nbsp;id="dataSource"&nbsp;class="com.mchange.v2.c3p0.ComboPooledDataSource"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;destroy-method="close"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="driverClass"&nbsp;value="&nbsp;oracle.jdbc.driver.OracleDriver&nbsp;"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="jdbcUrl"&nbsp;value="&nbsp;jdbc:oracle:thin:@localhost:1521:ora9i&nbsp;"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="user"&nbsp;value="admin"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="password"&nbsp;value="1234"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&lt;/bean&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
</ol>
</div>
<textarea style="display: none;" name="code" class="xml">&lt;bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close"&gt;
&lt;property name="driverClass" value=" oracle.jdbc.driver.OracleDriver "/&gt;
&lt;property name="jdbcUrl" value=" jdbc:oracle:thin:@localhost:1521:ora9i "/&gt;
&lt;property name="user" value="admin"/&gt;
&lt;property name="password" value="1234"/&gt;
&lt;/bean&gt;
</textarea><br />
ComboPooledDataSource和BasicDataSource一样提供了一个用于关闭数据源的close()方法，这样我们就可以保证Spring容器关闭时数据源能够成功释放。&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;C3P0拥有比DBCP更丰富的配置属性，通过这些属性，可以对数据源进行各种有效的控制：&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;acquireIncrement：当连接池中的连接用完时，C3P0一次性创建新连接的数目；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;acquireRetryAttempts：定义在从数据库获取新连接失败后重复尝试获取的次数，默认为30；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;acquireRetryDelay：两次连接中间隔时间，单位毫秒，默认为1000；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;autoCommitOnClose：连接关闭时默认将所有未提交的操作回滚。默认为false；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;automaticTestTable：&nbsp;C3P0
将建一张名为Test的空表，并使用其自带的查询语句进行测试。如果定义了这个参数，那么属性preferredTestQuery将被忽略。你&nbsp;不能在
这张Test表上进行任何操作，它将中为C3P0测试所用，默认为null；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;breakAfterAcquireFailure：获取
连接失败将会引起所有等待获取连接的线程抛出异常。但是数据源仍有效保留，并在下次调&nbsp;&nbsp;&nbsp;用getConnection()的时候继续尝试获取连接。如
果设为true，那么在尝试获取连接失败后该数据源将申明已断开并永久关闭。默认为&nbsp;false；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;checkoutTimeout：当连接池用完时客户端调用getConnection()后等待获取新连接的时间，超时后将抛出SQLException，如设为0则无限期等待。单位毫秒，默认为0；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;connectionTesterClassName：&nbsp;通
过实现ConnectionTester或QueryConnectionTester的类来测试连接，类名需设置为全限定名。默认
为&nbsp;com.mchange.v2.C3P0.impl.DefaultConnectionTester；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;idleConnectionTestPeriod：隔多少秒检查所有连接池中的空闲连接，默认为0表示不检查；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;initialPoolSize：初始化时创建的连接数，应在minPoolSize与maxPoolSize之间取值。默认为3；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;maxIdleTime：最大空闲时间，超过空闲时间的连接将被丢弃。为0或负数则永不丢弃。默认为0；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;maxPoolSize：连接池中保留的最大连接数。默认为15；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;maxStatements：JDBC
的标准参数，用以控制数据源内加载的PreparedStatement数量。但由于预缓存的Statement属&nbsp;于单个Connection而不是整
个连接池。所以设置这个参数需要考虑到多方面的因素，如果maxStatements与&nbsp;maxStatementsPerConnection均为0，
则缓存被关闭。默认为0；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;maxStatementsPerConnection：连接池内单个连接所拥有的最大缓存Statement数。默认为0；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;numHelperThreads：C3P0是异步操作的，缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能，通过多线程实现多个操作同时被执行。默认为3；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;preferredTestQuery：定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个参数能显著提高测试速度。测试的表必须在初始数据源的时候就存在。默认为null；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;propertyCycle：&nbsp;用户修改系统配置参数执行前最多等待的秒数。默认为300；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;testConnectionOnCheckout：
因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的时候都&nbsp;将校验其有效性。建议使用
idleConnectionTestPeriod或automaticTestTable&nbsp;<br />
等方法来提升连接测试的性能。默认为false；&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;testConnectionOnCheckin：如果设为true那么在取得连接的同时将校验连接的有效性。默认为false。&nbsp;<br />
<br />
读配置文件的方式引用属性：&nbsp;<br />
<div>
<div>
<div><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div>
</div>
<ol start="1">
    <li>&lt;bean&nbsp;id="propertyConfigurer"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="location"&nbsp;value="/WEB-INF/jdbc.properties"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&lt;/bean&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&lt;bean&nbsp;id="dataSource"&nbsp;class="org.apache.commons.dbcp.BasicDataSource"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;destroy-method="close"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="driverClassName"&nbsp;value="${jdbc.driverClassName}"&nbsp;/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="url"&nbsp;value="${jdbc.url}"&nbsp;/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="username"&nbsp;value="${jdbc.username}"&nbsp;/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="password"&nbsp;value="${jdbc.password}"&nbsp;/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&lt;/bean&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
</ol>
</div>
<textarea style="display: none;" name="code" class="xml">&lt;bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&gt;
&lt;property name="location" value="/WEB-INF/jdbc.properties"/&gt;
&lt;/bean&gt;
&lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"&gt;
&lt;property name="driverClassName" value="${jdbc.driverClassName}" /&gt;
&lt;property name="url" value="${jdbc.url}" /&gt;
&lt;property name="username" value="${jdbc.username}" /&gt;
&lt;property name="password" value="${jdbc.password}" /&gt;
&lt;/bean&gt;
</textarea><br />
&nbsp;&nbsp;&nbsp;&nbsp;在jdbc.properties属性文件中定义属性值：&nbsp;<br />
&nbsp;&nbsp;&nbsp;jdbc.driverClassName=&nbsp;com.mysql.jdbc.Driver&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;jdbc.url=&nbsp;jdbc:mysql://localhost:3309/sampledb&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;jdbc.username=root&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;jdbc.password=1234&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;提示&nbsp;经常有开发者在${xxx}的前后不小心键入一些空格，这些空格字符将和变量合并后作为属性的值。如：&nbsp;的属性配置项，在前后都有空格，被解析后，username的值为&#8220;&nbsp;1234&nbsp;&#8221;，这将造成最终的错误，因此需要特别小心。<br />
<br />
&nbsp;获取JNDI数据源&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;如
果应用配置在高性能的应用服务器（如WebLogic或Websphere等）上，我们可能更希望使用应用服务器本身提供的数据源。应用服务器的数据
源&nbsp;使用JNDI开放调用者使用，Spring为此专门提供引用JNDI资源的JndiObjectFactoryBean类。下面是一个简单的配置：<br />
<br />
xml&nbsp;代码<br />
<div>
<div>
<div><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div>
</div>
<ol start="1">
    <li>&lt;bean&nbsp;id="dataSource"&nbsp;class="org.springframework.jndi.JndiObjectFactoryBean"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="jndiName"&nbsp;value="java:comp/env/jdbc/bbt"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&lt;/bean&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
</ol>
</div>
<textarea style="display: none;" name="code" class="xml">&lt;bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"&gt;
&lt;property name="jndiName" value="java:comp/env/jdbc/bbt"/&gt;
&lt;/bean&gt;
</textarea><br />
通过jndiName指定引用的JNDI数据源名称。&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;Spring&nbsp;2.0为获取J2EE资源提供了一个jee命名空间，通过jee命名空间，可以有效地简化J2EE资源的引用。下面是使用jee命名空间引用JNDI数据源的配置：&nbsp;<br />
<br />
xml&nbsp;代码<br />
<div>
<div>
<div><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div>
</div>
<ol start="1">
    <li>&lt;beans&nbsp;xmlns=http://www.springframework.org/schema/beans&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>xmlns:jee=http://www.springframework.org/schema/jee&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>xsi:schemaLocation="http://www.springframework.org/schema/beans&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>http://www.springframework.org/schema/beans/spring-beans-2.0.xsd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>http://www.springframework.org/schema/jee&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>http://www.springframework.org/schema/jee/spring-jee-2.0.xsd"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&lt;jee:jndi-lookup&nbsp;id="dataSource"&nbsp;jndi-name="&nbsp;java:comp/env/jdbc/bbt"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&lt;/beans&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
</ol>
</div>
<textarea style="display: none;" name="code" class="xml">&lt;beans xmlns=http://www.springframework.org/schema/beans
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xmlns:jee=http://www.springframework.org/schema/jee
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-2.0.xsd"&gt;
&lt;jee:jndi-lookup id="dataSource" jndi-name=" java:comp/env/jdbc/bbt"/&gt;
&lt;/beans&gt;
</textarea><br />
Spring的数据源实现类&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;Spring本身也提供了一个简单的数据源实现类
DriverManagerDataSource&nbsp;，它位于org.springframework.jdbc.datasource包中。这个类实现了
javax.sql.DataSource接口，但&nbsp;它并没有提供池化连接的机制，每次调用getConnection()获取新连接时，只是简单地创建
一个新的连接。因此，这个数据源类比较适合在单元测试&nbsp;或简单的独立应用中使用，因为它不需要额外的依赖类。&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下面，我们来看一下DriverManagerDataSource的简单使用：当然，我们也可以通过配置的方式直接使用DriverManagerDataSource。<br />
<br />
java&nbsp;代码<br />
<div>
<div>
<div><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div>
</div>
<ol start="1">
    <li>DriverManagerDataSource&nbsp;ds&nbsp;=&nbsp;new&nbsp;DriverManagerDataSource&nbsp;();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>ds.setDriverClassName("com.mysql.jdbc.Driver");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>ds.setUrl("jdbc:mysql://localhost:3309/sampledb");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>ds.setUsername("root");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>ds.setPassword("1234");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>Connection&nbsp;actualCon&nbsp;=&nbsp;ds.getConnection();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
</ol>
</div>
<textarea style="display: none;" name="code" class="java">DriverManagerDataSource ds = new DriverManagerDataSource ();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3309/sampledb");
ds.setUsername("root");
ds.setPassword("1234");
Connection actualCon = ds.getConnection();
</textarea><br />
小结&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;不管采用何种持久化技术，都需要定义数据源。Spring附带了两个数据源的实现类包，你可以自行
选择进行定义。在实际部署时，我们可能会直接采用应用服&nbsp;务器本身提供的数据源，这时，则可以通过JndiObjectFactoryBean或jee命
名空间引用JNDI中的数据源。&nbsp;<br />
<br />
DBCP与C3PO配置的区别：<br />
<br />
C3PO&nbsp;：<br />
xml&nbsp;代码<br />
<div>
<div>
<div><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div>
</div>
<ol start="1">
    <li>&lt;bean&nbsp;id="dataSource"&nbsp;class="com.mchange.v2.c3p0.ComboPooledDataSource"&nbsp;destroy-method="close"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="driverClass"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;oracle.jdbc.driver.OracleDrivervalue&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="jdbcUrl"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;jdbc:oracle:thin:@10.10.10.6:1521:DataBaseNamevalue&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="user"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;testAdminvalue&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="password"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;123456value&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&lt;/bean&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
</ol>
</div>
<textarea style="display: none;" name="code" class="xml">&lt;bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"&gt;
&lt;property name="driverClass"&gt;
&lt;value&gt;oracle.jdbc.driver.OracleDrivervalue&gt;
&lt;/property&gt;
&lt;property name="jdbcUrl"&gt;
&lt;value&gt;jdbc:oracle:thin:@10.10.10.6:1521:DataBaseNamevalue&gt;
&lt;/property&gt;
&lt;property name="user"&gt;
&lt;value&gt;testAdminvalue&gt;
&lt;/property&gt;
&lt;property name="password"&gt;
&lt;value&gt;123456value&gt;
&lt;/property&gt;
&lt;/bean&gt;
</textarea><br />
&nbsp;DBCP：<br />
<br />
xml&nbsp;代码<br />
<div>
<div>
<div><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.xyhot.com/article.asp?id=274#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div>
</div>
<ol start="1">
    <li>&lt;bean&nbsp;id="dataSource"&nbsp;class="org.apache.commons.dbcp.BasicDataSource"&nbsp;destroy-method="close"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="driverClassName"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;oracle.jdbc.driver.OracleDrivervalue&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="url"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;jdbc:oracle:thin:@10.10.10.6:1521:DataBaseNamevalue&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="username"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;testAdminvalue&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="password"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;123456value&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
    <li>&lt;/bean&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
</ol>
</div>
<textarea style="display: none;" name="code" class="xml">&lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"&gt;
&lt;property name="driverClassName"&gt;
&lt;value&gt;oracle.jdbc.driver.OracleDrivervalue&gt;
&lt;/property&gt;
&lt;property name="url"&gt;
&lt;value&gt;jdbc:oracle:thin:@10.10.10.6:1521:DataBaseNamevalue&gt;
&lt;/property&gt;
&lt;property name="username"&gt;
&lt;value&gt;testAdminvalue&gt;
&lt;/property&gt;
&lt;property name="password"&gt;
&lt;value&gt;123456value&gt;
&lt;/property&gt;
&lt;/bean</textarea><br />
<br />
<img src="http://www.xyhot.com/images/icon_trackback.gif" style="margin: 0px 2px -4px 0px;" alt="" /><strong>引用地址:</strong> <a href="http://www.xyhot.com/trackback.asp?tbID=274" target="_blank">http://www.xyhot.com/trackback.asp?tbID=274</a>
<img src ="http://www.blogjava.net/alinglau36/aggbug/266167.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alinglau36/" target="_blank">lau</a> 2009-04-17 15:29 <a href="http://www.blogjava.net/alinglau36/archive/2009/04/17/266167.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 泛型</title><link>http://www.blogjava.net/alinglau36/archive/2009/03/05/257984.html</link><dc:creator>lau</dc:creator><author>lau</author><pubDate>Thu, 05 Mar 2009 05:53:00 GMT</pubDate><guid>http://www.blogjava.net/alinglau36/archive/2009/03/05/257984.html</guid><wfw:comment>http://www.blogjava.net/alinglau36/comments/257984.html</wfw:comment><comments>http://www.blogjava.net/alinglau36/archive/2009/03/05/257984.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/alinglau36/comments/commentRss/257984.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alinglau36/services/trackbacks/257984.html</trackback:ping><description><![CDATA[<div>泛型是JAVA SE
1.5的新特性，泛型的本质是参数化类型，也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中，分别称为泛型类、泛型接口、泛型方法。</div>
<div>&nbsp;</div>
<div>JAVA语言引入泛型的好处是安全简单。</div>
<div>&nbsp;</div>
<div>在JAVA SE
1.5之前，没有泛型的情况的下，通过对类型Object的引用来实现参数的&#8220;任意化&#8221;，&#8220;任意化&#8221;带来的缺点是要做显式的强制类型转换，而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况，编译器可能不提示错误，在运行的时候才出现异常，这是一个安全隐患。</div>
<div>&nbsp;</div>
<div>泛型的好处是在编译的时候检查类型安全，并且所有的强制转换都是自动和隐式的，提高代码的重用率。</div>
<div>&nbsp;</div>
<div><strong>泛型在使用中还有一些规则和限制：</strong></div>
<div>1、泛型的类型参数只能是类类型（包括自定义类），不能是简单类型。</div>
<div>2、同一种泛型可以对应多个版本（因为参数类型是不确定的），不同版本的泛型类实例是不兼容的。</div>
<div>3、泛型的类型参数可以有多个。</div>
<div>4、泛型的参数类型可以使用extends语句，例如&lt;T extends superclass&gt;。习惯上成为&#8220;有界类型&#8221;。</div>
<div>5、泛型的参数类型还可以是通配符类型。例如Class&lt;?&gt; classType =
Class.forName(java.lang.String);</div>
<div>&nbsp;</div>
<div>泛型还有接口、方法等等，内容很多，需要花费一番功夫才能理解掌握并熟练应用。在此给出我曾经了解泛型时候写出的两个例子（根据看的印象写的），实现同样的功能，一个使用了泛型，一个没有使用，通过对比，可以很快学会泛型的应用，学会这个基本上学会了泛型70%的内容。</div>
<div>&nbsp;</div>
<div>估计你快等不及了，现在就贴出源码：</div>
<div>&nbsp;</div>
<div><strong><font color="#ff0000">例子一：使用了泛型</font></strong></div>
<div>&nbsp;</div>
<div>public class Gen&lt;T&gt; {</div>
<div>&nbsp;&nbsp;&nbsp; private T ob;&nbsp;&nbsp; //定义泛型成员变量</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; public Gen(T ob) {</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.ob = ob;</div>
<div>&nbsp;&nbsp;&nbsp; }</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; public T getOb() {</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ob;</div>
<div>&nbsp;&nbsp;&nbsp; }</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; public void setOb(T ob) {</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.ob = ob;</div>
<div>&nbsp;&nbsp;&nbsp; }</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; public void showTyep() {</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("T的实际类型是: " + ob.getClass().getName());</div>
<div>&nbsp;&nbsp;&nbsp; }</div>
<div>}</div>
<div>&nbsp;</div>
<div>public class GenDemo {</div>
<div>&nbsp;&nbsp;&nbsp; public static void main(String[] args){</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //定义泛型类Gen的一个Integer版本</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Gen&lt;Integer&gt; intOb=new Gen&lt;Integer&gt;(88);</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intOb.showTyep();</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i= intOb.getOb();</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("value= " + i);</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("----------------------------------");</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //定义泛型类Gen的一个String版本</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Gen&lt;String&gt; strOb=new Gen&lt;String&gt;("Hello Gen!");</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strOb.showTyep();</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s=strOb.getOb();</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("value= " + s);</div>
<div>&nbsp;&nbsp;&nbsp; }</div>
<div>}</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><strong><font color="#ff0000">例子二：没有使用泛型</font></strong></div>
<div>&nbsp;</div>
<div>public class Gen2 {</div>
<div>&nbsp;&nbsp;&nbsp; private Object ob;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //定义一个通用类型成员</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; public Gen2(Object ob) {</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.ob = ob;</div>
<div>&nbsp;&nbsp;&nbsp; }</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; public Object getOb() {</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ob;</div>
<div>&nbsp;&nbsp;&nbsp; }</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; public void setOb(Object ob) {</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.ob = ob;</div>
<div>&nbsp;&nbsp;&nbsp; }</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; public void showTyep() {</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("T的实际类型是: " + ob.getClass().getName());</div>
<div>&nbsp;&nbsp;&nbsp; }</div>
<div>}</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>public class GenDemo2 {</div>
<div>&nbsp;&nbsp;&nbsp; public static void main(String[] args) {</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //定义类Gen2的一个Integer版本</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Gen2 intOb = new Gen2(new Integer(88));</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intOb.showTyep();</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i = (Integer) intOb.getOb();</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("value= " + i);</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("----------------------------------");</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //定义类Gen2的一个String版本</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Gen2 strOb = new Gen2("Hello Gen!");</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strOb.showTyep();</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s = (String) strOb.getOb();</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("value= " + s);</div>
<div>&nbsp;&nbsp;&nbsp; }</div>
<div>}</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><strong><font color="#ff0000">运行结果：</font></strong></div>
<div>&nbsp;</div>
<div>两个例子运行Demo结果是相同的,控制台输出结果如下：</div>
<div>&nbsp;</div>
<div><font style="background-color: rgb(0, 0, 0);" color="#fffafa">T的实际类型是:
java.lang.Integer</font></div>
<div><font style="background-color: rgb(0, 0, 0);" color="#fffafa">value=
88</font></div>
<div><font style="background-color: rgb(0, 0, 0);" color="#fffafa">----------------------------------</font></div>
<div><font style="background-color: rgb(0, 0, 0);" color="#fffafa">T的实际类型是:
java.lang.String</font></div>
<div><font style="background-color: rgb(0, 0, 0);" color="#fffafa">value= Hello
Gen!</font></div>
<div>&nbsp;</div>
<div><font style="background-color: rgb(0, 0, 0);" color="#fffafa">Process finished with
exit code 0</font></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>看明白这个，以后基本的泛型应用和代码阅读就不成问题了。</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<p>本文出自 &#8220;<a href="http://lavasoft.blog.51cto.com/">熔 岩</a>&#8221; 博客</p>
<br />
http://lavasoft.blog.51cto.com/62575/42400<br />
<img src ="http://www.blogjava.net/alinglau36/aggbug/257984.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alinglau36/" target="_blank">lau</a> 2009-03-05 13:53 <a href="http://www.blogjava.net/alinglau36/archive/2009/03/05/257984.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Collection List Set Map 区别</title><link>http://www.blogjava.net/alinglau36/archive/2009/03/04/257746.html</link><dc:creator>lau</dc:creator><author>lau</author><pubDate>Wed, 04 Mar 2009 03:51:00 GMT</pubDate><guid>http://www.blogjava.net/alinglau36/archive/2009/03/04/257746.html</guid><wfw:comment>http://www.blogjava.net/alinglau36/comments/257746.html</wfw:comment><comments>http://www.blogjava.net/alinglau36/archive/2009/03/04/257746.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alinglau36/comments/commentRss/257746.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alinglau36/services/trackbacks/257746.html</trackback:ping><description><![CDATA[<table style="table-layout: fixed;">
    <tbody>
        <tr>
            <td>
            <div class="cnt" id="blog_text"><span style="font-size: 18pt;"><a title="永久链接:Collection List Set Map 区别记忆" href="http://gwshuai.javaeye.com/blog/99373"><font size="1"><font color="#ff0000"><strong>Collection List Set Map
            <span>区别</span></strong></font></font></a><font size="1"> </font></span>
            <table style="border: 1pt solid windowtext;" border="1" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td style="padding: 0cm; width: 110.05pt;" colspan="2" valign="top" width="147">
                        <br />
                        </td>
                        <td style="padding: 0cm; width: 180.85pt;" valign="top" width="241">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">有序否</font></span></div>
                        </td>
                        <td style="padding: 0cm; width: 130.6pt;" valign="top" width="174">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">允许元素重复否</font></span></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="padding: 0cm; width: 110.05pt;" colspan="2" valign="top" width="147">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">Collection</font></span></div>
                        </td>
                        <td style="padding: 0cm; width: 180.85pt;" valign="top" width="241">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">否</font></span></div>
                        </td>
                        <td style="padding: 0cm; width: 130.6pt;" valign="top" width="174">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">是</font></span></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="padding: 0cm; width: 110.05pt;" colspan="2" valign="top" width="147">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">List</font></span></div>
                        </td>
                        <td style="padding: 0cm; width: 180.85pt;" valign="top" width="241">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">是</font></span></div>
                        </td>
                        <td style="padding: 0cm; width: 130.6pt;" valign="top" width="174">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">是</font></span></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="padding: 0cm 5.4pt; width: 41.55pt;" rowspan="3" width="55">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">Set</font></span></div>
                        </td>
                        <td style="padding: 0cm; width: 68.5pt;" valign="top" width="91">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">AbstractSet</font></span></div>
                        </td>
                        <td style="padding: 0cm; width: 180.85pt;" rowspan="2" width="241">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">否</font></span></div>
                        </td>
                        <td style="padding: 0cm; width: 130.6pt;" rowspan="3" width="174">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">否</font></span></div>
                        </td>
                    </tr>
                    <tr style="height: 5.25pt;">
                        <td style="padding: 0cm 5.4pt; width: 68.5pt; height: 5.25pt;" valign="top" width="91">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">HashSet</font></span></div>
                        </td>
                    </tr>
                    <tr style="height: 5.25pt;">
                        <td style="padding: 0cm 5.4pt; width: 68.5pt; height: 5.25pt;" valign="top" width="91">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">TreeSet</font></span></div>
                        </td>
                        <td style="padding: 0cm; width: 180.85pt; height: 5.25pt;" valign="top" width="241">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">是（用二叉树排序）</font></span></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="padding: 0cm 5.4pt; width: 41.55pt;" rowspan="3" valign="top" width="55">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">Map</font></span></div>
                        </td>
                        <td style="padding: 0cm; width: 68.5pt;" valign="top" width="91">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">AbstractMap</font></span></div>
                        </td>
                        <td style="padding: 0cm; width: 180.85pt;" rowspan="2" width="241">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">否</font></span></div>
                        </td>
                        <td style="padding: 0cm; width: 130.6pt;" rowspan="3" valign="top" width="174">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">使用key-value来映射和存储数据，Key必须惟一，value可以重复</font></span></div>
                        </td>
                    </tr>
                    <tr style="height: 5.25pt;">
                        <td style="padding: 0cm 5.4pt; width: 68.5pt; height: 5.25pt;" valign="top" width="91">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">HashMap</font></span></div>
                        </td>
                    </tr>
                    <tr style="height: 5.25pt;">
                        <td style="padding: 0cm 5.4pt; width: 68.5pt; height: 5.25pt;" valign="top" width="91">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">TreeMap</font></span></div>
                        </td>
                        <td style="padding: 0cm; width: 180.85pt; height: 5.25pt;" valign="top" width="241">
                        <div align="left"><span style="font-size: 12pt;"><font size="1">是（用二叉树排序）</font></span></div>
                        </td>
                    </tr>
                </tbody>
            </table>
            <div><font size="1"><span style="font-size: 12pt;">线性表，链表，哈希表是常用的数据结构，在进行</span><span style="font-size: 12pt;">Java</span><span style="font-size: 12pt;">开发时，</span><span style="font-size: 12pt;">JDK</span><span style="font-size: 12pt;">已经为我们提供了一系列相应的类来实现基本的数据结构。这些类均在</span><span style="font-size: 12pt;">java.util</span><span style="font-size: 12pt;">包中。本文试图通过简单的描述，向读者阐述各个类的作用以及如何正确使用这些类。</span></font><span style="font-size: 12pt;"><br />
            <font size="1">Collection<br />
            </font></span><span style="font-size: 12pt;"><font size="1">├</font></span><font size="1"><span style="font-size: 12pt;">List<br />
            </span><span style="font-size: 12pt;">│├</span></font><font size="1"><span style="font-size: 12pt;">LinkedList<br />
            </span><span style="font-size: 12pt;">│├</span></font><font size="1"><span style="font-size: 12pt;">ArrayList<br />
            </span><span style="font-size: 12pt;">│└</span></font><font size="1"><span style="font-size: 12pt;">Vector<br />
            </span><span style="font-size: 12pt;">│</span><span style="font-size: 12pt;">　</span><span style="font-size: 12pt;">└</span></font><font size="1"><span style="font-size: 12pt;">Stack<br />
            </span><span style="font-size: 12pt;">└</span></font><font size="1"><span style="font-size: 12pt;">Set<br />
            Map<br />
            </span><span style="font-size: 12pt;">├</span></font><font size="1"><span style="font-size: 12pt;">Hashtable<br />
            </span><span style="font-size: 12pt;">├</span></font><font size="1"><span style="font-size: 12pt;">HashMap<br />
            </span><span style="font-size: 12pt;">└</span></font><font size="1"><span style="font-size: 12pt;">WeakHashMap<br />
            <strong><font color="#ff0000">Co</font></strong></span><strong><font color="#ff0000"><span style="font-size: 12pt;">llection</span><span style="font-size: 12pt;">接口</span></font></strong></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">是最基本的集合接口，一个</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">代表一组</span><span style="font-size: 12pt;">Object</span><span style="font-size: 12pt;">，即</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">的元素（</span><span style="font-size: 12pt;">Elements</span><span style="font-size: 12pt;">）。一些</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">允许相同的元素而另一些不行。一些能排序而另一些不行。</span><span style="font-size: 12pt;">Java SDK</span><span style="font-size: 12pt;">不提供直接继承自</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">的类，</span><span style="font-size: 12pt;">Java
            SDK</span><span style="font-size: 12pt;">提供的类都是继承自</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">的</span><span style="font-size: 12pt;">&#8220;</span><span style="font-size: 12pt;">子接口</span><span style="font-size: 12pt;">&#8221;</span><span style="font-size: 12pt;">如</span><span style="font-size: 12pt;">List</span><span style="font-size: 12pt;">和</span><span style="font-size: 12pt;">Set</span><span style="font-size: 12pt;">。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　所有实现</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">接口的类都必须提供两个标准的构造函数：无参数的构造函数用于创建一个空的</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">，有一个</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">参数的构造函数用于创建一个新的</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">，这个新的</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">与传入的</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">有相同的元素。后一个构造函数允许用户复制一个</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　如何遍历</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">中的每一个元素？不论</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">的实际类型如何，它都支持一个</span><span style="font-size: 12pt;">iterator()</span><span style="font-size: 12pt;">的方法，该方法返回一个迭代子，使用该迭代子即可逐一访问</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">中每一个元素。典型的用法如下：</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　　　</span><span style="font-size: 12pt;">Iterator it =
            collection.iterator(); // </span><span style="font-size: 12pt;">获得一个迭代子</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　　　</span></font><font size="1"><span style="font-size: 12pt;">while(it.hasNext()) { <br />
            </span><span style="font-size: 12pt;">　　　　　　</span><span style="font-size: 12pt;">Object obj =
            it.next(); // </span><span style="font-size: 12pt;">得到下一个元素</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　　　</span></font><font size="1"><span style="font-size: 12pt;">} <br />
            </span><span style="font-size: 12pt;">　　由</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">接口派生的两个接口是</span><span style="font-size: 12pt;">List</span><span style="font-size: 12pt;">和</span><span style="font-size: 12pt;">Set</span><span style="font-size: 12pt;">。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            <strong><font color="#ff0000">List</font></strong></span><span style="font-size: 12pt;"><strong><font color="#ff0000">接口</font></strong></span></font><font size="1"><span style="font-size: 12pt;"> <br />
            List</span><span style="font-size: 12pt;">是有序的</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">，使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引（元素在</span><span style="font-size: 12pt;">List</span><span style="font-size: 12pt;">中的位置，类似于数组下标）来访问</span><span style="font-size: 12pt;">List</span><span style="font-size: 12pt;">中的元素，这类似于</span><span style="font-size: 12pt;">Java</span><span style="font-size: 12pt;">的数组。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">和下面要提到的</span><span style="font-size: 12pt;">Set</span><span style="font-size: 12pt;">不同，</span><span style="font-size: 12pt;">List</span><span style="font-size: 12pt;">允许有相同的元素。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　除了具有</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">接口必备的</span><span style="font-size: 12pt;">iterator()</span><span style="font-size: 12pt;">方法外，</span><span style="font-size: 12pt;">List</span><span style="font-size: 12pt;">还提供一个</span><span style="font-size: 12pt;">listIterator()</span><span style="font-size: 12pt;">方法，返回一个</span><span style="font-size: 12pt;">ListIterator</span><span style="font-size: 12pt;">接口，和标准的</span><span style="font-size: 12pt;">Iterator</span><span style="font-size: 12pt;">接口相比，</span><span style="font-size: 12pt;">ListIterator</span><span style="font-size: 12pt;">多了一些</span><span style="font-size: 12pt;">add()</span><span style="font-size: 12pt;">之类的方法，允许添加，删除，设定元素，还能向前或向后遍历。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　实现</span><span style="font-size: 12pt;">List</span><span style="font-size: 12pt;">接口的常用类有</span><span style="font-size: 12pt;">LinkedList</span><span style="font-size: 12pt;">，</span><span style="font-size: 12pt;">ArrayList</span><span style="font-size: 12pt;">，</span><span style="font-size: 12pt;">Vector</span><span style="font-size: 12pt;">和</span><span style="font-size: 12pt;">Stack</span><span style="font-size: 12pt;">。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            <font color="#ff0000"><strong>LinkedList</strong></font></span><span style="font-size: 12pt;"><font color="#ff0000"><strong>类</strong></font></span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　</span><span style="font-size: 12pt;">LinkedList</span><span style="font-size: 12pt;">实现了</span><span style="font-size: 12pt;">List</span><span style="font-size: 12pt;">接口，允许</span><span style="font-size: 12pt;">null</span><span style="font-size: 12pt;">元素。此外</span><span style="font-size: 12pt;">LinkedList</span><span style="font-size: 12pt;">提供额外的</span><span style="font-size: 12pt;">get</span><span style="font-size: 12pt;">，</span><span style="font-size: 12pt;">remove</span><span style="font-size: 12pt;">，</span><span style="font-size: 12pt;">insert</span><span style="font-size: 12pt;">方法在</span><span style="font-size: 12pt;">LinkedList</span><span style="font-size: 12pt;">的首部或尾部。这些操作使</span><span style="font-size: 12pt;">LinkedList</span><span style="font-size: 12pt;">可被用作堆栈（</span><span style="font-size: 12pt;">stack</span><span style="font-size: 12pt;">），队列（</span><span style="font-size: 12pt;">queue</span><span style="font-size: 12pt;">）或双向队列（</span><span style="font-size: 12pt;">deque</span><span style="font-size: 12pt;">）。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　注意</span><span style="font-size: 12pt;">LinkedList</span><span style="font-size: 12pt;">没有同步方法。如果多个线程同时访问一个</span><span style="font-size: 12pt;">List</span><span style="font-size: 12pt;">，则必须自己实现访问同步。一种解决方法是在创建</span><span style="font-size: 12pt;">List</span><span style="font-size: 12pt;">时构造一个同步的</span><span style="font-size: 12pt;">List</span><span style="font-size: 12pt;">：</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　　　</span></font><font size="1"><span style="font-size: 12pt;">List list = Collections.synchronizedList(new
            LinkedList(...)); <br />
            <strong><font color="#ff0000">ArrayList</font></strong></span><span style="font-size: 12pt;"><strong><font color="#ff0000">类</font></strong></span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　</span><span style="font-size: 12pt;">ArrayList</span><span style="font-size: 12pt;">实现了可变大小的数组。它允许所有元素，包括</span><span style="font-size: 12pt;">null</span><span style="font-size: 12pt;">。</span><span style="font-size: 12pt;">ArrayList</span><span style="font-size: 12pt;">没有同步。</span><span style="font-size: 12pt;">size</span><span style="font-size: 12pt;">，</span><span style="font-size: 12pt;">isEmpty</span><span style="font-size: 12pt;">，</span><span style="font-size: 12pt;">get</span><span style="font-size: 12pt;">，</span><span style="font-size: 12pt;">set</span><span style="font-size: 12pt;">方法运行时间为常数。但是</span><span style="font-size: 12pt;">add</span><span style="font-size: 12pt;">方法开销为分摊的常数，添加</span><span style="font-size: 12pt;">n</span><span style="font-size: 12pt;">个元素需要</span><span style="font-size: 12pt;">O(n)</span><span style="font-size: 12pt;">的时间。其他的方法运行时间为线性。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　每个</span><span style="font-size: 12pt;">ArrayList</span><span style="font-size: 12pt;">实例都有一个容量（</span><span style="font-size: 12pt;">Capacity</span><span style="font-size: 12pt;">），即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加，但是增长算法并没有定义。当需要插入大量元素时，在插入前可以调用</span><span style="font-size: 12pt;">ensureCapacity</span><span style="font-size: 12pt;">方法来增加</span><span style="font-size: 12pt;">ArrayList</span><span style="font-size: 12pt;">的容量以提高插入效率。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　和</span><span style="font-size: 12pt;">LinkedList</span><span style="font-size: 12pt;">一样，</span><span style="font-size: 12pt;">ArrayList</span><span style="font-size: 12pt;">也是非同步的（</span><span style="font-size: 12pt;">unsynchronized</span><span style="font-size: 12pt;">）。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            <strong><font color="#ff0000">Vector</font></strong></span><span style="font-size: 12pt;"><strong><font color="#ff0000">类</font></strong></span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　</span><span style="font-size: 12pt;">Vector</span><span style="font-size: 12pt;">非常类似</span><span style="font-size: 12pt;">ArrayList</span><span style="font-size: 12pt;">，但是</span><span style="font-size: 12pt;">Vector</span><span style="font-size: 12pt;">是同步的。由</span><span style="font-size: 12pt;">Vector</span><span style="font-size: 12pt;">创建的</span><span style="font-size: 12pt;">Iterator</span><span style="font-size: 12pt;">，虽然和</span><span style="font-size: 12pt;">ArrayList</span><span style="font-size: 12pt;">创建的</span><span style="font-size: 12pt;">Iterator</span><span style="font-size: 12pt;">是同一接口，但是，因为</span><span style="font-size: 12pt;">Vector</span><span style="font-size: 12pt;">是同步的，当一个</span><span style="font-size: 12pt;">Iterator</span><span style="font-size: 12pt;">被创建而且正在被使用，另一个线程改变了</span><span style="font-size: 12pt;">Vector</span><span style="font-size: 12pt;">的状态（例如，添加或删除了一些元素），这时调用</span><span style="font-size: 12pt;">Iterator</span><span style="font-size: 12pt;">的方法时将抛出</span><span style="font-size: 12pt;">ConcurrentModificationException</span><span style="font-size: 12pt;">，因此必须捕获该异常。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            <strong><font color="#ff0000">Stack
            </font></strong></span><span style="font-size: 12pt;"><strong><font color="#ff0000">类</font></strong></span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　</span><span style="font-size: 12pt;">Stack</span><span style="font-size: 12pt;">继承自</span><span style="font-size: 12pt;">Vector</span><span style="font-size: 12pt;">，实现一个后进先出的堆栈。</span><span style="font-size: 12pt;">Stack</span><span style="font-size: 12pt;">提供</span><span style="font-size: 12pt;">5</span><span style="font-size: 12pt;">个额外的方法使得</span><span style="font-size: 12pt;">Vector</span><span style="font-size: 12pt;">得以被当作堆栈使用。基本的</span><span style="font-size: 12pt;">push</span><span style="font-size: 12pt;">和</span><span style="font-size: 12pt;">pop</span><span style="font-size: 12pt;">方法，还有</span><span style="font-size: 12pt;">peek</span><span style="font-size: 12pt;">方法得到栈顶的元素，</span><span style="font-size: 12pt;">empty</span><span style="font-size: 12pt;">方法测试堆栈是否为空，</span><span style="font-size: 12pt;">search</span><span style="font-size: 12pt;">方法检测一个元素在堆栈中的位置。</span><span style="font-size: 12pt;">Stack</span><span style="font-size: 12pt;">刚创建后是空栈。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            <strong><font color="#ff0000">Set</font></strong></span><span style="font-size: 12pt;"><strong><font color="#ff0000">接口</font></strong></span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　</span><span style="font-size: 12pt;">Set</span><span style="font-size: 12pt;">是一种不包含重复的元素的</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">，即任意的两个元素</span><span style="font-size: 12pt;">e1</span><span style="font-size: 12pt;">和</span><span style="font-size: 12pt;">e2</span><span style="font-size: 12pt;">都有</span><span style="font-size: 12pt;">e1.equals(e2)=false</span><span style="font-size: 12pt;">，</span><span style="font-size: 12pt;">Set</span><span style="font-size: 12pt;">最多有一个</span><span style="font-size: 12pt;">null</span><span style="font-size: 12pt;">元素。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　很明显，</span><span style="font-size: 12pt;">Set</span><span style="font-size: 12pt;">的构造函数有一个约束条件，传入的</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">参数不能包含重复的元素。</span></font><span style="font-size: 12pt;"><br />
            </span><font size="1"><span style="font-size: 12pt;">请注意：必须小心操作可变对象（</span><span style="font-size: 12pt;">Mutable Object</span><span style="font-size: 12pt;">）。如果一个</span><span style="font-size: 12pt;">Set</span><span style="font-size: 12pt;">中的可变元素改变了自身状态</span><span style="font-size: 12pt;">导致</span><span style="font-size: 12pt;">Object.equals(Object)=true</span><span style="font-size: 12pt;">将导致一些问题。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            <strong><font color="#ff0000">Map</font></strong></span><span style="font-size: 12pt;"><strong><font color="#ff0000">接口</font></strong></span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　请注意，</span><span style="font-size: 12pt;">Map</span><span style="font-size: 12pt;">没有继承</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">接口，</span><span style="font-size: 12pt;">Map</span><span style="font-size: 12pt;">提供</span><span style="font-size: 12pt;">key</span><span style="font-size: 12pt;">到</span><span style="font-size: 12pt;">value</span><span style="font-size: 12pt;">的映射。一个</span><span style="font-size: 12pt;">Map</span><span style="font-size: 12pt;">中不能包含相同的</span><span style="font-size: 12pt;">key</span><span style="font-size: 12pt;">，每个</span><span style="font-size: 12pt;">key</span><span style="font-size: 12pt;">只能映射一个</span><span style="font-size: 12pt;">value</span><span style="font-size: 12pt;">。</span><span style="font-size: 12pt;">Map</span><span style="font-size: 12pt;">接口提供</span><span style="font-size: 12pt;">3</span><span style="font-size: 12pt;">种集合的视图，</span><span style="font-size: 12pt;">Map</span><span style="font-size: 12pt;">的内容可以被当作一组</span><span style="font-size: 12pt;">key</span><span style="font-size: 12pt;">集合，一组</span><span style="font-size: 12pt;">value</span><span style="font-size: 12pt;">集合，或者一组</span><span style="font-size: 12pt;">key-value</span><span style="font-size: 12pt;">映射。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            <strong><font color="#ff0000">Hashtable</font></strong></span><span style="font-size: 12pt;"><strong><font color="#ff0000">类</font></strong></span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　</span><span style="font-size: 12pt;">Hashtable</span><span style="font-size: 12pt;">继承</span><span style="font-size: 12pt;">Map</span><span style="font-size: 12pt;">接口，实现一个</span><span style="font-size: 12pt;">key-value</span><span style="font-size: 12pt;">映射的哈希表。任何非空（</span><span style="font-size: 12pt;">non-null</span><span style="font-size: 12pt;">）的对象都可作为</span><span style="font-size: 12pt;">key</span><span style="font-size: 12pt;">或者</span><span style="font-size: 12pt;">value</span><span style="font-size: 12pt;">。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　添加数据使用</span><span style="font-size: 12pt;">put(key,
            value)</span><span style="font-size: 12pt;">，取出数据使用</span><span style="font-size: 12pt;">get(key)</span><span style="font-size: 12pt;">，这两个基本操作的时间开销为常数。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　</span><span style="font-size: 12pt;">Hashtable</span><span style="font-size: 12pt;">通过</span><span style="font-size: 12pt;">initial
            capacity</span><span style="font-size: 12pt;">和</span><span style="font-size: 12pt;">load factor</span><span style="font-size: 12pt;">两个参数调整性能。通常缺省的</span><span style="font-size: 12pt;">load
            factor 0.75</span><span style="font-size: 12pt;">较好地实现了时间和空间的均衡。增大</span><span style="font-size: 12pt;">load factor</span><span style="font-size: 12pt;">可以节省空间但相应的查找时间将增大，这会影响像</span><span style="font-size: 12pt;">get</span><span style="font-size: 12pt;">和</span><span style="font-size: 12pt;">put</span><span style="font-size: 12pt;">这样的操作。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">使用</span><span style="font-size: 12pt;">Hashtable</span><span style="font-size: 12pt;">的简单示例如下，将</span><span style="font-size: 12pt;">1</span><span style="font-size: 12pt;">，</span><span style="font-size: 12pt;">2</span><span style="font-size: 12pt;">，</span><span style="font-size: 12pt;">3</span><span style="font-size: 12pt;">放到</span><span style="font-size: 12pt;">Hashtable</span><span style="font-size: 12pt;">中，他们的</span><span style="font-size: 12pt;">key</span><span style="font-size: 12pt;">分别是</span><span style="font-size: 12pt;">&#8221;one&#8221;</span><span style="font-size: 12pt;">，</span><span style="font-size: 12pt;">&#8221;two&#8221;</span><span style="font-size: 12pt;">，</span><span style="font-size: 12pt;">&#8221;three&#8221;</span><span style="font-size: 12pt;">：</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　　　</span></font><font size="1"><span style="font-size: 12pt;">Hashtable numbers = new Hashtable(); <br />
            </span><span style="font-size: 12pt;">　　　　</span></font><font size="1"><span style="font-size: 12pt;">numbers.put(&#8220;one&#8221;, new Integer(1)); <br />
            </span><span style="font-size: 12pt;">　　　　</span></font><font size="1"><span style="font-size: 12pt;">numbers.put(&#8220;two&#8221;, new Integer(2)); <br />
            </span><span style="font-size: 12pt;">　　　　</span></font><font size="1"><span style="font-size: 12pt;">numbers.put(&#8220;three&#8221;, new Integer(3)); <br />
            </span><span style="font-size: 12pt;">　　要取出一个数，比如</span><span style="font-size: 12pt;">2</span><span style="font-size: 12pt;">，用相应的</span><span style="font-size: 12pt;">key</span><span style="font-size: 12pt;">：</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　　　</span></font><font size="1"><span style="font-size: 12pt;">Integer n = (Integer)numbers.get(&#8220;two&#8221;);
            <br />
            </span><span style="font-size: 12pt;">　　　　</span></font><font size="1"><span style="font-size: 12pt;">System.out.println(&#8220;two = &#8221; + n); <br />
            </span><span style="font-size: 12pt;">　　由于作为</span><span style="font-size: 12pt;">key</span><span style="font-size: 12pt;">的对象将通过计算其散列函数来确定与之对应的</span><span style="font-size: 12pt;">value</span><span style="font-size: 12pt;">的位置，因此任何作为</span><span style="font-size: 12pt;">key</span><span style="font-size: 12pt;">的对象都必须实现</span><span style="font-size: 12pt;">hashCode</span><span style="font-size: 12pt;">和</span><span style="font-size: 12pt;">equals</span><span style="font-size: 12pt;">方法。</span><span style="font-size: 12pt;">hashCode</span><span style="font-size: 12pt;">和</span><span style="font-size: 12pt;">equals</span><span style="font-size: 12pt;">方法继承自根类</span><span style="font-size: 12pt;">Object</span><span style="font-size: 12pt;">，如果你用自定义的类当作</span><span style="font-size: 12pt;">key</span><span style="font-size: 12pt;">的话，要相当小心，按照散列函数的定义，如果两个对象相同，即</span><span style="font-size: 12pt;">obj1.equals(obj2)=true</span><span style="font-size: 12pt;">，则它们的</span><span style="font-size: 12pt;">hashCode</span><span style="font-size: 12pt;">必须相同，但如果两个对象不同，则它们的</span><span style="font-size: 12pt;">hashCode</span><span style="font-size: 12pt;">不一定不同，如果两个不同对象的</span><span style="font-size: 12pt;">hashCode</span><span style="font-size: 12pt;">相同，这种现象称为冲突，冲突会导致操作哈希表的时间开销增大，所以尽量定义好的</span><span style="font-size: 12pt;">hashCode()</span><span style="font-size: 12pt;">方法，能加快哈希表的操作。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　如果相同的对象有不同的</span><span style="font-size: 12pt;">hashCode</span><span style="font-size: 12pt;">，对哈希表的操作会出现意想不到的结果（期待的</span><span style="font-size: 12pt;">get</span><span style="font-size: 12pt;">方法返回</span><span style="font-size: 12pt;">null</span><span style="font-size: 12pt;">），要避免这种问题，只需要牢记一条：要同时复写</span><span style="font-size: 12pt;">equals</span><span style="font-size: 12pt;">方法和</span><span style="font-size: 12pt;">hashCode</span><span style="font-size: 12pt;">方法，而不要只写其中一个。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　</span><span style="font-size: 12pt;">Hashtable</span><span style="font-size: 12pt;">是同步的。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            <strong><font color="#ff0000">HashMap</font></strong></span><span style="font-size: 12pt;"><strong><font color="#ff0000">类</font></strong></span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　</span><span style="font-size: 12pt;">HashMap</span><span style="font-size: 12pt;">和</span><span style="font-size: 12pt;">Hashtable</span><span style="font-size: 12pt;">类似，不同之处在于</span><span style="font-size: 12pt;">HashMap</span><span style="font-size: 12pt;">是非同步的，并且允许</span><span style="font-size: 12pt;">null</span><span style="font-size: 12pt;">，即</span><span style="font-size: 12pt;">null value</span><span style="font-size: 12pt;">和</span><span style="font-size: 12pt;">null
            key</span><span style="font-size: 12pt;">。，但是将</span><span style="font-size: 12pt;">HashMap</span><span style="font-size: 12pt;">视为</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">时（</span><span style="font-size: 12pt;">values()</span><span style="font-size: 12pt;">方法可返回</span><span style="font-size: 12pt;">Collection</span><span style="font-size: 12pt;">），其迭代子操作时间开销和</span><span style="font-size: 12pt;">HashMap</span><span style="font-size: 12pt;">的容量成比例。因此，如果迭代操作的性能相当重要的话，不要将</span><span style="font-size: 12pt;">HashMap</span><span style="font-size: 12pt;">的初始化容量设得过高，或者</span><span style="font-size: 12pt;">load
            factor</span><span style="font-size: 12pt;">过低。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            <strong><font color="#ff0000">WeakHashMap</font></strong></span><span style="font-size: 12pt;"><strong><font color="#ff0000">类</font></strong></span></font><span style="font-size: 12pt;"><br />
            </span><font size="1"><span style="font-size: 12pt;">　　</span><span style="font-size: 12pt;">WeakHashMap</span><span style="font-size: 12pt;">是一种改进的</span><span style="font-size: 12pt;">HashMap</span><span style="font-size: 12pt;">，它对</span><span style="font-size: 12pt;">key</span><span style="font-size: 12pt;">实行</span><span style="font-size: 12pt;">&#8220;</span><span style="font-size: 12pt;">弱引用</span><span style="font-size: 12pt;">&#8221;</span><span style="font-size: 12pt;">，如果一个</span><span style="font-size: 12pt;">key</span><span style="font-size: 12pt;">不再被外部所引用，那么该</span><span style="font-size: 12pt;">key</span><span style="font-size: 12pt;">可以被</span><span style="font-size: 12pt;">GC</span><span style="font-size: 12pt;">回收。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">总结</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　如果涉及到堆栈，队列等操作，应该考虑用</span><span style="font-size: 12pt;">List</span><span style="font-size: 12pt;">，对于需要快速插入，删除元素，应该使用</span><span style="font-size: 12pt;">LinkedList</span><span style="font-size: 12pt;">，如果需要快速随机访问元素，应该使用</span><span style="font-size: 12pt;">ArrayList</span><span style="font-size: 12pt;">。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　如果程序在单线程环境中，或者访问仅仅在一个线程中进行，考虑非同步的类，其效率较高，如果多个线程可能同时操作一个类，应该使用同步的类。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　要特别注意对哈希表的操作，作为</span><span style="font-size: 12pt;">key</span><span style="font-size: 12pt;">的对象要正确复写</span><span style="font-size: 12pt;">equals</span><span style="font-size: 12pt;">和</span><span style="font-size: 12pt;">hashCode</span><span style="font-size: 12pt;">方法。</span></font><font size="1"><span style="font-size: 12pt;"> <br />
            </span><span style="font-size: 12pt;">　　尽量返回接口而非实际的类型，如返回</span><span style="font-size: 12pt;">List</span><span style="font-size: 12pt;">而非</span><span style="font-size: 12pt;">ArrayList</span><span style="font-size: 12pt;">，这样如果以后需要将</span><span style="font-size: 12pt;">ArrayList</span><span style="font-size: 12pt;">换成</span><span style="font-size: 12pt;">LinkedList</span><span style="font-size: 12pt;">时，客户端代码不用改变。这就是针对抽象编程。</span></font></div>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/alinglau36/aggbug/257746.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alinglau36/" target="_blank">lau</a> 2009-03-04 11:51 <a href="http://www.blogjava.net/alinglau36/archive/2009/03/04/257746.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Token（令牌）的机制来解决重复提交</title><link>http://www.blogjava.net/alinglau36/archive/2009/02/18/255283.html</link><dc:creator>lau</dc:creator><author>lau</author><pubDate>Wed, 18 Feb 2009 07:39:00 GMT</pubDate><guid>http://www.blogjava.net/alinglau36/archive/2009/02/18/255283.html</guid><wfw:comment>http://www.blogjava.net/alinglau36/comments/255283.html</wfw:comment><comments>http://www.blogjava.net/alinglau36/archive/2009/02/18/255283.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alinglau36/comments/commentRss/255283.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alinglau36/services/trackbacks/255283.html</trackback:ping><description><![CDATA[struts有自带的Token（令牌）的机制来解决重复提交（包括后退，刷新等）．举例：
<br />
<br />
假设：假设有一个新增用户的填写表单页面，填写完后点击＂提交＂按钮完成数据库录入功能，要求不能重复提交（指类似刷新页面的情况）．此时，需要有两个action（第一个action用来生成hidden的token值．第二个action用来校验token值，通过判断来决定是不是重复提交，不是则提交操作，否则提示错误）和至少一个页面（保存token值和填写用户信息的录入页面）来完成校验是否重复提交．此处有两个页面来完成．
<br />
<br />
为了方便，用户表只有两个字段用户名＜username＞和密码＜password＞： <br />
<br />
具体逻辑如下：
<br />
<br />
index.jsp--链接--&gt; PrepareAddUserAction.java--转发并生成token--&gt;
addUser.jsp--提交--&gt; <br />
AddUserAction.java--首先校验 '是否重复提交 ',是提示错误信息,不是,执行数据库操作.
<br />
<br />
部分相关代码(省略formbean的代码): <br />
========index.jsp======== <br />
&lt;html&gt;
&lt;head&gt; &lt;title&gt; 测试 &lt;/title&gt; &lt;/head&gt; &lt;body&gt; <br />
&nbsp; &nbsp;
&lt;a &nbsp; href= " &lt;%=request.getContextPath()%&gt; /PrepareAddUserAction.java
"&gt; 新增用户 &lt;/a&gt; <br />
&lt;/body&gt; &lt;/html&gt;
<br />
<br />
=========PrepareAddUserAction.java========= <br />
package &nbsp;
com.tseyimwah.struts.action; <br />
<br />
import &nbsp;
javax.servlet.http.HttpServletRequest; <br />
import &nbsp;
javax.servlet.http.HttpServletResponse; <br />
<br />
import &nbsp;
org.apache.struts.action.Action; <br />
import &nbsp;
org.apache.struts.action.ActionForm; <br />
import &nbsp;
org.apache.struts.action.ActionForward; <br />
import &nbsp;
org.apache.struts.action.ActionMapping; <br />
<br />
public &nbsp; class &nbsp;
PrepareAddUserAction &nbsp; extends &nbsp; Action &nbsp; { <br />
public &nbsp; ActionForward &nbsp;
execute( <br />
ActionMapping &nbsp; mapping, <br />
ActionForm &nbsp; form,
<br />
HttpServletRequest &nbsp; request, <br />
HttpServletResponse &nbsp; response) &nbsp; throws &nbsp;
HibernateException &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .........//相关方法
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; saveToken(request); &nbsp; &nbsp;
//在下一个页面addUser.jsp生成hidden类型的token值 <br />
return &nbsp; mapping.findForward( "addUser
");//页面跳转 <br />
} <br />
} <br />
<br />
==========addUser.jsp=============
<br />
此处代码没有什么要求,含有form的普通struts页面,代码省略,里面的 "提交 "按纽给AddUserAction.java,即
&lt;html:form &nbsp; &nbsp; action= "/AddUserAction.do " &nbsp; method= "post "&gt;
<br />
<br />
============AddUserAction.java===== <br />
package &nbsp;
com.tseyimwah.struts.action; <br />
<br />
import &nbsp;
javax.servlet.http.HttpServletRequest; <br />
import &nbsp;
javax.servlet.http.HttpServletResponse; <br />
<br />
import &nbsp;
org.apache.struts.action.Action; <br />
import &nbsp;
org.apache.struts.action.ActionForm; <br />
import &nbsp;
org.apache.struts.action.ActionForward; <br />
import &nbsp;
org.apache.struts.action.ActionMapping; <br />
<br />
public &nbsp; class &nbsp; AddUserAction &nbsp;
extends &nbsp; Action &nbsp; { <br />
public &nbsp; ActionForward &nbsp; execute( <br />
ActionMapping &nbsp;
mapping, <br />
ActionForm &nbsp; form, <br />
HttpServletRequest &nbsp; request,
<br />
HttpServletResponse &nbsp; response) &nbsp; throws &nbsp; HibernateException &nbsp; { <br />
&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; //判断token值,如果是重复提交跳转到错误页面则提示出错信息,否则执行相关的数据库操作 <br />
&nbsp; &nbsp; &nbsp; if &nbsp;
(!isTokenValid(request)){ <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
request.setAttribute(GlobalKeys.MESSAGE_ID, &nbsp; "不允许重复提交! ");//设置出错信息 <br />
&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; return &nbsp; (mapping.findForward( "errorPage ")); <br />
&nbsp; &nbsp; &nbsp; } &nbsp; else <br />
&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; resetToken(request); &nbsp; //重新设置token值,可不用 <br />
&nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; ...... <br />
&nbsp; &nbsp;
&nbsp; ......//其他的相关方法,如设置相关属性值,调用相关的数据库操作等 <br />
&nbsp; &nbsp; &nbsp; return &nbsp; (mapping.findForward(
"addUserSucess "));//新增用户成功的页面 <br />
} <br />
<br />
<br />
这只是将相关的必要代码写出,根据需要可以改写相关的代码.
<img src ="http://www.blogjava.net/alinglau36/aggbug/255283.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alinglau36/" target="_blank">lau</a> 2009-02-18 15:39 <a href="http://www.blogjava.net/alinglau36/archive/2009/02/18/255283.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>