﻿<?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-沙漠中的鱼-文章分类-Java基础</title><link>http://www.blogjava.net/aoneany/category/39245.html</link><description>欲上天堂，先下地狱</description><language>zh-cn</language><lastBuildDate>Fri, 02 Aug 2013 23:49:11 GMT</lastBuildDate><pubDate>Fri, 02 Aug 2013 23:49:11 GMT</pubDate><ttl>60</ttl><item><title>编写bat脚本执行jar</title><link>http://www.blogjava.net/aoneany/articles/402292.html</link><dc:creator>沙漠中的鱼</dc:creator><author>沙漠中的鱼</author><pubDate>Fri, 02 Aug 2013 03:08:00 GMT</pubDate><guid>http://www.blogjava.net/aoneany/articles/402292.html</guid><wfw:comment>http://www.blogjava.net/aoneany/comments/402292.html</wfw:comment><comments>http://www.blogjava.net/aoneany/articles/402292.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aoneany/comments/commentRss/402292.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aoneany/services/trackbacks/402292.html</trackback:ping><description><![CDATA[<div>@echo off &nbsp; &nbsp; &nbsp;&nbsp;</div><div>set PATH=C:\Program Files (x86)\Java\jdk1.6.0_20\bin;C:\WINDOWS;C:\WINDOWS\COMMAND&nbsp;</div><div>set classpath=.;C:\Program Files (x86)\Java\jdk1.6.0_20\lib\tools.jar;C:\Program Files (x86)\Java\jdk1.6.0_20\lib\dt.jar&nbsp;</div><div></div><div>java -jar extract_excel.jar</div><div>&nbsp; &nbsp;</div><div>pause&nbsp;</div><img src ="http://www.blogjava.net/aoneany/aggbug/402292.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aoneany/" target="_blank">沙漠中的鱼</a> 2013-08-02 11:08 <a href="http://www.blogjava.net/aoneany/articles/402292.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在CXF中如何传递抽象对象</title><link>http://www.blogjava.net/aoneany/articles/371010.html</link><dc:creator>沙漠中的鱼</dc:creator><author>沙漠中的鱼</author><pubDate>Wed, 29 Feb 2012 08:29:00 GMT</pubDate><guid>http://www.blogjava.net/aoneany/articles/371010.html</guid><wfw:comment>http://www.blogjava.net/aoneany/comments/371010.html</wfw:comment><comments>http://www.blogjava.net/aoneany/articles/371010.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aoneany/comments/commentRss/371010.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aoneany/services/trackbacks/371010.html</trackback:ping><description><![CDATA[先定一个适配器类，继承XmlAdapter,可以将抽象类转换为可以识别的传输对象<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;UserTOAdapter&nbsp;</span><span style="color: #0000FF; ">extends</span><span style="color: #000000; ">&nbsp;XmlAdapter</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">TO,&nbsp;User</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;User&nbsp;unmarshal(TO&nbsp;to)&nbsp;</span><span style="color: #0000FF; ">throws</span><span style="color: #000000; ">&nbsp;Exception&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;(User)to;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;TO&nbsp;marshal(User&nbsp;user)&nbsp;</span><span style="color: #0000FF; ">throws</span><span style="color: #000000; ">&nbsp;Exception&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;(TO)user;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
}<br />
</span></div>
<div>在WebService接口中定义参数转换的方法，如下<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">@WebService<br /></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">interface</span><span style="color: #000000; ">&nbsp;TypeConvert&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;@WebMethod<br />&nbsp;&nbsp;&nbsp;&nbsp;@XmlJavaTypeAdapter(UserTOAdapter.</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">)<br />&nbsp;&nbsp;&nbsp;&nbsp;User&nbsp;addUser(User&nbsp;user);<br />}</span></div><br /><br /></div><img src ="http://www.blogjava.net/aoneany/aggbug/371010.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aoneany/" target="_blank">沙漠中的鱼</a> 2012-02-29 16:29 <a href="http://www.blogjava.net/aoneany/articles/371010.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>位移进制运算</title><link>http://www.blogjava.net/aoneany/articles/348889.html</link><dc:creator>沙漠中的鱼</dc:creator><author>沙漠中的鱼</author><pubDate>Sat, 23 Apr 2011 13:58:00 GMT</pubDate><guid>http://www.blogjava.net/aoneany/articles/348889.html</guid><wfw:comment>http://www.blogjava.net/aoneany/comments/348889.html</wfw:comment><comments>http://www.blogjava.net/aoneany/articles/348889.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aoneany/comments/commentRss/348889.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aoneany/services/trackbacks/348889.html</trackback:ping><description><![CDATA[<p>带符号右移 题：－15 &gt;&gt; 2 = -4</p>
<p>15原码: 　　00000000 00000000 00000000 00001111 //32位,二进制<br />
反码： 　　 11111111 11111111 11111111 11110000 //0变1,1变O<br />
补码： 　　 11111111 11111111 11111111 11110001 //最后位加1,-15二进制<br />
右移2位：　 11111111 11111111 11111111 11111100 //右边丢弃2位,前面30位保留,左边补1<br />
取反：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00000000 00000000 00000000 00000011 //0变1,1变O<br />
＋１:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3+1<br />
结果:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ＝－４ //负号保留,十进制</p>
<p><br />
带符号左移 题: 10 &lt;&lt; 2 = 40<br />
10 补码:&nbsp;&nbsp;&nbsp; 00000000 00000000 00000000 00001010 //32位,二进制<br />
左移2位:&nbsp;&nbsp;&nbsp; 00000000 00000000 00000000 00101000 //左边丢弃2位,右边补0<br />
结果:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 40 //十进制</p>
<p>　</p>
<p>无符号右移 题：－4321 &gt;&gt;&gt; 30 = 3<br />
4321原码: 　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00000000 00000000 00010000 11100011 //32位,二进制<br />
反码： 　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 11111111 11111111 11101111 00011100 //0变1,1变O<br />
补码： 　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 11111111 11111111 11101111 00011101 //最后位加1,-4321二进制<br />
无符号右移30位：　 00000000 00000000 00000000 00000011 //右边丢弃30位,前面二位保留,左边补0<br />
结果:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3 //十进制</p>
<p><br />
&amp; 位逻辑与 题：44 &amp; 21 = 4<br />
44 补码:&nbsp;&nbsp;&nbsp; 00000000 00000000 00000000 00101100 //32位,二进制<br />
21 补码:&nbsp;&nbsp;&nbsp; 00000000 00000000 00000000 00010101 //32位,二进制<br />
&amp; 运算:&nbsp;&nbsp;&nbsp;&nbsp; 00000000 00000000 00000000 00000100 //对应的两个二进制位均为1时 结果位才为1 否则为0<br />
结果:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4 //十进制&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>| 位逻辑与 题：9 | 5 = 13<br />
9 补码:&nbsp;&nbsp;&nbsp; 00000000 00000000 00000000 00001001 //32位,二进制<br />
5 补码:&nbsp;&nbsp;&nbsp; 00000000 00000000 00000000 00000101 //32位,二进制<br />
| 运算:&nbsp;&nbsp;&nbsp; 00000000 00000000 00000000 00001101 //对应的二个二进制位有一个为1时，结果位就为1<br />
结果:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13 //十进制 </p>
<p><br />
^ 位逻辑异或 题: 9 ^ 5 = 12<br />
9 补码:&nbsp;&nbsp;&nbsp; 00000000 00000000 00000000 00001001 //32位,二进制<br />
5 补码:&nbsp;&nbsp;&nbsp; 00000000 00000000 00000000 00000101 //32位,二进制<br />
| 运算:&nbsp;&nbsp;&nbsp; 00000000 00000000 00000000 00001100 //对应的二进制位相异时，结果为1<br />
结果:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12 //十进制</p>
<p><br />
~ 位逻辑反 题: ~9 = -10<br />
9 补码:&nbsp;&nbsp;&nbsp; 00000000 00000000 00000000 00001001 //32位,二进制<br />
~ 运算:&nbsp;&nbsp;&nbsp; 11111111 11111111 11111111 11110110 //最高位为1表示为一个负数,则进行取反加1<br />
取反:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00000000 00000000 00000000 00001001 //32位,二进制<br />
＋１:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9+1 //32位,二进制<br />
结果:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -10 //十进制</p>
<p><br />
在计算机系统中，数值一律用补码来表示（存储）。<br />
主要原因：使用补码，可以将符号位和其它位统一处理；同时，减法也可按加法来处理。另外，两个用补<br />
码表示的数相加时，如果最高位（符号位）有进位，则进位被舍弃。<br />
补码与原码的转换过程几乎是相同的。<br />
数值的补码表示也分两种情况：<br />
（1）正数的补码：与原码相同。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 例如，+9的补码是00001001。<br />
（2）负数的补码：符号位为1，其余位为该数绝对值的原码按位取反；然后整个数加1。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 例如，-7的补码：因为是负数，则符号位为&#8220;1&#8221;,整个为10000111；其余7位为-7的绝对值+7的原码<br />
&nbsp;&nbsp;&nbsp;&nbsp; 0000111按位取反为1111000；再加1，所以-7的补码是11111001。<br />
已知一个数的补码，求原码的操作分两种情况：<br />
（1）如果补码的符号位为&#8220;0&#8221;，表示是一个正数，所以补码就是该数的原码。<br />
（2）如果补码的符号位为&#8220;1&#8221;，表示是一个负数，求原码的操作可以是：符号位为1，其余各位取反，然后再整个数加1。<br />
&nbsp;&nbsp;&nbsp;&nbsp; 例如，已知一个补码为11111001，则原码是10000111（-7）：因为符号位为&#8220;1&#8221;，表示是一个负数，所以该位不变，仍为&#8220;1&#8221;；其余7位1111001取反后为0000110；再加1，所以是10000111。 </p>
<p>&nbsp;</p>
<p>转载：<a href="http://blog.csdn.net/zjp8023/archive/2009/05/29/4224121.aspx">http://blog.csdn.net/zjp8023/archive/2009/05/29/4224121.aspx</a></p>
<img src ="http://www.blogjava.net/aoneany/aggbug/348889.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aoneany/" target="_blank">沙漠中的鱼</a> 2011-04-23 21:58 <a href="http://www.blogjava.net/aoneany/articles/348889.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>您的小数点到哪里去了</title><link>http://www.blogjava.net/aoneany/articles/348753.html</link><dc:creator>沙漠中的鱼</dc:creator><author>沙漠中的鱼</author><pubDate>Thu, 21 Apr 2011 15:36:00 GMT</pubDate><guid>http://www.blogjava.net/aoneany/articles/348753.html</guid><wfw:comment>http://www.blogjava.net/aoneany/comments/348753.html</wfw:comment><comments>http://www.blogjava.net/aoneany/articles/348753.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aoneany/comments/commentRss/348753.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aoneany/services/trackbacks/348753.html</trackback:ping><description><![CDATA[<p>Java 语言支持两种基本的浮点类型： <code>float</code> 和 <code>double</code> ，以及与它们对应的包装类 <code>Float</code> 和 <code>Double</code> 。它们都依据 IEEE 754 标准，该标准为 32 位浮点和 64 位双精度浮点二进制小数定义了二进制标准。 </p>
<p>IEEE 754 用科学记数法以底数为 2 的小数来表示浮点数。IEEE 浮点数用 1 位表示数字的符号，用 8 位来表示指数，用 23 位来表示尾数，即小数部分。作为有符号整数的指数可以有正负之分。小数部分用二进制（底数 2）小数来表示，这意味着最高位对应着值 ?(2 <sup>-1</sup>)，第二位对应着 ?(2 <sup>-2</sup>)，依此类推。对于双精度浮点数，用 11 位表示指数，52 位表示尾数。IEEE 浮点值的格式如图 1 所示。 </p>
<br />
<a name="IDADA0PE"><strong>图 1. IEEE 754 浮点数的格式 </strong></a><br />
<img alt="图 1. IEEE 754 浮点数的格式" src="http://www.ibm.com/developerworks/cn/java/j-jtp0114/float.gif" width="579" height="177" /> <br />
<p>因为用科学记数法可以有多种方式来表示给定数字，所以要规范化浮点数，以便用底数为 2 并且小数点左边为 1 的小数来表示，按照需要调节指数就可以得到所需的数字。所以，例如，数 1.25 可以表示为尾数为 1.01，指数为 0： <code>(-1) <sup>0</sup>*1.01 <sub>2</sub>*2 <sup>0</sup> </code></p>
<p>数 10.0 可以表示为尾数为 1.01，指数为 3： <code>(-1) <sup>0</sup>*1.01 <sub>2</sub>*2 <sup>3</sup> </code></p>
<p><code></code>&nbsp;</p>
<p>一个十进制数能否用二进制浮点数精确表示，关键在于小数部分。我们来看一个最简单的小数<img title="（转）IEEE754" border="0" alt="（转）IEEE754" src="http://www.cnblogs.com/images/cnblogs_com/bossin/WindowsLiveWriter/IEEE754_B489/clip_image016.gif" width="44" height="24" real_src="http://www.cnblogs.com/images/cnblogs_com/bossin/WindowsLiveWriter/IEEE754_B489/clip_image016.gif" />能否精确表示。按照乘以2取整数位的方法，有：</p>
<p><img title="（转）IEEE754" border="0" alt="（转）IEEE754" src="http://www.cnblogs.com/images/cnblogs_com/bossin/WindowsLiveWriter/IEEE754_B489/clip_image018.gif" width="268" height="243" real_src="http://www.cnblogs.com/images/cnblogs_com/bossin/WindowsLiveWriter/IEEE754_B489/clip_image018.gif" /></p>
<p>得到一个无限循环的二进制小数<img title="（转）IEEE754" border="0" alt="（转）IEEE754" src="http://www.cnblogs.com/images/cnblogs_com/bossin/WindowsLiveWriter/IEEE754_B489/clip_image020.gif" width="177" height="24" real_src="http://www.cnblogs.com/images/cnblogs_com/bossin/WindowsLiveWriter/IEEE754_B489/clip_image020.gif" />，用有限位无法表示无限循环小数，因此，<img title="（转）IEEE754" border="0" alt="（转）IEEE754" src="http://www.cnblogs.com/images/cnblogs_com/bossin/WindowsLiveWriter/IEEE754_B489/clip_image016%5B1%5D.gif" width="44" height="24" real_src="http://www.cnblogs.com/images/cnblogs_com/bossin/WindowsLiveWriter/IEEE754_B489/clip_image016%5B1%5D.gif" />无法用IEEE 754浮点数精确表示。从中也可以看到：由于</p>
<p><img title="（转）IEEE754" border="0" alt="（转）IEEE754" src="http://www.cnblogs.com/images/cnblogs_com/bossin/WindowsLiveWriter/IEEE754_B489/clip_image023.gif" width="375" height="48" real_src="http://www.cnblogs.com/images/cnblogs_com/bossin/WindowsLiveWriter/IEEE754_B489/clip_image023.gif" />，</p>
<p>这四个数也无法精确表示。同理：</p>
<p><img title="（转）IEEE754" border="0" alt="（转）IEEE754" src="http://www.cnblogs.com/images/cnblogs_com/bossin/WindowsLiveWriter/IEEE754_B489/clip_image025.gif" width="272" height="73" real_src="http://www.cnblogs.com/images/cnblogs_com/bossin/WindowsLiveWriter/IEEE754_B489/clip_image025.gif" /></p>
<p>也无法用IEEE 754浮点数精确表示。</p>
<p>在以0.1~0.9结尾的9个小数中，只有0.5可以精确表示：（如）<img title="（转）IEEE754" border="0" alt="（转）IEEE754" src="http://www.cnblogs.com/images/cnblogs_com/bossin/WindowsLiveWriter/IEEE754_B489/clip_image029.gif" width="101" height="24" real_src="http://www.cnblogs.com/images/cnblogs_com/bossin/WindowsLiveWriter/IEEE754_B489/clip_image029.gif" />，而其他均无法进行精确转换。</p>
<img src ="http://www.blogjava.net/aoneany/aggbug/348753.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aoneany/" target="_blank">沙漠中的鱼</a> 2011-04-21 23:36 <a href="http://www.blogjava.net/aoneany/articles/348753.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>遍历查找性能测试报告（Map,Array,RBTree）</title><link>http://www.blogjava.net/aoneany/articles/348346.html</link><dc:creator>沙漠中的鱼</dc:creator><author>沙漠中的鱼</author><pubDate>Fri, 15 Apr 2011 05:39:00 GMT</pubDate><guid>http://www.blogjava.net/aoneany/articles/348346.html</guid><wfw:comment>http://www.blogjava.net/aoneany/comments/348346.html</wfw:comment><comments>http://www.blogjava.net/aoneany/articles/348346.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aoneany/comments/commentRss/348346.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aoneany/services/trackbacks/348346.html</trackback:ping><description><![CDATA[&nbsp;
<p><span style="font-family: 宋体">&nbsp; </p>
<p><span style="font-family: 宋体">上次只测试查询的性能，而且都是在最优的情况下进行，没有考虑条他情况，这次重新修改了测试用例，把整个测试的各个过程描述出来（加载，排序，查找的效率）。</span></p>
<p><strong><span style="font-family: 宋体">场景：</span></strong><span style="font-family: 宋体">随机生成</span>5<span style="font-family: 宋体">百万条不同的记录，而每条记录不存在相同的情况。现在将这</span>5<span style="font-family: 宋体">百万条记录在不同的情况下进行测试。测试结果如下</span></p>
<p>1<span style="font-family: 宋体">、</span>5<span style="font-family: 宋体">百万条记录，总共查询</span>50<span style="font-family: 宋体">万次（查询前</span>50<span style="font-family: 宋体">万条记录）</span></p>
<p><span style="font-family: 宋体">数组性能测试加载花费</span>:<strong><span style="color: red">6.11</strong></span><span style="font-family: 宋体">秒</span></p>
<p><span style="font-family: 宋体">数组性能测试排序花费</span>:<strong><span style="color: red">18.313</strong></span><span style="font-family: 宋体">秒</span></p>
<p><span style="font-family: 宋体">数组性能测试查找花费</span>:<strong><span style="color: red">3.297</strong></span><span style="font-family: 宋体">秒</span></p>
<p><span style="font-family: 宋体">数组性能测试共花费</span>:<strong><span style="color: red">27.72</strong></span><span style="font-family: 宋体">秒</span></p>
<p><span style="font-family: 宋体">数组性能测试总共占</span>:<strong><span style="color: red">100005888</strong> </span><span style="font-family: 宋体">字节</span></p>
<p>RBTree<span style="font-family: 宋体">性能测试加载花费</span>:<strong><span style="color: red">53.644</strong></span><span style="font-family: 宋体">秒</span></p>
<p>RBTree<span style="font-family: 宋体">性能测试查找共花费</span>:<strong><span style="color: red">2.86</strong></span><span style="font-family: 宋体">秒</span></p>
<p>RBTree<span style="font-family: 宋体">性能测试共花费</span>:<strong><span style="color: red">56.504</strong></span><span style="font-family: 宋体">秒</span></p>
<p>RBTREE<span style="font-family: 宋体">性能测试共占用</span>:<strong><span style="color: red">240004864</strong> </span><span style="font-family: 宋体">字节</span></p>
<p>MAP<span style="font-family: 宋体">性能测试加载花费</span>:<strong><span style="color: red">7.282</strong></span><span style="font-family: 宋体">秒</span></p>
<p>MAP<span style="font-family: 宋体">性能测试查找花费</span>:<strong><span style="color: red">0.11</strong></span><span style="font-family: 宋体">秒</span></p>
<p>MAP<span style="font-family: 宋体">性能测试共花费</span>:<strong><span style="color: red">7.392</strong></span><span style="font-family: 宋体">秒</span></p>
<p>MAP<span style="font-family: 宋体">性能测试</span> <span style="font-family: 宋体">共占用</span>:<strong><span style="color: red">173554048</strong> </span><span style="font-family: 宋体">字节</span></p>
<p>2<span style="font-family: 宋体">、</span>5<span style="font-family: 宋体">百万条记录，总共查询</span>5<span style="font-family: 宋体">百万次（每条记录查询一次）</span></p>
<p><span style="font-family: 宋体">数组性能测试加载花费</span>:<strong><span style="color: red">6.078</strong></span><span style="font-family: 宋体">秒</span></p>
<p><span style="font-family: 宋体">数组性能测试排序花费</span>:<strong><span style="color: red">17.642</strong></span><span style="font-family: 宋体">秒</span></p>
<p><span style="font-family: 宋体">数组性能测试查找花费</span>:<strong><span style="color: red">33.049</strong></span><span style="font-family: 宋体">秒</span></p>
<p><span style="font-family: 宋体">数组性能测试共花费</span>:<strong><span style="color: red">56.769</strong></span><span style="font-family: 宋体">秒</span></p>
<p><span style="font-family: 宋体">数组性能测试总共占用</span> = <strong><span style="color: red">100005552</strong> </span><span style="font-family: 宋体">字节</span></p>
<p>RBTree<span style="font-family: 宋体">性能测试加载花费</span>:<strong><span style="color: red">54.8</strong></span><span style="font-family: 宋体">秒</span></p>
<p>RBTree<span style="font-family: 宋体">性能测试查找共花费</span>:<strong><span style="color: red">34.581</strong></span><span style="font-family: 宋体">秒</span></p>
<p>RBTree<span style="font-family: 宋体">性能测试共花费</span>:<strong><span style="color: red">89.381</strong></span><span style="font-family: 宋体">秒</span></p>
<p>RBTREE<span style="font-family: 宋体">性能测试共占用</span> = <strong><span style="color: red">240005024</strong> </span><span style="font-family: 宋体">字节</span></p>
<p>MAP<span style="font-family: 宋体">性能测试加载花费</span>:<strong><span style="color: red">6.501</strong></span><span style="font-family: 宋体">秒</span></p>
<p>MAP<span style="font-family: 宋体">性能测试查找花费</span>:<strong><span style="color: red">0.937</strong></span><span style="font-family: 宋体">秒</span></p>
<p>MAP<span style="font-family: 宋体">性能测试共花费</span>:<strong><span style="color: red">7.438</strong></span><span style="font-family: 宋体">秒</span></p>
<p>MAP<span style="font-family: 宋体">性能测试</span> <span style="font-family: 宋体">共占用</span>=<strong><span style="color: red">173553888</strong> </span><span style="font-family: 宋体">字节</span></p>
<p>3<span style="font-family: 宋体">、</span>5<span style="font-family: 宋体">百万条记录，总共查询</span>5<span style="font-family: 宋体">千万次（每条数据查询</span>10<span style="font-family: 宋体">次）</span></p>
<p style="text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 宋体">数组性能测试加载花费</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">:</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">6.11</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span></p>
<p style="text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 宋体">数组性能测试排序花费</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">:</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">17.861</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span></p>
<p style="text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 宋体">数组性能测试查找花费</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">:</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">331.224</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span></p>
<p style="text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 宋体">数组性能测试共花费</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">:</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">355.195</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span></p>
<p style="text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 宋体">数组性能测试总共占用</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">:</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">99990456</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">字节</span></p>
<p style="text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">RBTree</span><span style="font-size: 10pt; color: black; font-family: 宋体">性能测试加载花费</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">:</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">53.097</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span></p>
<p style="text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">RBTree</span><span style="font-size: 10pt; color: black; font-family: 宋体">性能测试查找共花费</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">:</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">345.866</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span></p>
<p style="text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">RBTree</span><span style="font-size: 10pt; color: black; font-family: 宋体">性能测试共花费</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">:</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">398.963</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span></p>
<p style="text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">RBTREE</span><span style="font-size: 10pt; color: black; font-family: 宋体">性能测试共占用</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'"> = </span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">240005248 </span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">字节</span></p>
<p style="text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">MAP</span><span style="font-size: 10pt; color: black; font-family: 宋体">性能测试加载花费</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">:</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">7.235</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span></p>
<p style="text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">MAP</span><span style="font-size: 10pt; color: black; font-family: 宋体">性能测试查找花费</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">:</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">9.375</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span></p>
<p style="text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">MAP</span><span style="font-size: 10pt; color: black; font-family: 宋体">性能测试共花费</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">:</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">16.61</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span></p>
<p style="text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">MAP</span><span style="font-size: 10pt; color: black; font-family: 宋体">性能测试</span><span style="font-size: 10pt; color: black; font-family: 宋体">共占用</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">:</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">173554048</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">字节<br />
<br />
测试文件地址：&nbsp; <a href="/Files/aoneany/search2.rar">/Files/aoneany/search2.rar</a><br />
<br />
================================================================<br />
&nbsp;&nbsp;&nbsp; </p>
<p class="MsoNormal"><span style="color: #1f497d; font-family: 宋体">前面的测试算法中，有一个地方偷懒（直接使用</span><span lang="EN-US" style="color: #1f497d">String.CompareTo</span><span style="color: #1f497d; font-family: 宋体">方法进行比较）导致查询效率很差，现在对其进行优化，测试后的数据为：</span><span lang="EN-US" style="color: #1f497d"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color: #1f497d"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">5</span><span style="font-family: 宋体">百万条记录，总共查询</span><span lang="EN-US">5</span><span style="font-family: 宋体">百万次（每条记录查询一次）</span><span lang="EN-US" style="color: #1f497d"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 宋体">数组性能测试加载花费</span><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'">:<span style="color: red"><strong>1.016</strong></span></span><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span><span lang="EN-US" style="font-size: 10pt; font-family: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 宋体">数组性能测试排序花费</span><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'">:<span style="color: red"><strong>14.485</strong></span></span><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span><span lang="EN-US" style="font-size: 10pt; font-family: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 宋体">数组性能测试查找花费</span><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'">:<span style="color: red"><strong>0.703</strong></span></span><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span><span lang="EN-US" style="font-size: 10pt; font-family: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 宋体">数组性能测试共花费</span><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'">:<strong style="color: red">16.204</strong></span><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-align: left" align="left"><span lang="EN-US" style="font-size: 10pt; font-family: 'Courier New'"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="text-align: left" align="left"><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'">RBTree</span><span style="font-size: 10pt; color: black; font-family: 宋体">性能测试加载花费</span><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'">:<strong style="color: red">20.705</strong></span><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span><span lang="EN-US" style="font-size: 10pt; font-family: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-align: left" align="left"><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'">RBTree</span><span style="font-size: 10pt; color: black; font-family: 宋体">性能测试查找共花费</span><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'">:<strong style="color: red">3.75</strong></span><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span><span lang="EN-US" style="font-size: 10pt; font-family: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-align: left" align="left"><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'">RBTree</span><span style="font-size: 10pt; color: black; font-family: 宋体">性能测试共花费</span><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'">:<strong style="color: red">24.455</strong></span><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-align: left" align="left"><span lang="EN-US" style="font-size: 10pt; font-family: 'Courier New'"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="text-align: left" align="left"><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'">MAP</span><span style="font-size: 10pt; color: black; font-family: 宋体">性能测试加载花费</span><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'">:<strong style="color: red">3.875</strong></span><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span><span lang="EN-US" style="font-size: 10pt; font-family: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-align: left" align="left"><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'">MAP</span><span style="font-size: 10pt; color: black; font-family: 宋体">性能测试查找花费</span><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'">:<strong style="color: red">1.516</strong></span><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span><span lang="EN-US" style="font-size: 10pt; font-family: 'Courier New'"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-align: left" align="left"><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'">MAP</span><span style="font-size: 10pt; color: black; font-family: 宋体">性能测试共花费</span><span lang="EN-US" style="font-size: 10pt; color: black; font-family: 'Courier New'">:<strong style="color: red">5.391</strong></span><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span></p>
</span></span>
<img src ="http://www.blogjava.net/aoneany/aggbug/348346.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aoneany/" target="_blank">沙漠中的鱼</a> 2011-04-15 13:39 <a href="http://www.blogjava.net/aoneany/articles/348346.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>遍历查找性能测试报告（If,Switch,Map,Array,RBTree）</title><link>http://www.blogjava.net/aoneany/articles/348129.html</link><dc:creator>沙漠中的鱼</dc:creator><author>沙漠中的鱼</author><pubDate>Tue, 12 Apr 2011 04:01:00 GMT</pubDate><guid>http://www.blogjava.net/aoneany/articles/348129.html</guid><wfw:comment>http://www.blogjava.net/aoneany/comments/348129.html</wfw:comment><comments>http://www.blogjava.net/aoneany/articles/348129.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aoneany/comments/commentRss/348129.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aoneany/services/trackbacks/348129.html</trackback:ping><description><![CDATA[&nbsp; <span style="font-family: 宋体">性能测试报告</span>
<p><span style="font-family: 宋体">场景一</span></p>
<p><span style="font-family: 宋体">有</span>1<span style="font-family: 宋体">，</span>2<span style="font-family: 宋体">，</span>3<span style="font-family: 宋体">，</span>4<span style="font-family: 宋体">，</span>5<span style="font-family: 宋体">个整数，分别对每个一数遍历</span>2<span style="font-family: 宋体">亿次，总共</span>10<span style="font-family: 宋体">亿次，在不同用例测试花费的时间如下</span></p>
<p><span style="font-size: 10pt; color: black; font-family: 'Courier New'">Switch</span><span style="font-size: 10pt; color: black; font-family: 宋体">测试</span></p>
<p><span style="font-size: 10pt; color: black; font-family: 宋体">总共花费</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">:</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">20.329</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span></p>
<p>IF<span style="font-family: 宋体">测试</span></p>
<p><span style="font-size: 10pt; color: black; font-family: 宋体">总共花费</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">:</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">20.437</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span></p>
<p><span style="font-size: 10pt; color: black; font-family: 'Courier New'">Array</span><span style="font-size: 10pt; color: black; font-family: 宋体">测试</span></p>
<p><span style="font-size: 10pt; color: black; font-family: 宋体">总共花费</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">:</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">20.703</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span></p>
<p><span style="font-size: 10pt; color: black; font-family: 'Courier New'">Map</span><span style="font-size: 10pt; color: black; font-family: 宋体">测试</span></p>
<p><span style="font-size: 10pt; color: black; font-family: 宋体">总共花费</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">:</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">56.719</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span></p>
<p><span style="font-family: 宋体">场景二</span></p>
<p><span style="font-family: 宋体">有</span>5<span style="font-family: 宋体">百万条数据，分别对每一个数据访问</span>10<span style="font-family: 宋体">次，总共查找</span>5<span style="font-family: 宋体">千万次，在不同用例测试花费的时间如下：</span></p>
<p>Map<span style="font-family: 宋体">测试</span></p>
<p><span style="font-family: 宋体">总共花费：</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">4.047</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">秒（自己对这结果很怀疑，但是测试几次都是这样）</span></p>
<p><span style="font-size: 10pt; color: black; font-family: 宋体">内存占用：</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">273579872</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">字节</span></p>
<p><span style="font-size: 10pt; color: black; font-family: 'Courier New'">CPU</span><span style="font-size: 10pt; color: black; font-family: 宋体">占用：</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">50%</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">左右</span></p>
<p>Array Comparable<span style="font-size: 10pt; color: black; font-family: 宋体">测试</span></p>
<p><span style="font-size: 10pt; color: black; font-family: 宋体">总共花费</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">: </span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">45.312</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span></p>
<p><span style="font-size: 10pt; color: black; font-family: 宋体">内存占用：</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">160025376</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">字节</span></p>
<p><span style="font-size: 10pt; color: black; font-family: 'Courier New'">CPU</span><span style="font-size: 10pt; color: black; font-family: 宋体">占用：</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">50%</strong></span><span style="font-size: 10pt; color: black; font-family: 宋体">左右</span></p>
<p><span style="font-size: 10pt; color: black; font-family: 'Courier New'">RBTree</span><span style="font-size: 10pt; color: black; font-family: 宋体">测试</span></p>
<p><span style="font-size: 10pt; color: black; font-family: 宋体">总共花费：</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">63.485</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">秒</span></p>
<p><span style="font-size: 10pt; color: black; font-family: 宋体">内存占用：</span><span style="font-size: 10pt; color: red; font-family: 'Courier New'">320030976</span><span style="font-size: 10pt; color: black; font-family: 宋体">字节</span></p>
<p><span style="font-size: 10pt; color: black; font-family: 'Courier New'">CPU</span><span style="font-size: 10pt; color: black; font-family: 宋体">占用：</span><strong><span style="font-size: 10pt; color: red; font-family: 'Courier New'">50%</span></strong><span style="font-size: 10pt; color: black; font-family: 宋体">左右<br />
<br />
<br />
测试文件地址：<a href="http://www.blogjava.net/Files/aoneany/search.rar">http://www.blogjava.net/Files/aoneany/search.rar</a></span></p>
<img src ="http://www.blogjava.net/aoneany/aggbug/348129.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aoneany/" target="_blank">沙漠中的鱼</a> 2011-04-12 12:01 <a href="http://www.blogjava.net/aoneany/articles/348129.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>类型信息-Thinking in java读书笔记</title><link>http://www.blogjava.net/aoneany/articles/304119.html</link><dc:creator>沙漠中的鱼</dc:creator><author>沙漠中的鱼</author><pubDate>Sun, 29 Nov 2009 11:23:00 GMT</pubDate><guid>http://www.blogjava.net/aoneany/articles/304119.html</guid><wfw:comment>http://www.blogjava.net/aoneany/comments/304119.html</wfw:comment><comments>http://www.blogjava.net/aoneany/articles/304119.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aoneany/comments/commentRss/304119.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aoneany/services/trackbacks/304119.html</trackback:ping><description><![CDATA[<p><strong>Class.forName("Gum");</strong></p>
<p>forName是取得Class引用的一种方法，返回一个Class对象的引用。</p>
<p>如果Gum类还没有被加载就加载它，在加载过程中，Gum的静态子句被执行。</p>
<p>可能产生的异常：ClassNotFoundException</p>
<p><strong>Class.getInterfaces("Gum")</strong></p>
<p>返回对象是Class类型，表示类Gum包含的接口</p>
<p>如类Gum implements interface1,</p>
<p>则会获取到interface1的类对象</p>
<p><strong>Class.newInstance()</strong></p>
<p>实现&#8220;虚拟构造器&#8221;的一种途径</p>
<p>&nbsp;</p>
<p><strong>类字面常量</strong></p>
<p>obj.Class生成对Class对象的引用，它比forName更加安全，因为它在编译时就接受检查。</p>
<p><span style="color: red">注意</span>:当使用.Class来创建Class对象的引用时，不会自动初始化Class对象。</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><img id="Codehighlighter1_14_179_Open_Image" onclick="this.style.display='none'; Codehighlighter1_14_179_Open_Text.style.display='none'; Codehighlighter1_14_179_Closed_Image.style.display='inline'; Codehighlighter1_14_179_Closed_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" /><img style="display: none" id="Codehighlighter1_14_179_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_14_179_Closed_Text.style.display='none'; Codehighlighter1_14_179_Open_Image.style.display='inline'; Codehighlighter1_14_179_Open_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" /><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Initable</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_14_179_Closed_Text"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_14_179_Open_Text"><span style="color: #000000">{<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">final</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;staticFinal</span><span style="color: #000000">=</span><span style="color: #000000">47</span><span style="color: #000000">;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">final</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;staticFinal2</span><span style="color: #000000">=</span><span style="color: #000000">ClassInitialization.rand.nextInt(</span><span style="color: #000000">1000</span><span style="color: #000000">);<br />
<img id="Codehighlighter1_128_177_Open_Image" onclick="this.style.display='none'; Codehighlighter1_128_177_Open_Text.style.display='none'; Codehighlighter1_128_177_Closed_Image.style.display='inline'; Codehighlighter1_128_177_Closed_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" /><img style="display: none" id="Codehighlighter1_128_177_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_128_177_Closed_Text.style.display='none'; Codehighlighter1_128_177_Open_Image.style.display='inline'; Codehighlighter1_128_177_Open_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_128_177_Closed_Text"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_128_177_Open_Text"><span style="color: #000000">{<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">Initialzing&nbsp;Initable</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000"><br />
<img id="Codehighlighter1_196_289_Open_Image" onclick="this.style.display='none'; Codehighlighter1_196_289_Open_Text.style.display='none'; Codehighlighter1_196_289_Closed_Image.style.display='inline'; Codehighlighter1_196_289_Closed_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" /><img style="display: none" id="Codehighlighter1_196_289_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_196_289_Closed_Text.style.display='none'; Codehighlighter1_196_289_Open_Image.style.display='inline'; Codehighlighter1_196_289_Open_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Initable2</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_196_289_Closed_Text"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_196_289_Open_Text"><span style="color: #000000">{<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;staticNonFinal</span><span style="color: #000000">=</span><span style="color: #000000">147</span><span style="color: #000000">;<br />
<img id="Codehighlighter1_237_287_Open_Image" onclick="this.style.display='none'; Codehighlighter1_237_287_Open_Text.style.display='none'; Codehighlighter1_237_287_Closed_Image.style.display='inline'; Codehighlighter1_237_287_Closed_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" /><img style="display: none" id="Codehighlighter1_237_287_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_237_287_Closed_Text.style.display='none'; Codehighlighter1_237_287_Open_Image.style.display='inline'; Codehighlighter1_237_287_Open_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_237_287_Closed_Text"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_237_287_Open_Text"><span style="color: #000000">{<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">Initialzing&nbsp;Initable2</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000"><br />
<img id="Codehighlighter1_306_398_Open_Image" onclick="this.style.display='none'; Codehighlighter1_306_398_Open_Text.style.display='none'; Codehighlighter1_306_398_Closed_Image.style.display='inline'; Codehighlighter1_306_398_Closed_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" /><img style="display: none" id="Codehighlighter1_306_398_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_306_398_Closed_Text.style.display='none'; Codehighlighter1_306_398_Open_Image.style.display='inline'; Codehighlighter1_306_398_Open_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Initable3</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_306_398_Closed_Text"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_306_398_Open_Text"><span style="color: #000000">{<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;staticNonFinal</span><span style="color: #000000">=</span><span style="color: #000000">74</span><span style="color: #000000">;<br />
<img id="Codehighlighter1_346_396_Open_Image" onclick="this.style.display='none'; Codehighlighter1_346_396_Open_Text.style.display='none'; Codehighlighter1_346_396_Closed_Image.style.display='inline'; Codehighlighter1_346_396_Closed_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" /><img style="display: none" id="Codehighlighter1_346_396_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_346_396_Closed_Text.style.display='none'; Codehighlighter1_346_396_Open_Image.style.display='inline'; Codehighlighter1_346_396_Open_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_346_396_Closed_Text"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_346_396_Open_Text"><span style="color: #000000">{<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">Initialzing&nbsp;Initable3</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000"><br />
<img id="Codehighlighter1_433_893_Open_Image" onclick="this.style.display='none'; Codehighlighter1_433_893_Open_Text.style.display='none'; Codehighlighter1_433_893_Closed_Image.style.display='inline'; Codehighlighter1_433_893_Closed_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" /><img style="display: none" id="Codehighlighter1_433_893_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_433_893_Closed_Text.style.display='none'; Codehighlighter1_433_893_Open_Image.style.display='inline'; Codehighlighter1_433_893_Open_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;ClassInitialization&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_433_893_Closed_Text"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_433_893_Open_Text"><span style="color: #000000">{<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;Random&nbsp;rand</span><span style="color: #000000">=</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Random(</span><span style="color: #000000">47</span><span style="color: #000000">);<br />
<img id="Codehighlighter1_517_891_Open_Image" onclick="this.style.display='none'; Codehighlighter1_517_891_Open_Text.style.display='none'; Codehighlighter1_517_891_Closed_Image.style.display='inline'; Codehighlighter1_517_891_Closed_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" /><img style="display: none" id="Codehighlighter1_517_891_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_517_891_Closed_Text.style.display='none'; Codehighlighter1_517_891_Open_Image.style.display='inline'; Codehighlighter1_517_891_Open_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;main(String[]&nbsp;args)</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_517_891_Closed_Text"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_517_891_Open_Text"><span style="color: #000000">{<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class&nbsp;initable</span><span style="color: #000000">=</span><span style="color: #000000">Initable.</span><span style="color: #0000ff">class</span><span style="color: #000000">;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">After&nbsp;creating&nbsp;Initable&nbsp;ref</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(Initable.staticFinal);<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(Initable.staticFinal2);<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(Initable2.staticNonFinal);<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class&nbsp;initable3</span><span style="color: #000000">=</span><span style="color: #000000">Class.forName(</span><span style="color: #000000">"</span><span style="color: #000000">Initable3</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">After&nbsp;creating&nbsp;Initable3&nbsp;ref</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(Initable3.staticNonFinal);<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span><span style="color: #000000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /></span></div>
<p>&nbsp;</p>
<p>输出结果为：</p>
<p>Initialzing Initable<br />
After creating Initable ref<br />
47<br />
258<br />
Initialzing Initable2<br />
147<br />
Initialzing Initable3<br />
After creating Initable3 ref<br />
74</p>
<p><strong>结论：</strong>如果一个static final值是"编译期常量"，就象Initable.staticFinal那样，那么这个值不需要对Initable类初使化就可以读取，但是如果只是将一个域设置为static和final的，如对Initable.staticFinal2的访问将进行强制的初使化，因为它不是一个编译型常量。</p>
<p>如果一个static而不是final的，那么在它访问时，总是要求进行链接（为这个域分配存储空间）和初始化（初始化该存储空间），就像对Initable2.staticNonFinal那样。</p>
<p><strong>泛化的Class引用</strong></p>
<p>Class&lt;Integer&gt; iniClass=int.class</p>
<p><strong>新的转型语法</strong></p>
<p>case()</p>
<p>InstanceOf</p>
<p><strong>反射</strong></p>
<p>getMethods()返回Method对象的数组</p>
<p>getConstructors()返回Contructor对象的数组</p>
<p><strong>动态代理</strong></p>
<p>实现InvocationHandler接口</p>
<p>public Object invoke(Objct proxy,Method method,Object[] args)throws Throwable｛｝方法</p>
<p>通过Proxy.newProxyInstance(ClassLoader,Class[],InvocationHandler)创建动态代理</p>
<p>具体示例参见:</p>
<p><a href="http://www.blogjava.net/aoneany/articles/271019.html" target="_blank">http://www.blogjava.net/aoneany/articles/271019.html</a></p><img src ="http://www.blogjava.net/aoneany/aggbug/304119.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aoneany/" target="_blank">沙漠中的鱼</a> 2009-11-29 19:23 <a href="http://www.blogjava.net/aoneany/articles/304119.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字符串-Thinking in Java读书笔记</title><link>http://www.blogjava.net/aoneany/articles/304020.html</link><dc:creator>沙漠中的鱼</dc:creator><author>沙漠中的鱼</author><pubDate>Sat, 28 Nov 2009 05:54:00 GMT</pubDate><guid>http://www.blogjava.net/aoneany/articles/304020.html</guid><wfw:comment>http://www.blogjava.net/aoneany/comments/304020.html</wfw:comment><comments>http://www.blogjava.net/aoneany/articles/304020.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aoneany/comments/commentRss/304020.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aoneany/services/trackbacks/304020.html</trackback:ping><description><![CDATA[<p>String对象是不可变的</p>
<p>Scanner扫描字符串对象。</p>
<p>备注：</p>
<p>在java编译好的class文件中,有个区域称为Constant Pool,他是一个由数组组成的表,类型<br />
为cp_info constant_pool[],用来存储程序中使用的各种常量,包括Class<span style="color: rgb(0,0,0)">/</span><span style="color: rgb(0,0,0)">String</span><span style="color: rgb(0,0,0)">/</span><span style="color: rgb(0,0,0)">Integer等各<br />
种基本Java数据类型,详情参见The Java Virtual Machine Specification </span><span style="color: rgb(0,0,0)">4</span><span style="color: rgb(0,0,0)">.4章节.<br />
<br />
对于Constant Pool,表的基本通用结构为:<br />
cp_info {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u1 tag;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u1 info[];<br />
}<br />
<br />
tag是一个数字,用来表示存储的常量的类型,例如8表示String类型,5表示Long类型,info[]根据<br />
类型码tag的不同会发生相应变化.<br />
对于String类型,表的结构为:<br />
CONSTANT_String_info {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u1 tag;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u2 string_index;<br />
}<br />
tag固定为8,string_index是字符串内容信息,类型为:<br />
CONSTANT_Utf8_info {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u1 tag;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u2 length;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u1 bytes[length];<br />
}<br />
tag固定为1,length为字符串的长度,bytes[length]为字符串的内容.<br />
<br />
<strong>代码样例<br />
</strong>(以下代码在jdk6中编译)<br />
为了详细理解Constant Pool的结构,我们参看一些代码:<br />
&nbsp;&nbsp;&nbsp; String s1 </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">sss111</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">;<br />
&nbsp;&nbsp;&nbsp; String s2 </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">sss222</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">;<br />
&nbsp;&nbsp;&nbsp; System.out.println(s1 </span><span style="color: rgb(0,0,0)">+</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">+</span><span style="color: rgb(0,0,0)"> s2);<br />
由于</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">sss111</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">和</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">sss222</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">都是字符串常量,在编译期就已经创建好了存储在class文件中.<br />
在编译后的class文件中会存在这2个常量的对应表示:<br />
</span><span style="color: rgb(0,0,0)">08</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">00</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">11</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">01</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">00</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">06</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">73</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">73</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">73</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">31</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">31</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">31</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">08</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">00</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">13</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">01</span><span style="color: rgb(0,0,0)"> ; ......sss111....<br />
</span><span style="color: rgb(0,0,0)">00</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">06</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">73</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">73</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">73</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">32</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">32</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">32</span><span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; ..sss222<br />
<br />
根据上面说的String常量结构,我们分析一下<br />
开始的08为CONSTANT_String_info结构中的tag,而11应该是它的相对引用,01为<br />
CONSTANT_Utf8_info的tag,06为对应字符串的长度,</span><span style="color: rgb(0,0,0)">73</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">73</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">73</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">31</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">31</span><span style="color: rgb(0,0,0)"> 31为字符串对<br />
应的编码,接着分析,会发现后面的是对应</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">sss222</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">的存储结构.<br />
<br />
经过上面分析,我们知道了11和13是两个字符串的相对引用,就可以修改class文件<br />
来修改打印的内容,把class文件中的<br />
</span><span style="color: rgb(0,0,0)">00</span><span style="color: rgb(0,0,0)"> 6E </span><span style="color: rgb(0,0,0)">00</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">04</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">00</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">03</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">00</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">00</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">00</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">24</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">12</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">10</span><span style="color: rgb(0,0,0)"> 4C </span><span style="color: rgb(0,0,0)">12</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">12</span><span style="color: rgb(0,0,0)"> 4D<br />
改成<br />
</span><span style="color: rgb(0,0,0)">00</span><span style="color: rgb(0,0,0)"> 6E </span><span style="color: rgb(0,0,0)">00</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">04</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">00</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">03</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">00</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">00</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">00</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">24</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">12</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">10</span><span style="color: rgb(0,0,0)"> 4C </span><span style="color: rgb(0,0,0)">12</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">10</span><span style="color: rgb(0,0,0)"> 4D<br />
程序就会输出sss111 sss111,而不是和原程序一样输出sss111 sss222,因为我<br />
们把对</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">sss222</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">的相对引用12改成了对</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">sss111</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">的相对引用10.<br />
<br />
</span><span style="color: rgb(0,0,0)">------------</span><span style="color: rgb(0,0,0)">分割线<br />
</span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">class</span><span style="color: rgb(0,0,0)"> Test {<br />
&nbsp;&nbsp;&nbsp; </span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">void</span><span style="color: rgb(0,0,0)"> main(String[] args) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s1 </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">sss111</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s2 </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">sss111</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">;<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
<br />
在上面程序中存在2个相同的常量</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">sss111</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">,对于n个值相同的String常量,在Constant Pool中<br />
只会创建一个,所以在编译好的class文件中,我们只能找到一个对</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">sss111</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">的表示:<br />
000000abh: </span><span style="color: rgb(0,0,0)">08</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">00</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">11</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">01</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">00</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">06</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">73</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">73</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">73</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">31</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">31</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,0)">31</span><span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; ......sss111<br />
<br />
在程序执行的时候,Constant Pool会储存在Method Area,而不是heap中.<br />
<br />
另外,对于</span><span style="color: rgb(0,0,0)">""</span><span style="color: rgb(0,0,0)">内容为空的字符串常量,会创建一个长度为0,内容为空的字符串放到Constant Pool中,<br />
而且Constant Pool在运行期是可以动态扩展的.<br />
<br />
<strong>关于String类的说明<br />
<br />
</strong></span><span style="color: rgb(0,0,0)">1</span><span style="color: rgb(0,0,0)">.String使用private </span><span style="color: rgb(0,0,255)">final</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">char</span><span style="color: rgb(0,0,0)"> value[]来实现字符串的存储,也就是说String对象创建之后,就不能<br />
再修改此对象中存储的字符串内容,就是因为如此,才说String类型是不可变的(immutable).<br />
<br />
</span><span style="color: rgb(0,0,0)">2</span><span style="color: rgb(0,0,0)">.String类有一个特殊的创建方法,就是使用</span><span style="color: rgb(0,0,0)">""</span><span style="color: rgb(0,0,0)">双引号来创建.例如new String(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">i am</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">)实际创建了2个<br />
String对象,一个是</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">i am</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">通过</span><span style="color: rgb(0,0,0)">""</span><span style="color: rgb(0,0,0)">双引号创建的,另一个是通过new创建的.只不过他们创建的时期不同,<br />
一个是编译期,一个是运行期</span><span style="color: rgb(0,0,0)">!</span><span style="color: rgb(0,0,0)"><br />
<br />
</span><span style="color: rgb(0,0,0)">3</span><span style="color: rgb(0,0,0)">.java对String类型重载了</span><span style="color: rgb(0,0,0)">+</span><span style="color: rgb(0,0,0)">操作符,可以直接使用</span><span style="color: rgb(0,0,0)">+</span><span style="color: rgb(0,0,0)">对两个字符串进行连接.<br />
<br />
</span><span style="color: rgb(0,0,0)">4</span><span style="color: rgb(0,0,0)">.运行期调用String类的intern()方法可以向String Pool中动态添加对象.<br />
<br />
<strong>String的创建方法</strong><br />
<br />
一般有如下几种<br />
</span><span style="color: rgb(0,0,0)">1</span><span style="color: rgb(0,0,0)">.直接使用</span><span style="color: rgb(0,0,0)">""</span><span style="color: rgb(0,0,0)">引号创建.<br />
</span><span style="color: rgb(0,0,0)">2</span><span style="color: rgb(0,0,0)">.使用new String()创建.<br />
</span><span style="color: rgb(0,0,0)">3</span><span style="color: rgb(0,0,0)">.使用new String(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">someString</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">)创建以及其他的一些重载构造函数创建.<br />
</span><span style="color: rgb(0,0,0)">4</span><span style="color: rgb(0,0,0)">.使用重载的字符串连接操作符</span><span style="color: rgb(0,0,0)">+</span><span style="color: rgb(0,0,0)">创建.</span></p>
<p><span style="color: rgb(0,0,0)"><strong>面试题:</strong></span></p>
<p><span style="color: rgb(0,0,0)">String s1 <span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)"> String(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">s1</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">) ;<br />
String s2 </span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)"> </span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)"> String(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">s1</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">) ;<br />
上面创建了几个String对象</span><span style="color: rgb(0,0,0)">?</span><span style="color: rgb(0,0,0)"><br />
答案:3个 ,编译期Constant Pool中创建1个,运行期heap中创建2个.</span></p>
<p><br />
</p>
</span>
<img src ="http://www.blogjava.net/aoneany/aggbug/304020.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aoneany/" target="_blank">沙漠中的鱼</a> 2009-11-28 13:54 <a href="http://www.blogjava.net/aoneany/articles/304020.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>最简单的web服务器代码(Java)</title><link>http://www.blogjava.net/aoneany/articles/283248.html</link><dc:creator>沙漠中的鱼</dc:creator><author>沙漠中的鱼</author><pubDate>Fri, 19 Jun 2009 08:36:00 GMT</pubDate><guid>http://www.blogjava.net/aoneany/articles/283248.html</guid><wfw:comment>http://www.blogjava.net/aoneany/comments/283248.html</wfw:comment><comments>http://www.blogjava.net/aoneany/articles/283248.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aoneany/comments/commentRss/283248.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aoneany/services/trackbacks/283248.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: HttpServer.javapackage&nbsp;htmlbrowser;import&nbsp;java.io.File;import&nbsp;java.io.FileInputStream;import&nbsp;java.io.FileOutputStream;import&nbsp;java.util.Properties;import&nbsp;jav...&nbsp;&nbsp;<a href='http://www.blogjava.net/aoneany/articles/283248.html'>阅读全文</a><img src ="http://www.blogjava.net/aoneany/aggbug/283248.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aoneany/" target="_blank">沙漠中的鱼</a> 2009-06-19 16:36 <a href="http://www.blogjava.net/aoneany/articles/283248.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java实现一个用户在同一时间只登陆一次</title><link>http://www.blogjava.net/aoneany/articles/272005.html</link><dc:creator>沙漠中的鱼</dc:creator><author>沙漠中的鱼</author><pubDate>Thu, 21 May 2009 08:02:00 GMT</pubDate><guid>http://www.blogjava.net/aoneany/articles/272005.html</guid><wfw:comment>http://www.blogjava.net/aoneany/comments/272005.html</wfw:comment><comments>http://www.blogjava.net/aoneany/articles/272005.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aoneany/comments/commentRss/272005.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aoneany/services/trackbacks/272005.html</trackback:ping><description><![CDATA[<p>保证网站用户（或管理员）在同一时间只登陆一次在很多场合是很必要的！下面举一个基于Java平台实现的例子。<br />
&nbsp;&nbsp;&nbsp; <strong>第一步：创建SessionListenter类</strong></p>
<p>&nbsp;</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;javax.servlet.http.HttpSession;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;javax.servlet.http.HttpSessionEvent;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;javax.servlet.http.HttpSessionListener;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;org.apache.log4j.Logger;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;org.jpxx.sw.Constants;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;org.jpxx.sw.Factory;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_222_353_Open_Image" onclick="this.style.display='none'; Codehighlighter1_222_353_Open_Text.style.display='none'; Codehighlighter1_222_353_Closed_Image.style.display='inline'; Codehighlighter1_222_353_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_222_353_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_222_353_Closed_Text.style.display='none'; Codehighlighter1_222_353_Open_Image.style.display='inline'; Codehighlighter1_222_353_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_222_353_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">/**&nbsp;*/</span><span id="Codehighlighter1_222_353_Open_Text"><span style="color: #008000">/**</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;该监听器用于监听后台管理员登陆。只允许统一管理员在同一时间登陆一次。<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;</span><span style="color: #808080">@author</span><span style="color: #008000">&nbsp;Jun&nbsp;Li<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;</span><span style="color: #808080">@version</span><span style="color: #008000">&nbsp;&nbsp;$Revision:&nbsp;1.0.2&nbsp;$,&nbsp;$Date:&nbsp;2009/01/05&nbsp;$<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;</span><span style="color: #808080">@since</span><span style="color: #008000">&nbsp;1.0.0<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img id="Codehighlighter1_415_1053_Open_Image" onclick="this.style.display='none'; Codehighlighter1_415_1053_Open_Text.style.display='none'; Codehighlighter1_415_1053_Closed_Image.style.display='inline'; Codehighlighter1_415_1053_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_415_1053_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_415_1053_Closed_Text.style.display='none'; Codehighlighter1_415_1053_Open_Image.style.display='inline'; Codehighlighter1_415_1053_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;SessionListener&nbsp;</span><span style="color: #0000ff">implements</span><span style="color: #000000">&nbsp;HttpSessionListener&nbsp;</span><span id="Codehighlighter1_415_1053_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_415_1053_Open_Text"><span style="color: #000000">{&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;Logger&nbsp;log&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;Factory.getSingletonInstance().getLogger(SessionListener.</span><span style="color: #0000ff">class</span><span style="color: #000000">);<br />
<img id="Codehighlighter1_556_562_Open_Image" onclick="this.style.display='none'; Codehighlighter1_556_562_Open_Text.style.display='none'; Codehighlighter1_556_562_Closed_Image.style.display='inline'; Codehighlighter1_556_562_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_556_562_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_556_562_Closed_Text.style.display='none'; Codehighlighter1_556_562_Open_Image.style.display='inline'; Codehighlighter1_556_562_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;sessionCreated(HttpSessionEvent&nbsp;event)&nbsp;</span><span id="Codehighlighter1_556_562_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_556_562_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_623_1051_Open_Image" onclick="this.style.display='none'; Codehighlighter1_623_1051_Open_Text.style.display='none'; Codehighlighter1_623_1051_Closed_Image.style.display='inline'; Codehighlighter1_623_1051_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_623_1051_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_623_1051_Closed_Text.style.display='none'; Codehighlighter1_623_1051_Open_Image.style.display='inline'; Codehighlighter1_623_1051_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;sessionDestroyed(HttpSessionEvent&nbsp;event)&nbsp;</span><span id="Codehighlighter1_623_1051_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_623_1051_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpSession&nbsp;session&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;event.getSession();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;获取存储管理员的session</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;o&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;session.getAttribute(Constants.JPXX_ADMIN_LOGIN_USERNAME_SESSION);<br />
<img id="Codehighlighter1_807_1045_Open_Image" onclick="this.style.display='none'; Codehighlighter1_807_1045_Open_Text.style.display='none'; Codehighlighter1_807_1045_Closed_Image.style.display='inline'; Codehighlighter1_807_1045_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_807_1045_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_807_1045_Closed_Text.style.display='none'; Codehighlighter1_807_1045_Open_Image.style.display='inline'; Codehighlighter1_807_1045_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(o</span><span style="color: #000000">!=</span><span style="color: #0000ff">null</span><span style="color: #000000">)</span><span id="Codehighlighter1_807_1045_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_807_1045_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;userName&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;o.toString();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;登陆的用户都存储在Hashtable中，用户退出，从Hashtable中删除该用户</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Factory.getUsers().remove(userName);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.error(</span><span style="color: #000000">"</span><span style="color: #000000">删除用户：</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;userName&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;java.util.Date());<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
说明：由于该类来自于项目，有很多操作都进行了封装，您稍作修改即可正常使用。注释掉Logger，声明一个静态变量private static Hashtable user = new Hashtable();在sessionCreated()方法中将刚登陆的用户添加到user中。您还需要写注销的页面（jsp或者servlet），在页面里面调用session.invalidate(); 该方法会触发sessionDestroyed()事件！<br />
<br />
&nbsp;<strong>&nbsp;&nbsp; 第二部：将该监听器注册到web.xml<br />
</strong>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">listener</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">listener-class</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">org.jpxx.sw.business.SessionListener</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">listener-class</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">listener</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
说明：仅仅依靠session监听器不可能100%可靠，有可能用户不正常退出(例如直接关闭浏览器、系统断电等等)。针对直接关闭浏览器有如下解决方案：在被关闭的页面里面插入如下语句：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">body&nbsp;</span><span style="color: #ff0000">scroll</span><span style="color: #0000ff">="no"</span><span style="color: #ff0000">&nbsp;onUnload</span><span style="color: #0000ff">="Jpxx.forceLogout();"</span><span style="color: #ff0000">&nbsp;onbeforeunload</span><span style="color: #0000ff">="Jpxx.forceLogout();"</span><span style="color: #0000ff">&gt;</span></div>
<p>Jpxx.forceLogout()方法通过AJAX技术来强制注销用户，即调用session.invalidate()方法。 </p>
转载:<a href="http://www.jpxx.org/?tid=54">http://www.jpxx.org/?tid=54</a>
<img src ="http://www.blogjava.net/aoneany/aggbug/272005.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aoneany/" target="_blank">沙漠中的鱼</a> 2009-05-21 16:02 <a href="http://www.blogjava.net/aoneany/articles/272005.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用JAVA的动态属性之反射原理实现一个简单AOP容器 - AOP的实现原理分析</title><link>http://www.blogjava.net/aoneany/articles/271053.html</link><dc:creator>沙漠中的鱼</dc:creator><author>沙漠中的鱼</author><pubDate>Sat, 16 May 2009 14:25:00 GMT</pubDate><guid>http://www.blogjava.net/aoneany/articles/271053.html</guid><wfw:comment>http://www.blogjava.net/aoneany/comments/271053.html</wfw:comment><comments>http://www.blogjava.net/aoneany/articles/271053.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aoneany/comments/commentRss/271053.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aoneany/services/trackbacks/271053.html</trackback:ping><description><![CDATA[<span>AOP：Aspect Oriented Programming，意为面向切面/局部的程序设计。它是面向对象的程序设计的一种延伸。<br />
<br />
本文试图通过使用Java本身的动态属性，来实现一个具有简单的AOP功能的容器。</span>
<div><br />
开始理解起来可能比较费劲，但我们可以通过一个通俗说明来这样理解AOP的概念，就是使用AOP可以不用修改原有的代码，而可以追加新的功能。<br />
<br />
比如，我们用AOP实现了用户登陆（判断ID与密码是否正确）功能，现在我们要求在用户登陆时用LOG记录用户登陆的情况。一般的做法是直接修改已有的登陆逻辑代码，但使用AOP，可以不用修改原有的代码而完成此功能。<br />
<br />
<br />
本文试图通过使用Java本身的动态代理功能，来实现一个具有简单的AOP功能的容器。从而帮助大家对AOP有个大概的认识。<br />
<br />
<div class="tf_edit_html_title1">Java动态代理功能</div>
首先，我们简单介绍一下Java动态代理功能。JAVA的动态代理功能主要通过java.lang.reflect.Proxy类与java.lang.reflect.InvocationHandler接口完成，这里正是通过它们实现一个简单的AOP容器的。其实，像JBoss AOP等其他动态AOP框架也都是通过Proxy和InvocationHandler来实现的。<br />
<br />
<br />
<ul>
    <li>Java从JDK1.3开始提供动态代理（Java Proxy）功能。
    <li>所谓动态代理，即通过代理类：Proxy的代理，接口和实现类之间可以不直接发生联系，而可以在运行期（Runtime）实现动态关联。
    <li>AOP（Aspect Oriented Programming）：面向切面编程，其中的一种实现方法便是用Proxy来实现的。
    <li>Java Proxy只能代理接口，不能代理类。
    <li>Java Proxy功能主要通过java.lang.reflect.Proxy类与java.lang.reflect.InvocationHandler接口实现。
    <li>java.lang.reflect.Proxy （代理类） &gt; ProxyInterface（被代理的接口）&nbsp;&nbsp; &gt; InvocationHandler（关联类）&gt; Class（可以在InvocationHandler中被调用）。它们之间的关系可以用下面的流程图来表示： </li>
</ul>
<br />
<br />
<div class="tf_edit_html_box6">动态代理类：Proxy 被代理的接口 InvocationHandler实现类 代理类</div>
<br />
&nbsp;&nbsp;&nbsp;&nbsp; 实际上的调用关系可以用下面的流程图来表示:<br />
<div class="tf_edit_html_box6">
<div align="center"><br />
Proxy.newProxyInstance<br />
<br />
XxxxInterface xx = $ProxyN(N=0,1,2&#8230;)<br />
<br />
XxxxInterface.calledMethod<br />
<br />
$ProxyN.calledMethod<br />
<br />
InvocationHandler.invoke<br />
<br />
method.invoke(obj, args)<br />
<br />
obj.calledMethod</div>
</div>
<ol>
    <li>Proxy. newProxyInstance的参数：必须传送以下3个参数给Proxy. newProxyInstance方法：ClassLoader，Class[]，InvocationHandler。其中参数2为被代理的接口 Class，参数3为实现InvocationHandler接口的实例。
    <li>可以通过Proxy. newProxyInstance方法得到被代理的接口的一个实例（instance），该实例由newProxyInstance方法动态生成，并实现了该接口。
    <li>当程序显示调用接口的方法时，其时是调用该实例的方法，此方法又会调用与该实例相关联InvocationHandler的invoke方法。
    <li>这样我们可以在InvocationHandler.invoke方法里调用某些处理逻辑或真正的逻辑处理实现类。 </li>
</ol>
<br />
<br />
<br />
<div class="tf_edit_html_title1">用Java Proxy实现AOP容器</div>
下面我们使用Java Proxy来实现一个简单的AOP容器。<br />
文件列表：<br />
<table class="defTbl FCK__ShowTableBorders">
    <tbody>
        <tr class="altEventRow">
            <th>文件名</th>
            <th>说明</th>
        </tr>
        <tr class="eventRow">
            <td>AopInvocationHandlerImpl.java</td>
            <td>该类实现了java.lang.reflect.InvocationHandler接口，我们通过它记录LOG信息</td>
        </tr>
        <tr class="altEventRow">
            <td>AopContainer.java</td>
            <td>简单的AOP容器，通过它把IDoBusiness与AopInvocationHandlerImpl关联起来</td>
        </tr>
        <tr class="eventRow">
            <td>IDoBusiness.java</td>
            <td>逻辑处理接口</td>
        </tr>
        <tr class="altEventRow">
            <td>DoBusiness.java</td>
            <td>逻辑处理实现类</td>
        </tr>
        <tr class="eventRow">
            <td>TestAop.java</td>
            <td>测试类</td>
        </tr>
    </tbody>
</table>
<br />
简单的AOP容器：<br />
AopContainer.java<br />
<div class="tf_edit_html_code"><span style="font-weight: bold; color: #7f0055">package</span> com.test.aop.framework;<br />
<br />
<span style="font-weight: bold; color: #7f0055">import</span> java.lang.reflect.Proxy;<br />
<br />
<span style="color: #3f5fbf">/**<br />
* A Simple AOP Container<br />
*<br />
*/</span><br />
<span style="font-weight: bold; color: #7f0055">public</span> <span style="font-weight: bold; color: #7f0055">class</span> AopContainer {<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055">public</span> <span style="font-weight: bold; color: #7f0055">static</span> &lt;T&gt; T getBean(Class&lt;T&gt; interfaceClazz, <span style="font-weight: bold; color: #7f0055">final</span> T obj) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assert interfaceClazz.isInterface();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055">return</span> (T) Proxy.newProxyInstance(interfaceClazz.getClassLoader(),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055">new</span> Class[] { interfaceClazz }, <span style="font-weight: bold; color: #7f0055">new</span> AopInvocationHandlerImpl(obj));<br />
&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055">public</span> <span style="font-weight: bold; color: #7f0055">static</span> Object getBean(<span style="font-weight: bold; color: #7f0055">final</span> Object obj) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055">return</span> Proxy.newProxyInstance(obj.getClass().getClassLoader(),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; obj.getClass().getInterfaces(), <span style="font-weight: bold; color: #7f0055">new</span> AopInvocationHandlerImpl(obj));<br />
&nbsp;&nbsp;&nbsp;&nbsp; }<br />
}</div>
第一个getBean方法通过2个参数（第一个参数为被代理的接口，第二个参数为被代理的类实例）<br />
第二个getBean方法只有一个参数，就是类的实例。该类必须实现1个以上的接口。本文的例子并没有使用到该方法，所以这里顺便介绍一下它的使用方法。比如有一个类HelloWorld实现了接口IHelloWorld1和IHelloWorld2，那么可以通过<br />
<div class="tf_edit_html_code">HelloWorld helloWorld = <span style="font-weight: bold; color: #7f0055">new</span> HelloWorld();<br />
IHelloWorld1 helloWorld1 = (IHelloWorld1)AopContainer.getBean(helloWorld);<br />
<span style="color: #3f7f5f">//或<br />
</span>IHelloWorld2 helloWorld2 = (IHelloWorld2)AopContainer.getBean(helloWorld);</div>
调用。当然很多时候都不会直接用new HelloWorld()生成HelloWorld实例，这里为了简便，就直接用new生成HelloWorld实例了。<br />
<br />
实现InvocationHandler接口的中间类：<br />
AopInvocationHandlerImpl.java<br />
<div class="tf_edit_html_code"><span style="font-weight: bold; color: #7f0055">package</span> com.test.aop.framework;<br />
<br />
<span style="font-weight: bold; color: #7f0055">import</span> java.lang.reflect.InvocationHandler;<br />
<span style="font-weight: bold; color: #7f0055">import</span> java.lang.reflect.Method;<br />
<br />
<span style="font-weight: bold; color: #7f0055">public</span> <span style="font-weight: bold; color: #7f0055">class</span> AopInvocationHandlerImpl <span style="font-weight: bold; color: #7f0055">implements</span> InvocationHandler {<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055">private</span> Object bizPojo;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055">public</span> AopInvocationHandlerImpl(Object bizPojo) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.bizPojo = bizPojo;<br />
&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #3f7f5f">/*<br />
&nbsp;&nbsp;&nbsp;&nbsp; * (non - Javadoc)<br />
&nbsp;&nbsp;&nbsp;&nbsp; * <br />
&nbsp;&nbsp;&nbsp;&nbsp; * <span style="font-weight: bold; color: #7f9fbf">@see</span> java.lang.reflect.InvocationHandler#invoke(java.lang.Object,<br />
&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.lang.reflect.Method, java.lang.Object[])<br />
&nbsp;&nbsp;&nbsp;&nbsp; */</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055">public</span> Object invoke(Object proxy, Method method, Object[] args)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055">throws</span> Throwable {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object o = null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055">try</span> {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("<span style="color: #2a00ff">Start:</span>" + method.getName());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o = method.invoke(bizPojo, args);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("<span style="color: #2a00ff">End:</span>" + method.getName());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <span style="font-weight: bold; color: #7f0055">catch</span> (Exception e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("<span style="color: #2a00ff">Exception Occured!</span>" + e.getMessage());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #3f7f5f">// excetpion handling.<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055">return</span> o;<br />
&nbsp;&nbsp;&nbsp;&nbsp; }<br />
}</div>
AopInvocationHandlerImpl.invoke方法的第一个参数为代理类，在我们这个例子里为java.lang.reflect.Proxy类的一个实例。第二个参数Method，为被代理的接口的方法调用（实际上是自动生成代理类的方法调用），第三个方法为方法调用的参数。<br />
我们通过在AopInvocationHandlerImpl.invoke方法里的method.invoke(bizPojo, args)来调用bizPojo类的与被代理接口的同名方法。这里，bizPojo必须实现了被代理的接口。<br />
在我们的例子里，我们在实际上被调用的业务逻辑方法的前后输出了日志信息。<br />
<br />
实际上的逻辑处理类。该类实现了被代理的接口：IDoBusiness。 <br />
DoBusiness.java<br />
<div class="tf_edit_html_code"><span style="font-weight: bold; color: #7f0055">package</span> com.test.aop.framework;<br />
<br />
<span style="color: #3f5fbf">/**<br />
* A business class<br />
*<br />
*/</span><br />
<span style="font-weight: bold; color: #7f0055">public</span> <span style="font-weight: bold; color: #7f0055">class</span> DoBusiness <span style="font-weight: bold; color: #7f0055">implements</span> IDoBusiness {<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055">public</span> <span style="font-weight: bold; color: #7f0055">void</span> printNothing() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("<span style="color: #2a00ff">Just Say Hello!</span>");<br />
&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055">public</span> <span style="font-weight: bold; color: #7f0055">void</span> throwException() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055">throw</span> <span style="font-weight: bold; color: #7f0055">new</span> RuntimeException("<span style="color: #2a00ff">throw Exception from DoBusiness.throwException()</span>");<br />
&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
}</div>
<br />
被代理的接口定义：<br />
IDoBusiness.java<br />
<div class="tf_edit_html_code"><span style="font-weight: bold; color: #7f0055">package</span> com.test.aop.framework;<br />
<br />
<span style="color: #3f5fbf">/**<br />
* interface for business logic process<br />
*<br />
*/</span><br />
<span style="font-weight: bold; color: #7f0055">public</span> <span style="font-weight: bold; color: #7f0055">interface</span> IDoBusiness {<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055">public</span> <span style="font-weight: bold; color: #7f0055">void</span> printNothing();<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055">public</span> <span style="font-weight: bold; color: #7f0055">void</span> throwException();<br />
}</div>
<br />
测试类：<br />
TestAop.java<br />
<div class="tf_edit_html_code"><span style="font-weight: bold; color: #7f0055">package</span> com.test.aop.framework;<br />
<br />
<br />
<span style="color: #3f5fbf">/**<br />
* Test AOP<br />
*<br />
*/</span><br />
<span style="font-weight: bold; color: #7f0055">public</span> <span style="font-weight: bold; color: #7f0055">class</span> TestAop {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #3f5fbf">/**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * <span style="font-weight: bold; color: #7f9fbf">@param</span> args<br />
&nbsp;&nbsp;&nbsp;&nbsp; */</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold; color: #7f0055">public</span> <span style="font-weight: bold; color: #7f0055">static</span> <span style="font-weight: bold; color: #7f0055">void</span> main(String[] args) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DoBusiness doBusiness = <span style="font-weight: bold; color: #7f0055">new</span> DoBusiness();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IDoBusiness idoBusiness = AopContainer.getBean(IDoBusiness.class, doBusiness);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; idoBusiness.printNothing();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; idoBusiness.throwException();<br />
&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
}</div>
<br />
<strong>总结：</strong><br />
本文通过Java Proxy实现了一个简单地AOP容器。也简单地展示了AOP的基本实现原理，实际上可以以此为基础实现一个功能完善的AOP容器。</div>
<p>&nbsp;</p>
<p>转载:<a href="http://hi.baidu.com/e9151/blog/item/9c8d772be0319d305243c130.html">http://hi.baidu.com/e9151/blog/item/9c8d772be0319d305243c130.html</a><br />
</p>
<img src ="http://www.blogjava.net/aoneany/aggbug/271053.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aoneany/" target="_blank">沙漠中的鱼</a> 2009-05-16 22:25 <a href="http://www.blogjava.net/aoneany/articles/271053.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于InvocationHandler接口</title><link>http://www.blogjava.net/aoneany/articles/271019.html</link><dc:creator>沙漠中的鱼</dc:creator><author>沙漠中的鱼</author><pubDate>Sat, 16 May 2009 10:53:00 GMT</pubDate><guid>http://www.blogjava.net/aoneany/articles/271019.html</guid><wfw:comment>http://www.blogjava.net/aoneany/comments/271019.html</wfw:comment><comments>http://www.blogjava.net/aoneany/articles/271019.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aoneany/comments/commentRss/271019.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aoneany/services/trackbacks/271019.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 动态代理是很多框架和技术的基础, spring 的AOP实现就是基于动态代理实现的。了解动态代理的机制对于理解AOP的底层实现是很有帮助的。
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看doc文档就可以知道，在java.lang.reflect包中有一个叫Proxy的类。下面是doc文档对Proxy类的说明：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "A <em>dynamic proxy class</em> (simply referred to as a <em>proxy class</em> below) is a class that implements a list of interfaces specified at runtime when the class is created, with behavior as described below. A <em>proxy interface</em> is such an interface that is implemented by a proxy class. A <em>proxy instance</em> is an instance of a proxy class. Each proxy instance has an associated <em>invocation handler</em> object, which implements the interface <a title="interface in java.lang.reflect" href="file:///E:/Java/docs/api/java/lang/reflect/InvocationHandler.html"><code>InvocationHandler</code></a>."</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Proxy类的设计用到代理模式的设计思想，Proxy类对象实现了代理目标的所有接口，并代替目标对象进行实际的操作。但这种替代不是一种简单的替代，这样没有任何意义，代理的目的是在目标对象方法的基础上作增强，这种增强的本质通常就是对目标对象的方法进行拦截。所以，Proxy应该包括一个方法拦截器，来指示当拦截到方法调用时作何种处理。InvocationHandler就是拦截器的接口。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InvocationHandler接口也是在java.lang.reflec</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object <a href="file:///E:/Java/docs/api/java/lang/reflect/InvocationHandler.html#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])"><strong><font face="Courier New">invoke</font></strong></a><font face="Courier New">(</font><a title="class in java.lang" href="file:///E:/Java/docs/api/java/lang/Object.html"><font face="Courier New">Object</font></a><font face="Courier New">&nbsp;proxy, </font><a title="class in java.lang.reflect" href="file:///E:/Java/docs/api/java/lang/reflect/Method.html"><font face="Courier New">Method</font></a><font face="Courier New">&nbsp;method, </font><a title="class in java.lang" href="file:///E:/Java/docs/api/java/lang/Object.html"><font face="Courier New">Object</font></a><font face="Courier New">[]&nbsp;args)</font> </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 这个接口有三个参数，其中第二和第三个参数都比较好理解，一个是被拦截的方法，一个是该方法的参数列表。关键是第一个参数。按照doc文档的解析，</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<font face="Courier New">proxy</font> - the proxy instance that the method was invoked on</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;也就是说，proxy应该是一个代理实例，但为什么要传入这个参数呢？</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 带着这个问题，自己编了个小程序作了一点试验。</p>
<p>///////////////////////////////////////</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public interface IAnimal {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void info();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>////////////////////////////////////</p>
<p>&nbsp;&nbsp;&nbsp; public class Dog implements IAnimal</p>
<p>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;public void info() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("I am a dog!");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>///////////////////////////////////////<br />
import java.lang.reflect.*;</p>
<p>public class ProxyTest {<br />
&nbsp;public static void main(String[] args) throws InterruptedException {<br />
&nbsp;&nbsp;final IAnimal animal = new Dog();<br />
&nbsp;&nbsp;Object proxyObj =Proxy.newProxyInstance(<br />
&nbsp;&nbsp;&nbsp;&nbsp;animal.getClass().getClassLoader(), <br />
&nbsp;&nbsp;&nbsp;&nbsp;animal.getClass().getInterfaces(), <br />
&nbsp;&nbsp;&nbsp;&nbsp;new InvocationHandler()<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public Object invoke(Object proxy, Method method, Object[] args) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("被拦截的方法:" + method.getName());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return method.invoke(animal, args);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch (IllegalArgumentException e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// TODO Auto-generated catch block<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch (IllegalAccessException e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// TODO Auto-generated catch block<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch (InvocationTargetException e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// TODO Auto-generated catch block<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;});<br />
&nbsp;&nbsp;if(proxyObj instanceof IAnimal)<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;System.out.println("the proxyObj is an animal!");<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;else<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;System.out.println("the proxyObj isn't an animal!");<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;if(proxyObj instanceof Dog)<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;System.out.println("the proxyObj is a dog!");<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;else<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;System.out.println("the proxyObj isn't a dog!");<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;IAnimal animalProxy = (IAnimal)proxyObj;<br />
&nbsp;&nbsp;animalProxy.info();<br />
&nbsp;&nbsp;animalProxy.hashCode();<br />
&nbsp;&nbsp;System.out.println(animalProxy.getClass().getName().toString());<br />
&nbsp;}<br />
}</p>
<p>程序执行的结果如下：</p>
<p>the proxyObj is an animal!<br />
the proxyObj isn't a dog!<br />
被拦截的方法:info<br />
I am a dog!<br />
被拦截的方法:hashCode<br />
$Proxy0</p>
<p>从结果可以看出以下几点：</p>
<p>1. proxyObj 是一个实现了目标对象接口的对象，而不同于目标对象。也就是说，这种代理机制是面向接口，而不是面向类的。</p>
<p>2. info方法(在接口中)被成功拦截了，hashCode方法也成功被拦截了，但意外的是，getClass方法(继承自Object 类的方法)并没有被拦截！！</p>
<p>3. 应用调试还可以看出Invocation接口中invoke方法的传入的proxy参数确实就是代理对象实例proxyObj</p>
<p>为何getClass()没有被拦截？proxy参数又有何用呢？</p>
<p>先不管，做一个试验看看。既然这个proxy参数就是代理实例对象，它理所当然和proxyObj是一样的，可以调用info等方法。于是我们可以在invoke方法中加上如下一条语句：</p>
<p>((IAnimal)proxy).info();</p>
<p>结果是：</p>
<p>the proxyObj is an animal!<br />
the proxyObj isn't a dog!<br />
被拦截的方法:info<br />
被拦截的方法:info</p>
<p>.......</p>
<p>被拦截的方法:info<br />
被拦截的方法:info</p>
<p>然后就是栈溢出</p>
<p>结果是很明显的，在invoke方法中调用proxy中的方法会再一次引发invoke方法，这就陷入了死循环，最终结果当然是栈溢出的。</p>
<p>可以在invoke方法中调用proxy.getClass(), 程序可以正常运行。但如果调用hashCode()方法同样会导致栈溢出。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通过上面的试验，可以得出一些初步结论，invoke 接口中的proxy参数不能用于调用所实现接口的方法。奇怪的是hashCode()和getClass()方法都是从Object中继承下来的方法，为什么一个可以另一个不可以呢？带首疑问到doc文档看一下Object中这两个方法，发现getClass()是定义为final的，而hashCode()不是。难道是这个原因，于是找到一个非final方法，如equals试了一下，真的又会导致栈溢出；找另一个final方法如wait(),试了一下，invoke又不拦截了。final 难道就是关键之处？</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;还有一个问题就是proxy有什么用？既然proxy可以调用getClass()方法，我们就可以得到proxy的Class类象，从而可以获得关于proxy代理实例的所有类信息，如方法列表，Annotation等，这就为我们提供的一个分析proxy的有力工具，如通过分析Annotation分析方法的声明式事务需求。我想传入proxy参数应该是这样一个用意吧。</p>
<p>&nbsp;</p>
<p align="center"><font style="font-size: 14pt" color="#000066"><strong>InvocationHandler的资料</strong></font> </p>
<h2><font size="-1">属于包：java.lang.reflect</font></h2>
<dl>
<dt>
<pre>public interface <strong>InvocationHandler</strong></pre>
</dt></dl>
<p><code>InvocationHandler</code> 是代理实例的<em>调用处理程序</em> 实现的接口。 </p>
<p>每个代码实例都具有一个关联的调用处理程序。对代理实例调用方法时，将对方法调用进行编码并将其指派到它的调用处理程序的 <code>invoke</code> 方法。</p>
<dl>
<dt><strong>从以下版本开始：</strong>
<dd>JDK1.3</dd></dl>
<h3>invoke</h3>
<pre><a title="java.lang 中的类" href="http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/lang/Object.html">Object</a> <strong>invoke</strong>(<a title="java.lang 中的类" href="http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/lang/Object.html">Object</a>&nbsp;proxy,<br />
<a title="java.lang.reflect 中的类" href="http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/lang/reflect/Method.html">Method</a>&nbsp;method,<br />
<a title="java.lang 中的类" href="http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/lang/Object.html">Object</a>[]&nbsp;args)<br />
throws <a title="java.lang 中的类" href="http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/lang/Throwable.html">Throwable</a></pre>
<dl>
<dd>在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时，将在调用处理程序上调用此方法。
<p>&nbsp;</p>
<dd>
<dl>
<dt><strong>参数：</strong>
<dd><code>proxy</code> - 在其上调用方法的代理实例
<dd><code>method</code> - 对应于在代理实例上调用的接口方法的 <code>Method</code> 实例。<code>Method</code> 对象的声明类将是在其中声明方法的接口，该接口可以是代理类赖以继承方法的代理接口的超接口。
<dd><code>args</code> - 包含传入代理实例上方法调用的参数值的对象数组，如果接口方法不使用参数，则为 <code>null</code>。基本类型的参数被包装在适当基本包装器类（如 <code>java.lang.Integer</code> 或 <code>java.lang.Boolean</code>）的实例中。
<dt><strong>返回：</strong>
<dd>从代理实例的方法调用返回的值。如果接口方法的声明返回类型是基本类型，则此方法返回的值一定是相应基本包装对象类的实例；否则，它一定是可分配到声明返回类型的类型。如果此方法返回的值为 <code>null</code> 并且接口方法的返回类型是基本类型，则代理实例上的方法调用将抛出 <code>NullPointerException</code>。否则，如果此方法返回的值与上述接口方法的声明返回类型不兼容，则代理实例上的方法调用将抛出 <code>ClassCastException</code>。
<dt><strong>抛出：</strong>
<dd><code><a title="java.lang 中的类" href="http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/lang/Throwable.html">Throwable</a></code> - 从代理实例上的方法调用抛出的异常。该异常的类型必须可以分配到在接口方法的 <code>throws</code> 子句中声明的任一异常类型或未经检查的异常类型 <code>java.lang.RuntimeException</code> 或 <code>java.lang.Error</code>。如果此方法抛出经过检查的异常，该异常不可分配到在接口方法的 <code>throws</code> 子句中声明的任一异常类型，代理实例的方法调用将抛出包含此方法曾抛出的异常的 <a title="java.lang.reflect 中的类" href="http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/lang/reflect/UndeclaredThrowableException.html"><code>UndeclaredThrowableException</code></a>。</dd></dl></dd></dl>
<img src ="http://www.blogjava.net/aoneany/aggbug/271019.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aoneany/" target="_blank">沙漠中的鱼</a> 2009-05-16 18:53 <a href="http://www.blogjava.net/aoneany/articles/271019.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从一个ConnectionPool的实现看design pattern的运用 (source code for Java 1.1)</title><link>http://www.blogjava.net/aoneany/articles/270995.html</link><dc:creator>沙漠中的鱼</dc:creator><author>沙漠中的鱼</author><pubDate>Sat, 16 May 2009 05:43:00 GMT</pubDate><guid>http://www.blogjava.net/aoneany/articles/270995.html</guid><wfw:comment>http://www.blogjava.net/aoneany/comments/270995.html</wfw:comment><comments>http://www.blogjava.net/aoneany/articles/270995.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aoneany/comments/commentRss/270995.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aoneany/services/trackbacks/270995.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: ConnectionPool.java:public&nbsp;interface&nbsp;ConnectionPool{&nbsp;&nbsp;&nbsp;&nbsp;Connection&nbsp;getConnection()&nbsp;&nbsp;&nbsp;&nbsp;throws&nbsp;test.res.ResourceNotAvailableException,&n...&nbsp;&nbsp;<a href='http://www.blogjava.net/aoneany/articles/270995.html'>阅读全文</a><img src ="http://www.blogjava.net/aoneany/aggbug/270995.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aoneany/" target="_blank">沙漠中的鱼</a> 2009-05-16 13:43 <a href="http://www.blogjava.net/aoneany/articles/270995.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>做个好的（事件）侦听器笔记</title><link>http://www.blogjava.net/aoneany/articles/267761.html</link><dc:creator>沙漠中的鱼</dc:creator><author>沙漠中的鱼</author><pubDate>Mon, 27 Apr 2009 10:22:00 GMT</pubDate><guid>http://www.blogjava.net/aoneany/articles/267761.html</guid><wfw:comment>http://www.blogjava.net/aoneany/comments/267761.html</wfw:comment><comments>http://www.blogjava.net/aoneany/articles/267761.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aoneany/comments/commentRss/267761.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aoneany/services/trackbacks/267761.html</trackback:ping><description><![CDATA[<strong>事件监听的安全性</strong><br />
如下代码，在用Vector进行不安全的迭代时，另外一个线程对Vector的对象进行添加或删除时，会抛出会抛出 ConcurrentModificationException异常。<br />
Vector&lt;Listener&gt; v;<br />
for (int i=0; i&lt;v.size(); i++)<br />
&nbsp; v.get(i).eventHappened(event);<br />
java.util.concurrent 中的 CopyOnWriteArrayList 类，能够帮助防止这个问题。它实现了 List，而且是线程安全的，但是它的迭代器不会抛出 ConcurrentModificationException，遍历期间也不要求额外的锁定。这种特性组合是通过在每次列表修改时，在内部重新分配并拷贝列表内容而实现的，这样，遍历内容的线程不需要处理变化 —— 从它们的角度来说，列表的内容在遍历期间保持不变。虽然这听起来可能没效率，但是请记住，在多数观察者情况下，每个组件只有少量侦听器，遍历的数量远远超过插入和删除的数量。所以更快的迭代可以补偿较慢的变化过程，并提供更好的并发性，因为多个线程可以同时迭代列表。<br />
<strong>事件监听初使化风险</strong><br />
事件监听器允许"this"转义<br />
<strong>失效的监听</strong><br />
&nbsp; public void processFile(String filename) throws IOException {<br />
&nbsp;&nbsp;&nbsp; cancelButton.registerListener(this);<br />
&nbsp;&nbsp;&nbsp; // open file, read it, process it<br />
&nbsp;&nbsp;&nbsp; // might throw IOException<br />
&nbsp;&nbsp;&nbsp; cancelButton.unregisterListener(this);<br />
&nbsp; }<br />
当读入文件时，产生异常，会造成取消注册事件不能被执行，取消登记的操作应当在 finally 块中进行，这样，processFile() 方法的所有出口都会执行它。
<img src ="http://www.blogjava.net/aoneany/aggbug/267761.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aoneany/" target="_blank">沙漠中的鱼</a> 2009-04-27 18:22 <a href="http://www.blogjava.net/aoneany/articles/267761.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>