﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Thinking in MyLife-文章分类-java</title><link>http://www.blogjava.net/zhangzhong1018/category/16371.html</link><description>study ruby on rails</description><language>zh-cn</language><lastBuildDate>Tue, 23 Feb 2010 18:06:36 GMT</lastBuildDate><pubDate>Tue, 23 Feb 2010 18:06:36 GMT</pubDate><ttl>60</ttl><item><title>ant junit send mail</title><link>http://www.blogjava.net/zhangzhong1018/articles/151460.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Tue, 09 Oct 2007 09:27:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/151460.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/151460.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/151460.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/151460.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/151460.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td>
            <table cellspacing="0" cellpadding="0" width="100%" bgcolor="#ffffff" border="0">
                <tbody>
                    <tr>
                        <td class="title1" align="center" width="100%" bgcolor="#eeeeee" colspan="3" height="40"><strong></strong></td>
                    </tr>
                    <tr>
                        <td align="center" width="100%" bgcolor="#eeeeee">&nbsp; </td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
        <!-- end of article title -->
        <tr>
            <td valign="top" align="center" width="100%"><!--start of article content -->
            <table class="rtable" width="98%" border="0">
                <tbody>
                    <tr>
                        <td class="text" align="left" width="100%"><br />
                        当 测试 有error ，失败后做就send mail <br />
                        <br />
                        <div class="codeStyle">
                        <ol>
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name=<font color="#ff33ff">"report"</font>&nbsp;value=<font color="#ff33ff">"report"</font>&nbsp;/&gt;&nbsp;
                            <li>
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;target&nbsp;name=<font color="#ff33ff">"junitreport"</font>&nbsp;depends=<font color="#ff33ff">"clean,&nbsp;compile"</font>&gt;&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;junit&nbsp;printsummary=<font color="#ff33ff">"on"</font>&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fork=<font color="#ff33ff">"true"</font>&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;haltonfailure=<font color="#ff33ff">"false"</font>&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;failureproperty=<font color="#ff33ff">"tests.failed"</font>&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;showoutput=<font color="#ff33ff">"true"</font>&gt;&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;classpath&nbsp;refid=<font color="#ff33ff">"myclasspath"</font>/&gt;&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;formatter&nbsp;type=<font color="#ff33ff">"xml"</font>/&gt;&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;batchtest&nbsp;todir=<font color="#ff33ff">"${report}"</font>&gt;&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;fileset&nbsp;dir=<font color="#ff33ff">"${build}"</font>&gt;&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;include&nbsp;name=<font color="#ff33ff">"**/*Test.*"</font>/&gt;&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/fileset&gt;&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/batchtest&gt;&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/junit&gt;&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;junitreport&nbsp;todir=<font color="#ff33ff">"${report}"</font>&gt;&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;fileset&nbsp;dir=<font color="#ff33ff">"${report}"</font>&gt;&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;include&nbsp;name=<font color="#ff33ff">"TEST-*.xml"</font>/&gt;&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/fileset&gt;&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;report&nbsp;format=<font color="#ff33ff">"frames"</font>&nbsp;todir=<font color="#ff33ff">"${report}"</font>/&gt;&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/junitreport&gt;&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;fail&nbsp;<strong><font color="#0000ff">if</font></strong>=<font color="#ff33ff">"tests.failed"</font>&gt;&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;---------------------------------------------------------&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;One&nbsp;or&nbsp;more&nbsp;tests&nbsp;failed,&nbsp;check&nbsp;the&nbsp;report&nbsp;<strong><font color="#0000ff">for</font></strong>&nbsp;detail...&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;------------------
                            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;mail mailhost="localhost" mailport="25" subject="Web Test Result"&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;from address="webadm@gpe-hkg.com"/&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;to address="l.zhang@gpe-hkg.com"/&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;message&gt;Dear All,</p>
                            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The test result link "http://192.6.4.102/flex/webtest/test".</p>
                            <p>&nbsp;</p>
                            <p>Best Regards,<br />
                            Web Team.&lt;/message&gt;<br />
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/mail&gt;<br />
                            </p>
                            ---------------------------------------&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/fail&gt;&nbsp;
                            <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/target&gt;&nbsp; </li>
                        </ol>
                        </div>
                        。<br />
                        </td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/151460.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2007-10-09 17:27 <a href="http://www.blogjava.net/zhangzhong1018/articles/151460.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java基本数据类型转换</title><link>http://www.blogjava.net/zhangzhong1018/articles/151123.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Mon, 08 Oct 2007 10:04:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/151123.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/151123.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/151123.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/151123.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/151123.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1 字符串转换成数据 字符串转换成整数： String MyNumber ="1234"; int MyInt = Integer.parseInt(MyNumber); 字符串转换成byte, short, int, float, double, long等数据类型，可以分别参考Byte, Short, Integer, Float, Double, Long类的parseXXX...&nbsp;&nbsp;<a href='http://www.blogjava.net/zhangzhong1018/articles/151123.html'>阅读全文</a><img src ="http://www.blogjava.net/zhangzhong1018/aggbug/151123.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2007-10-08 18:04 <a href="http://www.blogjava.net/zhangzhong1018/articles/151123.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>eclipse   plug </title><link>http://www.blogjava.net/zhangzhong1018/articles/124358.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Thu, 14 Jun 2007 09:16:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/124358.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/124358.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/124358.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/124358.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/124358.html</trackback:ping><description><![CDATA[<strong>相关JAR包：<br><br>spring-framework-1.1.5</strong> ：http://voxel.dl.sourceforge.net/sourceforge/springframework/spring-framework-1.1.5.p<br><strong>spring-framework-1.1.5-with-dependencies</strong> ： http://nchc.dl.sourceforge.net/sourceforge/springframework/spring-framework-1.1.5-with-dependencies.p<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<p><strong>相关JAR包：<br><br>spring-framework-1.1.5</strong> ：http://voxel.dl.sourceforge.net/sourceforge/springframework/spring-framework-1.1.5.p<br><strong>spring-framework-1.1.5-with-dependencies</strong> ： http://nchc.dl.sourceforge.net/sourceforge/springframework/spring-framework-1.1.5-with-dependencies.p<br><strong>hibernate-2.1.8</strong> ：http://voxel.dl.sourceforge.net/sourceforge/hibernate/hibernate-2.1.8.p<br><strong>hibernate-extensions-2.1.3</strong> ：http://nchc.dl.sourceforge.net/sourceforge/hibernate/hibernate-extensions-2.1.3.p<br><strong>struts-menu-2.3</strong> ：http://optusnet.dl.sourceforge.net/sourceforge/struts-menu/struts-menu-2.3.p<br><strong>struts-menu.war</strong> ：http://jaist.dl.sourceforge.net/sourceforge/struts-menu/struts-menu.war<br><strong>Appfuse </strong>：http://appfuse.dev.java.net<br><br><br><strong>eclipse和相关开发插件及插件更新地址：</strong><br><br><strong>eclipse download</strong> ： http://eclipse.cis.sinica.edu.tw/downloads/drops/R-3.0.1-200409161125/eclipse-SDK-3.0.1-win32.p<br><strong>eclipse 3.0.X多国语言包</strong> ：http://download.eclipse.org/eclipse/downloads/drops/L-3.0.1_Translations-200409161125/NLpack-eclipse-SDK-3.0.x-win32.p<br><strong>lomboz.301</strong> ： http://download.us.forge.objectweb.org/lomboz/lomboz.301.p<br><strong>emf-sdo-runtime-2.0.0</strong> ： http://download.us.forge.objectweb.org/lomboz/emf-sdo-runtime-2.0.0.p<br><strong>lomboz_3.0.1.N20050106</strong> ： http://download.us.forge.objectweb.org/lomboz/org.objectweb.lomboz_3.0.1.N20050106.p<br><span><strong><span align="justify">Easy Strut 0.6.4 for Eclipse : </span></strong></span>http://easystruts.sourceforge.net/index.html#plugin<br><br><br><strong>插件更新地址：<br><br>Spring plugin</strong> ：http://springframework.sourceforge.net/spring-ide/eclipse/updatesite/<br><strong>hibernate plugin</strong> ：http://www.binamics.com/hibernatesync<br><strong>代码折叠</strong><strong> plugin</strong>：http://www.coffee-bytes.com/eclipse/update-site/site.xml<br><strong>visual editor plugin 1.0</strong>：http://update.eclipse.org/tools/ve/updates/1.0<br><strong>EMF/SDO/XSD Secondary </strong><strong>plugin</strong> ：http://download.eclipse.org/tools/emf/updates/site.xml<br><strong>UML 2.0 plugin</strong> ：http://download.eclipse.org/tools/uml2/updates/site.xml<br><strong>C# plugin</strong> ：http://www.improve-technologies.com/alpha/updates/site.xml<br><br><br><br>不断更新中......<br><br><strong>网上收集的--&gt;&gt;<br><br></strong><span style="FONT-FAMILY: arial">sourceforge <a href="http://www.sourceforge.net/"><span style="COLOR: navy"><u>http://www.sourceforge.net</u></span></a> </span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align=left><span style="FONT-FAMILY: arial">java.net <a href="http://www.java.net/"><span style="COLOR: navy"><u>http://www.java.net</u></span></a></span></p>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align=left><span style="FONT-FAMILY: arial"><a href="http://www.eclipse.org/"><span style="COLOR: navy"><u>www.eclipse.org</u></span></a></span></p>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align=left><span style="FONT-FAMILY: arial"><a href="http://www.opensource.org/"><span style="COLOR: navy"><u>www.opensource.org</u></span></a></span></p>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align=left><span style="FONT-FAMILY: arial">Lomboz <a href="http://www.objectlearn.com/index.jsp"><span style="COLOR: navy"><u>http://www.objectlearn.com/index.jsp</u></span></a> (J2EE plugin for Eclipse)<br>htmlArea <a href="http://sourceforge.net/projects/itools-htmlarea/"><span style="COLOR: navy"><u>http://sourceforge.net/projects/itools-htmlarea/</u></span></a> (</span><span style="FONT-FAMILY: 宋体">所见即所得的在线</span><span style="FONT-FAMILY: arial">HTML</span><span style="FONT-FAMILY: 宋体">编辑器</span><span style="FONT-FAMILY: arial">)<br>XmlBuddy <a href="http://www.xmlbuddy.com/"><span style="COLOR: navy"><u>http://www.xmlbuddy.com/</u></span></a> (XML Editor plugin for Eclipse)<br>JFreeChart <a href="http://www.jfree.org/"><span style="COLOR: navy"><u>http://www.jfree.org/</u></span></a> (</span><span style="FONT-FAMILY: 宋体">用于生成图表的项目</span><span style="FONT-FAMILY: arial">)<br>EclipseME <a href="http://eclipseme.sourceforge.net/"><span style="COLOR: navy"><u>http://eclipseme.sourceforge.net/</u></span></a> (J2ME Developmnt Plugin for Eclipse)<br>mvnForum <a href="http://sourceforge.net/projects/mvnforum/"><span style="COLOR: navy"><u>http://sourceforge.net/projects/mvnforum/</u></span></a> (</span><span style="FONT-FAMILY: 宋体">论坛</span><span style="FONT-FAMILY: arial">)<br>jChatBox <a href="http://www.javazoom.net/index.shtml"><span style="COLOR: navy"><u>http://www.javazoom.net/index.shtml</u></span></a> (</span><span style="FONT-FAMILY: 宋体">用</span><span style="FONT-FAMILY: arial">servlet</span><span style="FONT-FAMILY: 宋体">实现的</span><span style="FONT-FAMILY: arial">WEB</span><span style="FONT-FAMILY: 宋体">聊天引擎</span><span style="FONT-FAMILY: arial">)<br>POI <a href="http://jakarta.apache.org/poi/index.html"><span style="COLOR: navy"><u>http://jakarta.apache.org/poi/index.html</u></span></a> (</span><span style="FONT-FAMILY: 宋体">用于处理</span><span style="FONT-FAMILY: arial">Excel,WORD</span><span style="FONT-FAMILY: 宋体">等文档的项目</span><span style="FONT-FAMILY: arial">)<br>FileUpload <a href="http://jakarta.apache.org/commons/fileupload/"><span style="COLOR: navy"><u>http://jakarta.apache.org/commons/fileupload/</u></span></a> (</span><span style="FONT-FAMILY: 宋体">用于处理</span><span style="FONT-FAMILY: arial">HTTP</span><span style="FONT-FAMILY: 宋体">文件上传得项目</span><span style="FONT-FAMILY: arial">)<br>PDFBox <a href="http://sourceforge.net/projects/pdfbox/"><span style="COLOR: navy"><u>http://sourceforge.net/projects/pdfbox/</u></span></a> (</span><span style="FONT-FAMILY: 宋体">处理</span><span style="FONT-FAMILY: arial">PDF</span><span style="FONT-FAMILY: 宋体">文档的项目</span><span style="FONT-FAMILY: arial">)<br>Lucene <a href="http://jakarta.apache.org/lucene/index.html"><span style="COLOR: navy"><u>http://jakarta.apache.org/lucene/index.html</u></span></a> (</span><span style="FONT-FAMILY: 宋体">搜索引擎</span><span style="FONT-FAMILY: arial">)<br>Digester <a href="http://jakarta.apache.org/commons/digester/"><span style="COLOR: navy"><u>http://jakarta.apache.org/commons/digester/</u></span></a> (</span><span style="FONT-FAMILY: 宋体">处理</span><span style="FONT-FAMILY: arial">XML</span><span style="FONT-FAMILY: 宋体">信息的项目</span><span style="FONT-FAMILY: arial">)<br>DBCP <a href="http://jakarta.apache.org/commons/dbcp/"><span style="COLOR: navy"><u>http://jakarta.apache.org/commons/dbcp/</u></span></a> (</span><span style="FONT-FAMILY: 宋体">数据库连接池</span><span style="FONT-FAMILY: arial">)<br>AXIS <a href="http://ws.apache.org/axis/"><span style="COLOR: navy"><u>http://ws.apache.org/axis/</u></span></a> (WebService </span><span style="FONT-FAMILY: 宋体">的实现框架</span><span style="FONT-FAMILY: arial">)<br>Jetspeed <a href="http://portals.apache.org/jetspeed-1/"><span style="COLOR: navy"><u>http://portals.apache.org/jetspeed-1/</u></span></a> (Portal)<br>HSQLDB <a href="http://sourceforge.net/projects/hsqldb/"><span style="COLOR: navy"><u>http://sourceforge.net/projects/hsqldb/</u></span></a> (Im memory Database Engine)<br>CEWOLF <a href="http://sourceforge.net/projects/cewolf/"><span style="COLOR: navy"><u>http://sourceforge.net/projects/cewolf/</u></span></a> (</span><span style="FONT-FAMILY: 宋体">一套标签库实现</span><span style="FONT-FAMILY: arial">Web</span><span style="FONT-FAMILY: 宋体">报表</span><span style="FONT-FAMILY: arial">,</span><span style="FONT-FAMILY: 宋体">使用的是</span><span style="FONT-FAMILY: arial">jFreeChart</span><span style="FONT-FAMILY: 宋体">引擎</span><span style="FONT-FAMILY: arial">)<br>Struts Menu <a href="http://sourceforge.net/projects/struts-menu/"><span style="COLOR: navy"><u>http://sourceforge.net/projects/struts-menu/</u></span></a> (</span><span style="FONT-FAMILY: 宋体">基于</span><span style="FONT-FAMILY: arial">Struts</span><span style="FONT-FAMILY: 宋体">的</span><span style="FONT-FAMILY: arial">Web</span><span style="FONT-FAMILY: 宋体">菜单项目</span><span style="FONT-FAMILY: arial">)<br>htmlparser <a href="http://sourceforge.net/projects/htmlparser/"><span style="COLOR: navy"><u>http://sourceforge.net/projects/htmlparser/</u></span></a> (</span><span style="FONT-FAMILY: 宋体">用于解析</span><span style="FONT-FAMILY: arial">HTML</span><span style="FONT-FAMILY: 宋体">信息的项目</span><span style="FONT-FAMILY: arial">)<br>Mondrian <span style="COLOR: navy"><a href="http://sourceforge.net/projects/mondrian/(Open"><u><font color=#0000ff>http://sourceforge.net/projects/mondrian/</font></u></a></span>(Open Source OLAP Database)<br>ProGuard <span style="COLOR: navy"><a href="http://sourceforge.net/projects/proguard/(Java"><u><font color=#0000ff>http://sourceforge.net/projects/proguard/</font></u></a></span>(Java</span><span style="FONT-FAMILY: 宋体">的混淆器</span><span style="FONT-FAMILY: arial">)<br>InfoGlue <a href="http://sourceforge.net/projects/infoglue/"><span style="COLOR: navy"><u>http://sourceforge.net/projects/infoglue/</u></span></a> (J2EE </span><span style="FONT-FAMILY: 宋体">内容管理系统</span><span style="FONT-FAMILY: arial">)<br>JPivot <a href="http://sourceforge.net/projects/jpivot/"><span style="COLOR: navy"><u>http://sourceforge.net/projects/jpivot/</u></span></a> (</span><span style="FONT-FAMILY: 宋体">基于</span><span style="FONT-FAMILY: arial">WEB</span><span style="FONT-FAMILY: 宋体">的</span><span style="FONT-FAMILY: arial">OLAP </span><span style="FONT-FAMILY: 宋体">展现</span><span style="FONT-FAMILY: arial">)<br><a href="http://java-source.net/"><span style="COLOR: navy"><u>http://java-source.net/</u></span></a></span></p>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align=left><span style="FONT-FAMILY: arial">(5)</span><span style="FONT-FAMILY: 宋体">几个常用</span><span style="FONT-FAMILY: arial">JAVA</span><span style="FONT-FAMILY: 宋体">开源项目的地址荟萃</span><span style="FONT-FAMILY: arial">:<br>Lomboz <a href="http://www.objectlearn.com/index.jsp"><u><font color=#0000ff>http://www.objectlearn.com/index.jsp</font></u></a> (J2EE plugin for Eclipse)<br>htmlArea <a href="http://sourceforge.net/projects/itools-htmlarea/"><u><font color=#0000ff>http://sourceforge.net/projects/itools-htmlarea/</font></u></a> (</span><span style="FONT-FAMILY: 宋体">所见即所得的在线</span><span style="FONT-FAMILY: arial">HTML</span></p>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align=left><span style="FONT-FAMILY: 宋体">编辑器</span><span style="FONT-FAMILY: arial">)<br>XmlBuddy <a href="http://www.xmlbuddy.com/"><u><font color=#0000ff>http://www.xmlbuddy.com/</font></u></a> (XML Editor plugin for Eclipse)<br>JFreeChart <a href="http://www.jfree.org/"><u><font color=#0000ff>http://www.jfree.org/</font></u></a> (</span><span style="FONT-FAMILY: 宋体">用于生成图表的项目</span><span style="FONT-FAMILY: arial">)<br>EclipseME <a href="http://eclipseme.sourceforge.net/"><u><font color=#0000ff>http://eclipseme.sourceforge.net/</font></u></a> (J2ME Developmnt Plugin for Eclipse)<br>mvnForum <a href="http://sourceforge.net/projects/mvnforum/"><u><font color=#0000ff>http://sourceforge.net/projects/mvnforum/</font></u></a> (</span><span style="FONT-FAMILY: 宋体">论坛</span><span style="FONT-FAMILY: arial">)<br>jChatBox <a href="http://www.javazoom.net/index.shtml"><u><font color=#0000ff>http://www.javazoom.net/index.shtml</font></u></a> (</span><span style="FONT-FAMILY: 宋体">用</span><span style="FONT-FAMILY: arial">servlet</span><span style="FONT-FAMILY: 宋体">实现的</span><span style="FONT-FAMILY: arial">WEB</span><span style="FONT-FAMILY: 宋体">聊天引擎</span><span style="FONT-FAMILY: arial">)<br>POI <a href="http://jakarta.apache.org/poi/index.html"><u><font color=#0000ff>http://jakarta.apache.org/poi/index.html</font></u></a> (</span><span style="FONT-FAMILY: 宋体">用于处理</span><span style="FONT-FAMILY: arial">Excel,WORD</span><span style="FONT-FAMILY: 宋体">等文档</span></p>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align=left><span style="FONT-FAMILY: 宋体">的项目</span><span style="FONT-FAMILY: arial">)<br>FileUpload <a href="http://jakarta.apache.org/commons/fileupload/"><u><font color=#800080>http://jakarta.apache.org/commons/fileupload/</font></u></a> (</span><span style="FONT-FAMILY: 宋体">用于处理</span><span style="FONT-FAMILY: arial">HTTP</span><span style="FONT-FAMILY: 宋体">文件上传得项</span></p>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align=left><span style="FONT-FAMILY: 宋体">目</span><span style="FONT-FAMILY: arial">)<br>PDFBox <a href="http://sourceforge.net/projects/pdfbox/"><u><font color=#0000ff>http://sourceforge.net/projects/pdfbox/</font></u></a> (</span><span style="FONT-FAMILY: 宋体">处理</span><span style="FONT-FAMILY: arial">PDF</span><span style="FONT-FAMILY: 宋体">文档的项目</span><span style="FONT-FAMILY: arial">)<br>Lucene <a href="http://jakarta.apache.org/lucene/index.html"><u><font color=#0000ff>http://jakarta.apache.org/lucene/index.html</font></u></a> (</span><span style="FONT-FAMILY: 宋体">搜索引擎</span><span style="FONT-FAMILY: arial">)<br>Digester <a href="http://jakarta.apache.org/commons/digester/"><u><font color=#0000ff>http://jakarta.apache.org/commons/digester/</font></u></a> (</span><span style="FONT-FAMILY: 宋体">处理</span><span style="FONT-FAMILY: arial">XML</span><span style="FONT-FAMILY: 宋体">信息的项目</span><span style="FONT-FAMILY: arial">)<br>DBCP <a href="http://jakarta.apache.org/commons/dbcp/"><u><font color=#0000ff>http://jakarta.apache.org/commons/dbcp/</font></u></a> (</span><span style="FONT-FAMILY: 宋体">数据库连接池</span><span style="FONT-FAMILY: arial">)<br>AXIS <a href="http://ws.apache.org/axis/"><u><font color=#0000ff>http://ws.apache.org/axis/</font></u></a> (WebService </span><span style="FONT-FAMILY: 宋体">的实现框架</span><span style="FONT-FAMILY: arial">)<br>Jetspeed <a href="http://portals.apache.org/jetspeed-1/"><u><font color=#0000ff>http://portals.apache.org/jetspeed-1/</font></u></a> (Portal)<br>HSQLDB <a href="http://sourceforge.net/projects/hsqldb/"><u><font color=#0000ff>http://sourceforge.net/projects/hsqldb/</font></u></a> (Im memory Database Engine)<br>CEWOLF <a href="http://sourceforge.net/projects/cewolf/"><u><font color=#0000ff>http://sourceforge.net/projects/cewolf/</font></u></a> </span></p>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align=left><span style="FONT-FAMILY: arial">(</span><span style="FONT-FAMILY: 宋体">一套标签库实现</span><span style="FONT-FAMILY: arial">Web</span><span style="FONT-FAMILY: 宋体">报表</span><span style="FONT-FAMILY: arial">,</span><span style="FONT-FAMILY: 宋体">使用的是</span><span style="FONT-FAMILY: arial">jFreeChart</span><span style="FONT-FAMILY: 宋体">引擎</span><span style="FONT-FAMILY: arial">)<br>Struts Menu <a href="http://sourceforge.net/projects/struts-menu/"><u><font color=#0000ff>http://sourceforge.net/projects/struts-menu/</font></u></a> (</span><span style="FONT-FAMILY: 宋体">基于</span><span style="FONT-FAMILY: arial">Struts</span><span style="FONT-FAMILY: 宋体">的</span><span style="FONT-FAMILY: arial">Web</span><span style="FONT-FAMILY: 宋体">菜单项目</span></p>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align=left><span style="FONT-FAMILY: arial">)<br>htmlparser <a href="http://sourceforge.net/projects/htmlparser/"><u><font color=#0000ff>http://sourceforge.net/projects/htmlparser/</font></u></a> (</span><span style="FONT-FAMILY: 宋体">用于解析</span><span style="FONT-FAMILY: arial">HTML</span><span style="FONT-FAMILY: 宋体">信息的项目</span></p>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align=left><span style="FONT-FAMILY: arial">)<br>Mondrian <a href="http://sourceforge.net/projects/mondrian/"><u><font color=#800080>http://sourceforge.net/projects/mondrian/</font></u></a> (Open Source OLAP </span></p>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align=left><span style="FONT-FAMILY: arial">Database)<br>ProGuard <a href="http://sourceforge.net/projects/proguard/"><u><font color=#0000ff>http://sourceforge.net/projects/proguard/</font></u></a> (Java</span><span style="FONT-FAMILY: 宋体">的混淆器</span><span style="FONT-FAMILY: arial">)<br>InfoGlue <a href="http://sourceforge.net/projects/infoglue/"><u><font color=#0000ff>http://sourceforge.net/projects/infoglue/</font></u></a> (J2EE </span><span style="FONT-FAMILY: 宋体">内容管理系统</span><span style="FONT-FAMILY: arial">)<br>JPivot <a href="http://sourceforge.net/projects/jpivot/"><u><font color=#800080>http://sourceforge.net/projects/jpivot/</font></u></a> (</span><span style="FONT-FAMILY: 宋体">基于</span><span style="FONT-FAMILY: arial">WEB</span><span style="FONT-FAMILY: 宋体">的</span><span style="FONT-FAMILY: arial">OLAP </span><span style="FONT-FAMILY: 宋体">展现</span><span style="FONT-FAMILY: arial">)<br>HttpClient <a href="http://jakarta.apache.org/commons/httpclient/"><u><font color=#0000ff>http://jakarta.apache.org/commons/httpclient/</font></u></a> </span><span style="FONT-FAMILY: 宋体">处理</span><span style="FONT-FAMILY: arial">http</span><span style="FONT-FAMILY: 宋体">客户端的接口<br></span></p>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<p><font size=4>&nbsp;</font><span class=javascript id=text136548><a class=ilink href="http://www.tusc.com.au/tutorial/html/index.html" target=_blank><font color=#0000ff size=4><u>http://www.tusc.com.au/tutorial/html/index.html</u></font></a><br><font size=4>利用Eclipse,LOMBOZ plugins,JBoss开发J2EE教学的文章（En）很精彩<br>1.? lomboz.301.zip 与emf-sdo-runtime-2.0.0.zip(著名的开发J2ee的插件)<br><br>下载网址：http://forge.objectweb.org/project/showfiles.php?group_id=97? 　<br><br></font><a class=ilink href="http://www.objectlearn.com/" target=_blank><font color=#0000ff size=4><u>http://www.objectlearn.com/</u></font></a><font size=4> <br><br>Lomboz 可以做很多事情，是使用 Eclipse+JBoss 做 J2EE 的首选。 <br><br>2.MyEclipse,最好的J2EE开发框架<br><br>下载Myeclipse userId: ylfly? password: *******<br></font><a class=ilink href="http://www.myeclipseide.com/ContentExpress-display-ceid-47.html" target=_blank><font color=#0000ff size=4><u>http://www.myeclipseide.com/ContentExpress-display-ceid-47.html</u></font></a><br><font size=4>MyEclipse的注册码：<br>for eclispe3.0版的：<br>IceCraft<br>VAR7ZL-819-56-54678656108018950<br>for eclispe2.1版的：<br>IceCraft<br>VAR7ZL-719-56-54678657538454123<br><br>3.Log4j或者Apache commons Logger最得力的助手就是 Log4e： <br>??? 官方网站：http://log4e.jayefem.de/<br>??? 下载连接：http://log4e.jayefem.de/download/de.jayefem.log4e_0.5.5.zip<br><br>4. Easy Struts支持Struts的插件 (0.64版只支持Eclipse2.X)<br>是开放源代码组织sourceforge.net上的一个项目，目前最新的版本是0.64， <br><br></font><a class=ilink href="http://sourceforge.net/project/showfiles.php&#239;&#188;&#376;group_id=54542&amp;package_id=49230" target=_blank><font color=#0000ff size=4><u>http://sourceforge.net/project/showfiles.php？group_id=54542&amp;package_id=49230</u></font></a><font size=4> <br><br></font><a class=ilink href="http://easystruts.sourceforge.net/" target=_blank><font color=#0000ff size=4><u>http://easystruts.sourceforge.net/</u></font></a><font size=4> <br><br>5. TomcatPlugin 支持Tomcat插件 <br></font><a class=ilink href="http://www.sysdeo.com/eclipse/tomcatPlugin.html" target=_blank><font color=#0000ff size=4><u>http://www.sysdeo.com/eclipse/tomcatPlugin.html</u></font></a><font size=4> <br><br>6.Hibernate Synchronizer<br>Hibernate Synchronizer is a free Eclipse plugin code generation tool to be used with the Hibernate persistence framework. The plugin will automatically generate java code when your hibernate mapping files are modified. Objects are created with generated code in an abstract base class and a user-modifiable extension class so user code does not get deleted when the generation is performed. <br></font><a class=ilink href="http://www.binamics.com/hibernatesync/" target=_blank><font color=#0000ff size=4><u>http://www.binamics.com/hibernatesync/</u></font></a><br><a class=ilink href="https://sourceforge.net/project/showfiles.php?group_id=99370" target=_blank><font color=#0000ff size=4><u>https://sourceforge.net/project/showfiles.php?group_id=99370</u></font></a><br><font size=4>HibernateSynchronizer-2.1.25-Eclipse3M6.zip?? 只支持到M7<br><br>7. SWT Designer 使GUI更cool，更in，更happy!<br></font><a class=ilink href="http://www.swt-designer.com/??" target=_blank><font color=#0000ff size=4><u>http://www.swt-designer.com/??</u></font></a><font size=4> 14天<br><br>8. XML Editor &amp; XSLT Debugger 编辑XML的插件 <br></font><a class=ilink href="http://www.oxygenxml.com/" target=_blank><font color=#0000ff size=4><u>http://www.oxygenxml.com/</u></font></a><font size=4> <br><br>8.1支持Eclipse 3.0 的XML插件<br></font><a class=ilink href="http://www.xmlbuddy.com/" target=_blank><font color=#0000ff size=4><u>http://www.xmlbuddy.com/</u></font></a><br><br><font size=4>8.2XML Viewer <br>Version: 1.1.7<br></font><a class=ilink href="http://tabaquismo.freehosting.net/ignacio/eclipse/xmlview/index.html" target=_blank><font color=#0000ff size=4><u>http://tabaquismo.freehosting.net/ignacio/eclipse/xmlview/index.html</u></font></a><br><br><font size=4>9.UML Tool for Eclipse <br></font><a class=ilink href="http://www.visual-paradigm.com/download.php?shortName=sdeec" target=_blank><font color=#0000ff size=4><u>http://www.visual-paradigm.com/download.php?shortName=sdeec</u></font></a><br><br><font size=4>9.1 UML插件 Omondo的(支持eclipse 3.0 的studio 1.0 只试用20天) <br></font><a class=ilink href="http://www.omondo.com/" target=_blank><font color=#0000ff size=4><u>http://www.omondo.com/</u></font></a><font size=4> <br>useId :ylfly password:*******<br><br>9.2EclipseUML2? is Eclipse tools<br><br></font><a class=ilink href="http://www.eclipse.org/uml2/" target=_blank><font color=#0000ff size=4><u>http://www.eclipse.org/uml2/</u></font></a><br><br><font size=4>10.Eclipse加速插件KeepResident <br><br></font><a class=ilink href="http://suif.stanford.edu/pub/keepresident/" target=_blank><font color=#0000ff size=4><u>http://suif.stanford.edu/pub/keepresident/</u></font></a><br><br><font size=4>原理:利用两个 Windows API - SetProcessWorkingSetSize 与 VirtualLock (适用于 Windows 平台)。<br><br>切换时果然快很多。<br><br>官方建议最小值设定在 100 MB，最大值 250 MB 左右。<br><br>11.RMI Plugin for Eclipse 1.6.0 for Eclipse 3.0<br></font><a class=ilink href="http://www.genady.net/rmi" target=_blank><font color=#0000ff size=4><u>http://www.genady.net/rmi</u></font></a><font size=4> <br><br>12其它插件<br><br>perl插件 </font><a class=ilink href="http://e-p-i-c.sf.net/updates" target=_blank><font color=#0000ff size=4><u>http://e-p-i-c.sf.net/updates</u></font></a><br><font size=4>C#插件? </font><a class=ilink href="http://www.improve-technologies.com/alpha/updates/site.xml" target=_blank><font color=#0000ff size=4><u>http://www.improve-technologies.com/alpha/updates/site.xml</u></font></a><br><font size=4>C插件??? </font><a class=ilink href="http://update.eclipse.org/tools/cdt/releases/new" target=_blank><font color=#0000ff size=4><u>http://update.eclipse.org/tools/cdt/releases/new</u></font></a><br><font size=4>Hex插件 </font><a class=ilink href="http://ehep.sourceforge.net/update" target=_blank><font color=#0000ff size=4><u>http://ehep.sourceforge.net/update</u></font></a><br><br><font size=4>13.Eclipse插件使用links目录的用法：<br>　假设把插件安装在d:myplugin目录中，则myplugin的目录结构一定要是这样的：<br>　　d:myplugineclipseplugins插件 及 d:myplugineclipsefeatures插件<br>　　例如安装EclipseME插件到d:myplugin目录中，则目录结构<br><br>d:myplugineclipsepluginseclipseme_0.4.5。<br>　　再假设eclipse安装在d:eclipse目录中，则在eclipse目录中创建名称为links的目录，在links目<br><br>录中建立一个link文件，比如myplugin.link，该文件内容为path=d:myplugin。<br>　　启动eclipse，插件即安装上了，如果想暂时不启动插件，只需把myplugin.link文件删除即可。<br>补充说明：<br>　1. 插件可以分别安装在多个自定义的目录中。<br>　2. 一个自定义目录可以安装多个插件。<br>　3. link文件的文件名及扩展名可以取任意名称，比如myplugin.txt，goodplugin都可以。<br>　4. link文件可以有多行path=插件目录，对应多个自定义插件目录，每一行的path参数都将生效。<br>　5. 在links目录也可以有多个link文件，每个link文件中的path参数都将生效。<br>　6. 插件目录可以使用相对路径，如果我们把myplugin目录创建在eclipse安装目录中，如上例中的<br><br>d:eclipse目录中，则只需设置path=myplugin即可。<br><br>14.Eclipse tools<br><br>1).ALL SDK bundle (includes Source, Runtime and Docs for EMF, XSD, and SDO). <br>?<br>2).The Graphical Editing Framework (GEF) allows developers to take an existing application <br><br>model and quickly create a rich graphical editor.<br><br>3).UML2 is an EMF-based implementation of the UML 2.0 metamodel for the Eclipse platform.<br><br></font><a class=ilink href="http://www.eclipse.org/emf/" target=_blank><font color=#0000ff size=4><u>http://www.eclipse.org/emf/</u></font></a><br><a class=ilink href="http://www.eclipse.org/gef/" target=_blank><font color=#0000ff size=4><u>http://www.eclipse.org/gef/</u></font></a><br><a class=ilink href="http://www.eclipse.org/uml2/" target=_blank><font color=#0000ff size=4><u>http://www.eclipse.org/uml2/</u></font></a><br><br><font size=4>15.plug-in网址：<br><br></font><a class=ilink href="http://www.eclipse-plugins.info/eclipse/index.jsp" target=_blank><font color=#0000ff size=4><u>http://www.eclipse-plugins.info/eclipse/index.jsp</u></font></a><br><br><a class=ilink href="http://www.eclipse-workbench.com/jsp/" target=_blank><font color=#0000ff size=4><u>http://www.eclipse-workbench.com/jsp/</u></font></a><font size=4> <br><br></font><a class=ilink href="http://eclipse-plugins.2y.net/eclipse/index.jsp" target=_blank><font color=#0000ff size=4><u>http://eclipse-plugins.2y.net/eclipse/index.jsp</u></font></a><font size=4> （非常非常著名的插件更新网站） <br><br></font><a class=ilink href="http://www.crionics.com/products/opensource/eclipse/eclipse.jsp" target=_blank><font color=#0000ff size=4><u>http://www.crionics.com/products/opensource/eclipse/eclipse.jsp</u></font></a><font size=4> （分类清楚） <br><br></font><a class=ilink href="http://www.eclipseplugincentral.com/" target=_blank><font color=#0000ff size=4><u>http://www.eclipseplugincentral.com/</u></font></a><br><br><font size=4>16.调试JSP时,在tomcat里改confserver.xml<br><br>??????? docbase="C:eclipseworkspaceMyJ2EEProjectmyweb"<br><br>????????? workDir="C:eclipseworkspaceMyJ2EEProjectj2src" /&gt;<br><br>docBase="D:workspacemyJSP est"<br>path="/test" reloadable="true" workDir="D:workspacemyJSPj2src"/&gt;<br><br><br><br>j2src不要改动<br><br>17.CVS---并发版本系统(中文手册)v1.12.9<br></font><a class=ilink href="http://cvsdoc-zh.gro.clinux.org/cvsdoc/zh_CN/html/index.html" target=_blank><font color=#0000ff size=4><u>http://cvsdoc-zh.gro.clinux.org/cvsdoc/zh_CN/html/index.html</u></font></a><br><a class=ilink href="http://cvsdoc-zh.gro.clinux.org/" target=_blank><font color=#0000ff size=4><u>http://cvsdoc-zh.gro.clinux.org</u></font></a><br><font size=4>另一个CVS手册：<br></font><a class=ilink href="http://www.chedong.com/tech/cvs_card.html" target=_blank><font color=#0000ff size=4><u>http://www.chedong.com/tech/cvs_card.html</u></font></a><br><br><font size=4>18.Preferences无法显示新安装的插件的解决办法<br><br>删除C:eclipseconfigurationorg.eclipse.update下的platform.xml文件，重新启动Eclipse<br><br>19.评价<br><br>当前世界上最新最实用的IDE环境Eclipse。加上分析设计工具eclipseUML、MVC构架的Struts、<br><br>对象数据绑定构架OJB，Web系统的自动单元测试工具JUnit和HttpUnit，还有最普及的数据库MySQL，最<br><br>流行的版本管理服务器CVS，和支持Java/JSP/servlet的最佳Web引擎tomcat ,jboss。<br><br>20.Eclipse的许可证是怎样的？<br>现在Eclipse相关的许可证是大多数基于Common Public License (CPL)，CPL是一个为Open Source <br><br>Initiative (OSI)所认可的许可证。由于Eclipse Foundation的建立，Eclipse的许可证将逐渐趋向于使<br><br>用Eclipse Public License (EPL)，EPL是一个与CPL相类似的许可证，正在进行OSI的认证工作。此外，<br><br>Eclipse还涉及到多个开源项目和各类许可证，主要有 Apache Software License、IBM Public License<br><br>、Metro Link Public License和Mozilla Public License。个人无需太关心许可证的问题，企业在使用<br><br>Eclipse进行开发之前，最好请法律界人士研究一下。<br><br>各许可证的网址是：<br><br></font><a class=ilink href="http://www.eclipse.org/legal/cpl-v10.html&#227;€?" target=_blank><font color=#0000ff size=4><u>http://www.eclipse.org/legal/cpl-v10.html、</u></font></a><br><br><a class=ilink href="http://www.eclipse.org/legal/epl-v10.html&#227;€?" target=_blank><font color=#0000ff size=4><u>http://www.eclipse.org/legal/epl-v10.html、</u></font></a><br><br><a class=ilink href="http://www.apache.org/licenses/LICENSE&#227;€?" target=_blank><font color=#0000ff size=4><u>http://www.apache.org/licenses/LICENSE、</u></font></a><br><br><a class=ilink href="http://oss.software.ibm.com/developerworks/opensource/license10.html&#227;€?" target=_blank><font color=#0000ff size=4><u>http://oss.software.ibm.com/developerworks/opensource/license10.html、</u></font></a><br><br><a class=ilink href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html&#227;€?" target=_blank><font color=#0000ff size=4><u>http://www.opengroup.org/openmotif/supporters/metrolink/license.html、</u></font></a><br><br><a class=ilink href="http://www.mozilla.org/MPL/MPL-1.1." target=_blank><font color=#0000ff size=4><u>http://www.mozilla.org/MPL/MPL-1.1.</u></font></a><font size=4> </font></span><br></p>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<p>eclipse你最常用的快捷键是什么?</p>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<p>ctrl &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;g：查看引用 &nbsp;<br>ctrl &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;n：重命名 &nbsp;<br>ctrl &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;o：导入类 &nbsp;<br>ctrl &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;r：启动上次运行 &nbsp;<br>ctrl &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;f：格式化代码 &nbsp;<br>ctrl &nbsp;+ &nbsp;c：复制 &nbsp;<br>ctrl &nbsp;+ &nbsp;v：粘贴 &nbsp;<br>ctrl &nbsp;+ &nbsp;x：切剪 &nbsp;<br>ctrl &nbsp;+ &nbsp;a：全选 &nbsp;<br>ctrl &nbsp;+ &nbsp;f：查找 &nbsp;<br>ctrl &nbsp;+ &nbsp;z：撤销 &nbsp;<br>ctrl &nbsp;+ &nbsp;y：重做 &nbsp;<br>ctrl &nbsp;+ &nbsp;s：保存 &nbsp;<br>--------------------------------------------------------------- &nbsp;<br>&nbsp;<br>用的最多的应该就是CTRL+SHIFT+S &nbsp;<br>还有格式化用的也挺多。 &nbsp;<br>--------------------------------------------------------------- &nbsp;<br>&nbsp;<br>ctrl &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;f &nbsp;格式化代码 &nbsp;<br>ctrl &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;o &nbsp;组织导入 &nbsp;<br>F3 &nbsp; &nbsp;打开声明 &nbsp;<br>Alt &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;r &nbsp; &nbsp;重命名变量 &nbsp;<br>&nbsp;<br>--------------------------------------------------------------- &nbsp;<br>&nbsp;<br>up &nbsp;<br>--------------------------------------------------------------- &nbsp;<br>&nbsp;<br>Alt+/ &nbsp; &nbsp; &nbsp; &nbsp;<br>&nbsp;<br>--------------------------------------------------------------- &nbsp;<br>&nbsp;<br>alt &nbsp;+ &nbsp;left &nbsp;<br>alt &nbsp;+ &nbsp;right &nbsp;<br>ctrl &nbsp;+ &nbsp;q &nbsp;<br>--------------------------------------------------------------- &nbsp;<br>&nbsp;<br>ctrl &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;g：查看引用 &nbsp;<br>ctrl &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;n：重命名 &nbsp;<br>ctrl &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;f：格式化代码 &nbsp;<br>ctrl &nbsp;+ &nbsp;c：复制 &nbsp;<br>ctrl &nbsp;+ &nbsp;v：粘贴 &nbsp;<br>ctrl &nbsp;+ &nbsp;a：全选 &nbsp;<br>ctrl &nbsp;+ &nbsp;f：查找 &nbsp;<br>ctrl &nbsp;+ &nbsp;z：撤销 &nbsp;<br>ctrl &nbsp;+ &nbsp;s：保存 &nbsp;<br>Alt &nbsp; &nbsp;+ &nbsp;/ &nbsp;智能提示 &nbsp;<br>--------------------------------------------------------------- &nbsp;<br>&nbsp;<br>ctrl &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;g：查看引用 &nbsp;<br>ctrl &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;n：重命名 &nbsp;<br>ctrl &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;o：导入类 &nbsp;<br>ctrl &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;r：启动上次运行 &nbsp;<br>ctrl &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;f：格式化代码 &nbsp;<br>ctrl &nbsp;+ &nbsp;c：复制 &nbsp;<br>ctrl &nbsp;+ &nbsp;v：粘贴 &nbsp;<br>ctrl &nbsp;+ &nbsp;x：切剪 &nbsp;<br>ctrl &nbsp;+ &nbsp;a：全选 &nbsp;<br>ctrl &nbsp;+ &nbsp;f：查找 &nbsp;<br>ctrl &nbsp;+ &nbsp;z：撤销 &nbsp;<br>ctrl &nbsp;+ &nbsp;y：重做 &nbsp;<br>ctrl &nbsp;+ &nbsp;s：保存 &nbsp;<br>Alt &nbsp; &nbsp;+ &nbsp;/ &nbsp;智能提示 &nbsp;<br>F3 &nbsp; &nbsp;打开声明 &nbsp;<br>Alt &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;r &nbsp; &nbsp;重命名变量 &nbsp;<br>其实最常用的就是下面几个： &nbsp;<br>&nbsp;<br>ctrl &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;o：导入类 &nbsp;<br>&nbsp;<br>ctrl &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;f：格式化代码 &nbsp;<br>ctrl &nbsp;+ &nbsp;c：复制 &nbsp;<br>ctrl &nbsp;+ &nbsp;v：粘贴 &nbsp;<br>ctrl &nbsp;+ &nbsp;x：切剪 &nbsp;<br>ctrl &nbsp;+ &nbsp;z：撤销 &nbsp;<br>ctrl &nbsp;+ &nbsp;s：保存 &nbsp;<br>Alt &nbsp; &nbsp;+ &nbsp;/ &nbsp;智能提示 &nbsp;<br>&nbsp;<br>--------------------------------------------------------------- &nbsp;<br>&nbsp;<br>Ctrl+M: &nbsp;工作区最大化/最小化 &nbsp;<br>Alt+/: &nbsp; &nbsp;智能提示 &nbsp;<br>F3: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;察看声明 &nbsp;<br>Crtl+1: &nbsp;修正错误 &nbsp;<br>&nbsp;<br>Shift+Alt+T: &nbsp;重构 &nbsp;<br>Shift+Alt+M: &nbsp;提取函数 &nbsp;<br>Shift+Alt+R: &nbsp;重命名 &nbsp;<br>Shift+Alt+C: &nbsp;更改函数标记 &nbsp;<br>&nbsp;<br>Ctrl+Shitf+F: &nbsp;格式化代码 &nbsp;<br>&nbsp;<br>--------------------------------------------------------------- &nbsp;<br>&nbsp;<br>ctrl &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;o：导入类 &nbsp;<br>atl &nbsp;+ &nbsp;/：提示 &nbsp;<br>ctrl &nbsp;+ &nbsp;shift &nbsp;+ &nbsp;t：查找相关信息 &nbsp;<br>--------------------------------------------------------------- &nbsp;<br>&nbsp;<br>Eclipse快捷键指南 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br>编辑 &nbsp;<br>作用域 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;功能 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;快捷键 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;查找并替换 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+F &nbsp;<br>文本编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;查找上一个 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+K &nbsp;<br>文本编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;查找下一个 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+K &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;撤销 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Z &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;复制 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+C &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;恢复上一个选择 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Alt+Shift+&#8595; &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;剪切 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+X &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;快速修正 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl1+1 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;内容辅助 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Alt+/ &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;全部选中 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+A &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;删除 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Delete &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;上下文信息 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Alt+？ &nbsp;<br>Alt+Shift+? &nbsp;<br>Ctrl+Shift+Space &nbsp;<br>Java编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;显示工具提示描述 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;F2 &nbsp;<br>Java编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;选择封装元素 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Alt+Shift+&#8593; &nbsp;<br>Java编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;选择上一个元素 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Alt+Shift+&#8592; &nbsp;<br>Java编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;选择下一个元素 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Alt+Shift+&#8594; &nbsp;<br>文本编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;增量查找 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+J &nbsp;<br>文本编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;增量逆向查找 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+J &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;粘贴 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+V &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;重做 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Y &nbsp;<br>&nbsp; &nbsp;<br>查看 &nbsp;<br>作用域 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;功能 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;快捷键 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;放大 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+= &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;缩小 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+- &nbsp;<br>&nbsp; &nbsp;<br>窗口 &nbsp;<br>作用域 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;功能 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;快捷键 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;激活编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;F12 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;切换编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+W &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;上一个编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+F6 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;上一个视图 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+F7 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;上一个透视图 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+F8 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;下一个编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+F6 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;下一个视图 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+F7 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;下一个透视图 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+F8 &nbsp;<br>文本编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;显示标尺上下文菜单 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+W &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;显示视图菜单 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+F10 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;显示系统菜单 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Alt+- &nbsp;<br>&nbsp; &nbsp;<br>导航 &nbsp;<br>作用域 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;功能 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;快捷键 &nbsp;<br>Java编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;打开结构 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+F3 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;打开类型 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+T &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;打开类型层次结构 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;F4 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;打开声明 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;F3 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;打开外部javadoc &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Shift+F2 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;打开资源 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+R &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;后退历史记录 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Alt+&#8592; &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;前进历史记录 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Alt+&#8594; &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;上一个 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+, &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;下一个 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+. &nbsp;<br>Java编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;显示大纲 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+O &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;在层次结构中打开类型 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+H &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;转至匹配的括号 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+P &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;转至上一个编辑位置 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Q &nbsp;<br>Java编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;转至上一个成员 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+&#8593; &nbsp;<br>Java编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;转至下一个成员 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+&#8595; &nbsp;<br>文本编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;转至行 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+L &nbsp;<br>&nbsp; &nbsp;<br>搜索 &nbsp;<br>作用域 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;功能 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;快捷键 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;出现在文件中 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+U &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;打开搜索对话框 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+H &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;工作区中的声明 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+G &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;工作区中的引用 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+G &nbsp;<br>&nbsp; &nbsp;<br>文本编辑 &nbsp;<br>作用域 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;功能 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;快捷键 &nbsp;<br>文本编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;改写切换 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Insert &nbsp;<br>文本编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;上滚行 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+&#8593; &nbsp;<br>文本编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;下滚行 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+&#8595; &nbsp;<br>&nbsp; &nbsp;<br>文件 &nbsp;<br>作用域 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;功能 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;快捷键 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;保存 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+X &nbsp; &nbsp;<br>Ctrl+S &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;打印 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+P &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;关闭 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+F4 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;全部保存 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+S &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;全部关闭 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+F4 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;属性 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Alt+Enter &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;新建 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+N &nbsp;<br>&nbsp; &nbsp;<br>项目 &nbsp;<br>作用域 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;功能 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;快捷键 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;全部构建 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+B &nbsp;<br>&nbsp; &nbsp;<br>源代码 &nbsp;<br>作用域 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;功能 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;快捷键 &nbsp;<br>Java编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;格式化 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+F &nbsp;<br>Java编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;取消注释 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+ &nbsp;<br>Java编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;注释 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+/ &nbsp;<br>Java编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;添加导入 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+M &nbsp;<br>Java编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;组织导入 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+O &nbsp;<br>Java编辑器 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;使用try/catch块来包围 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;未设置，太常用了，所以在这里列出,建议自己设置。 &nbsp;<br>也可以使用Ctrl+1自动修正。 &nbsp;<br>&nbsp; &nbsp;<br>运行 &nbsp;<br>作用域 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;功能 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;快捷键 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;单步返回 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;F7 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;单步跳过 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;F6 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;单步跳入 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;F5 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;单步跳入选择 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+F5 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;调试上次启动 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;F11 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;继续 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;F8 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;使用过滤器单步执行 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Shift+F5 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;添加/去除断点 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+Shift+B &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;显示 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+D &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;运行上次启动 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+F11 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;运行至行 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+R &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;执行 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Ctrl+U &nbsp;<br>&nbsp; &nbsp;<br>重构 &nbsp;<br>作用域 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;功能 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;快捷键 &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;撤销重构 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Alt+Shift+Z &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;抽取方法 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Alt+Shift+M &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;抽取局部变量 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Alt+Shift+L &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;内联 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Alt+Shift+I &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;移动 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Alt+Shift+V &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;重命名 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Alt+Shift+R &nbsp;<br>全局 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;重做 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;Alt+Shift+Y&nbsp;</p>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/124358.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2007-06-14 17:16 <a href="http://www.blogjava.net/zhangzhong1018/articles/124358.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> open source link</title><link>http://www.blogjava.net/zhangzhong1018/articles/121305.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Fri, 01 Jun 2007 02:12:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/121305.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/121305.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/121305.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/121305.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/121305.html</trackback:ping><description><![CDATA[sourceforge <a title=http://sourceforge.net/ href="http://sourceforge.net/" target=_blank><u><font color=#0000ff>http://sourceforge.net/</font></u></a><br>java.net <a title=http://www.java.net href="http://www.java.net/" target=_blank><u><font color=#0000ff>http://www.java.net</font></u></a><br><br>www.eclipse.org<br><br>www.opensource.org<br><br>Lomboz <a title=http://www.objectlearn.com/index.jsp href="http://www.objectlearn.com/index.jsp" target=_blank><u><font color=#0000ff>http://www.objectlearn.com/index.jsp</font></u></a> (J2EE plugin for Eclipse)<br>htmlArea <a title=http://sourceforge.net/projects/itools-htmlarea/ href="http://sourceforge.net/projects/itools-htmlarea/" target=_blank><u><font color=#0000ff>http://sourceforge.net/projects/itools-htmlarea/</font></u></a> (所见即所得的在线HTML编辑器)<br>XmlBuddy <a title=http://www.xmlbuddy.com/ href="http://www.xmlbuddy.com/" target=_blank><u><font color=#0000ff>http://www.xmlbuddy.com/</font></u></a> (XML Editor plugin for Eclipse)<br>JFreeChart <a title=http://www.jfree.org/ href="http://www.jfree.org/" target=_blank><u><font color=#0000ff>http://www.jfree.org/</font></u></a> (用于生成图表的项目)<br>EclipseME <a title=http://eclipseme.sourceforge.net/ href="http://eclipseme.sourceforge.net/" target=_blank><u><font color=#0000ff>http://eclipseme.sourceforge.net/</font></u></a> (J2ME Developmnt Plugin for Eclipse)<br>mvnForum <a title=http://sourceforge.net/projects/mvnforum/ href="http://sourceforge.net/projects/mvnforum/" target=_blank><u><font color=#0000ff>http://sourceforge.net/projects/mvnforum/</font></u></a> (论坛)<br>jChatBox <a title=http://www.javazoom.net/index.shtml href="http://www.javazoom.net/index.shtml" target=_blank><u><font color=#0000ff>http://www.javazoom.net/index.shtml</font></u></a> (用servlet实现的WEB聊天引擎)<br>POI <a title=http://jakarta.apache.org/poi/index.html href="http://jakarta.apache.org/poi/index.html" target=_blank><u><font color=#0000ff>http://jakarta.apache.org/poi/index.html</font></u></a> (用于处理Excel,WORD等文档的项目)<br>FileUpload <a title=http://jakarta.apache.org/commons/fileupload/ href="http://jakarta.apache.org/commons/fileupload/" target=_blank><u><font color=#800080>http://jakarta.apache.org/commons/fileupload/</font></u></a> (用于处理HTTP文件上传得项目)<br>PDFBox <a title=http://sourceforge.net/projects/pdfbox/ href="http://sourceforge.net/projects/pdfbox/" target=_blank><u><font color=#0000ff>http://sourceforge.net/projects/pdfbox/</font></u></a> (处理PDF文档的项目)<br>Lucene <a title=http://jakarta.apache.org/lucene/index.html href="http://jakarta.apache.org/lucene/index.html" target=_blank><u><font color=#0000ff>http://jakarta.apache.org/lucene/index.html</font></u></a> (搜索引擎)<br>Digester <a title=http://jakarta.apache.org/commons/digester/ href="http://jakarta.apache.org/commons/digester/" target=_blank><u><font color=#0000ff>http://jakarta.apache.org/commons/digester/</font></u></a> (处理XML信息的项目)<br>DBCP <a title=http://jakarta.apache.org/commons/dbcp/ href="http://jakarta.apache.org/commons/dbcp/" target=_blank><u><font color=#0000ff>http://jakarta.apache.org/commons/dbcp/</font></u></a> (数据库连接池)<br>AXIS <a title=http://ws.apache.org/axis/ href="http://ws.apache.org/axis/" target=_blank><u><font color=#0000ff>http://ws.apache.org/axis/</font></u></a> (WebService 的实现框架)<br>Jetspeed <a title=http://portals.apache.org/jetspeed-1/ href="http://portals.apache.org/jetspeed-1/" target=_blank><u><font color=#0000ff>http://portals.apache.org/jetspeed-1/</font></u></a> (Portal)<br>HSQLDB <a title=http://sourceforge.net/projects/hsqldb/ href="http://sourceforge.net/projects/hsqldb/" target=_blank><u><font color=#0000ff>http://sourceforge.net/projects/hsqldb/</font></u></a> (Im memory Database Engine)<br>CEWOLF <a title=http://sourceforge.net/projects/cewolf/ href="http://sourceforge.net/projects/cewolf/" target=_blank><u><font color=#0000ff>http://sourceforge.net/projects/cewolf/</font></u></a> (一套标签库实现Web报表,使用的是jFreeChart引擎)<br>Struts Menu <a title=http://sourceforge.net/projects/struts-menu/ href="http://sourceforge.net/projects/struts-menu/" target=_blank><u><font color=#0000ff>http://sourceforge.net/projects/struts-menu/</font></u></a> (基于Struts的Web菜单项目)<br>htmlparser <a title=http://sourceforge.net/projects/htmlparser/ href="http://sourceforge.net/projects/htmlparser/" target=_blank><u><font color=#0000ff>http://sourceforge.net/projects/htmlparser/</font></u></a> (用于解析HTML信息的项目)<br>Mondrian <a title=http://sourceforge.net/projects/mondrian/ href="http://sourceforge.net/projects/mondrian/" target=_blank><u><font color=#800080>http://sourceforge.net/projects/mondrian/</font></u></a>(Open Source OLAP Database)<br>ProGuard <a title=http://sourceforge.net/projects/proguard/ href="http://sourceforge.net/projects/proguard/" target=_blank><u><font color=#0000ff>http://sourceforge.net/projects/proguard/</font></u></a>(Java的混淆器)<br>InfoGlue <a title=http://sourceforge.net/projects/infoglue/ href="http://sourceforge.net/projects/infoglue/" target=_blank><u><font color=#0000ff>http://sourceforge.net/projects/infoglue/</font></u></a> (J2EE 内容管理系统)<br>JPivot <a title=http://sourceforge.net/projects/jpivot/ href="http://sourceforge.net/projects/jpivot/" target=_blank><u><font color=#800080>http://sourceforge.net/projects/jpivot/</font></u></a> (基于WEB的OLAP 展现)<br><a title=http://java-source.net/ href="http://java-source.net/" target=_blank><u><font color=#0000ff>http://java-source.net/</font></u></a><br><br>(5)几个常用JAVA开源项目的地址荟萃:<br>Lomboz <a title=http://www.objectlearn.com/index.jsp href="http://www.objectlearn.com/index.jsp" target=_blank><u><font color=#0000ff>http://www.objectlearn.com/index.jsp</font></u></a> (J2EE plugin for Eclipse)<br>htmlArea <a title=http://sourceforge.net/projects/itools-htmlarea/ href="http://sourceforge.net/projects/itools-htmlarea/" target=_blank><u><font color=#0000ff>http://sourceforge.net/projects/itools-htmlarea/</font></u></a> (所见即所得的在线HTML编辑器)<br>XmlBuddy <a title=http://www.xmlbuddy.com/ href="http://www.xmlbuddy.com/" target=_blank><u><font color=#0000ff>http://www.xmlbuddy.com/</font></u></a> (XML Editor plugin for Eclipse)<br>JFreeChart <a title=http://www.jfree.org/ href="http://www.jfree.org/" target=_blank><u><font color=#0000ff>http://www.jfree.org/</font></u></a> (用于生成图表的项目)<br>EclipseME <a title=http://eclipseme.sourceforge.net/ href="http://eclipseme.sourceforge.net/" target=_blank><u><font color=#0000ff>http://eclipseme.sourceforge.net/</font></u></a> (J2ME Developmnt Plugin for Eclipse)<br>mvnForum <a title=http://sourceforge.net/projects/mvnforum/ href="http://sourceforge.net/projects/mvnforum/" target=_blank><u><font color=#0000ff>http://sourceforge.net/projects/mvnforum/</font></u></a> (论坛)<br>jChatBox <a title=http://www.javazoom.net/index.shtml href="http://www.javazoom.net/index.shtml" target=_blank><u><font color=#0000ff>http://www.javazoom.net/index.shtml</font></u></a> (用servlet实现的WEB聊天引擎)<br>POI <a title=http://jakarta.apache.org/poi/index.html href="http://jakarta.apache.org/poi/index.html" target=_blank><u><font color=#0000ff>http://jakarta.apache.org/poi/index.html</font></u></a> (用于处理Excel,WORD等文档的项目)<br>FileUpload <a title=http://jakarta.apache.org/commons/fileupload/ href="http://jakarta.apache.org/commons/fileupload/" target=_blank><u><font color=#800080>http://jakarta.apache.org/commons/fileupload/</font></u></a> (用于处理HTTP文件上传得项目)<br>PDFBox <a title=http://sourceforge.net/projects/pdfbox/ href="http://sourceforge.net/projects/pdfbox/" target=_blank><u><font color=#0000ff>http://sourceforge.net/projects/pdfbox/</font></u></a> (处理PDF文档的项目)<br>Lucene <a title=http://jakarta.apache.org/lucene/index.html href="http://jakarta.apache.org/lucene/index.html" target=_blank><u><font color=#0000ff>http://jakarta.apache.org/lucene/index.html</font></u></a> (搜索引擎)<br>Digester <a title=http://jakarta.apache.org/commons/digester/ href="http://jakarta.apache.org/commons/digester/" target=_blank><u><font color=#0000ff>http://jakarta.apache.org/commons/digester/</font></u></a> (处理XML信息的项目)<br>DBCP <a title=http://jakarta.apache.org/commons/dbcp/ href="http://jakarta.apache.org/commons/dbcp/" target=_blank><u><font color=#0000ff>http://jakarta.apache.org/commons/dbcp/</font></u></a> (数据库连接池)<br>AXIS <a title=http://ws.apache.org/axis/ href="http://ws.apache.org/axis/" target=_blank><u><font color=#0000ff>http://ws.apache.org/axis/</font></u></a> (WebService 的实现框架)<br>Jetspeed <a title=http://portals.apache.org/jetspeed-1/ href="http://portals.apache.org/jetspeed-1/" target=_blank><u><font color=#0000ff>http://portals.apache.org/jetspeed-1/</font></u></a> (Portal)<br>HSQLDB <a title=http://sourceforge.net/projects/hsqldb/ href="http://sourceforge.net/projects/hsqldb/" target=_blank><u><font color=#0000ff>http://sourceforge.net/projects/hsqldb/</font></u></a> (Im memory Database Engine)<br>CEWOLF <a title=http://sourceforge.net/projects/cewolf/ href="http://sourceforge.net/projects/cewolf/" target=_blank><u><font color=#0000ff>http://sourceforge.net/projects/cewolf/</font></u></a> <br><br>(一套标签库实现Web报表,使用的是jFreeChart引擎)<br>Struts Menu <a title=http://sourceforge.net/projects/struts-menu/ href="http://sourceforge.net/projects/struts-menu/" target=_blank><u><font color=#0000ff>http://sourceforge.net/projects/struts-menu/</font></u></a> (基于Struts的Web菜单项目)<br>htmlparser <a title=http://sourceforge.net/projects/htmlparser/ href="http://sourceforge.net/projects/htmlparser/" target=_blank><u><font color=#0000ff>http://sourceforge.net/projects/htmlparser/</font></u></a> (用于解析HTML信息的项目)<br>Mondrian <a title=http://sourceforge.net/projects/mondrian/ href="http://sourceforge.net/projects/mondrian/" target=_blank><u><font color=#800080>http://sourceforge.net/projects/mondrian/</font></u></a> (Open Source OLAP Database)<br>ProGuard <a title=http://sourceforge.net/projects/proguard/ href="http://sourceforge.net/projects/proguard/" target=_blank><u><font color=#0000ff>http://sourceforge.net/projects/proguard/</font></u></a> (Java的混淆器)<br>InfoGlue <a title=http://sourceforge.net/projects/infoglue/ href="http://sourceforge.net/projects/infoglue/" target=_blank><u><font color=#0000ff>http://sourceforge.net/projects/infoglue/</font></u></a> (J2EE 内容管理系统)<br>JPivot <a title=http://sourceforge.net/projects/jpivot/ href="http://sourceforge.net/projects/jpivot/" target=_blank><u><font color=#800080>http://sourceforge.net/projects/jpivot/</font></u></a> (基于WEB的OLAP 展现)<br>HttpClient <a title=http://jakarta.apache.org/commons/httpclient/ href="http://jakarta.apache.org/commons/httpclient/" target=_blank><u><font color=#0000ff>http://jakarta.apache.org/commons/httpclient/</font></u></a> 处理http客户端的接口 
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/121305.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2007-06-01 10:12 <a href="http://www.blogjava.net/zhangzhong1018/articles/121305.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>几个开源的 BI </title><link>http://www.blogjava.net/zhangzhong1018/articles/119997.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Fri, 25 May 2007 06:15:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/119997.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/119997.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/119997.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/119997.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/119997.html</trackback:ping><description><![CDATA[<p><font face="Times New Roman, serif"><font size=2><span><span>openI&nbsp;&nbsp;&nbsp; <a href="http://openi.sourceforge.net/">http://openi.sourceforge.net</a></span></span></font>&nbsp;<a href="http://openi.sourceforge.net/"><font size=2><span><span></span></span></font></a></font></p>
<p lang=zh-CN align=left><font face="Times New Roman, serif"><font size=2>jaspersoft&nbsp;&nbsp;&nbsp; <a href="http://www.jaspersoft.com/">http://www.jaspersoft.com/</a>&nbsp;</font></font></p>
<p lang=zh-CN align=left><font face="Times New Roman, serif"><font size=2>spagoBI&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://spago.eng.it/">http://spago.eng.it</a></font></font></p>
<p lang=zh-CN align=left><font face="Times New Roman, serif"><font size=2>pentaho&nbsp;&nbsp; &nbsp;<a href="http://www.pentaho.com/">http://www.pentaho.com/</a></font></font></p>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/119997.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2007-05-25 14:15 <a href="http://www.blogjava.net/zhangzhong1018/articles/119997.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java.util.logging.Logger 类</title><link>http://www.blogjava.net/zhangzhong1018/articles/119145.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Tue, 22 May 2007 08:06:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/119145.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/119145.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/119145.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/119145.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/119145.html</trackback:ping><description><![CDATA[<div class=postTitle>&nbsp;</div>
<div class=postText>
<p><br><br><br>1、可以在main方法中书写以下语句进行log。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final Logger baseLogger = Logger.getLogger("LogTest");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;baseLogger.setLevel(Level.INFO);//this set the log level to info. that means you can only pring info message to log file.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final Handler[] handlers = baseLogger.getHandlers();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; handlers.length; i++) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; baseLogger.removeHandler(handlers[i]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; baseLogger.addHandler(new <span style="BACKGROUND-COLOR: yellow">DefaultHandler</span>()); //class "DefaultHandler" is the default handler for log records. It currently only logs to a file in the format offered by TextFormatter.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (FreeColException e) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p><br>2、可以在配置文件（${jdk}\jar\lib下面找到logging.properties文件）里面改日志记录的级别。<br><br>3、定义"DefaultHandler" 类，用于处理日志。<br><br>public final class <span style="BACKGROUND-COLOR: yellow">DefaultHandler </span>extends Handler {</p>
<p>&nbsp;&nbsp;&nbsp; private static final String fileName = new String("test.log");</p>
<p>&nbsp;&nbsp;&nbsp; private FileWriter fileWriter;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;/**<br>&nbsp;&nbsp;&nbsp; * The constructor to use.<br>&nbsp;&nbsp;&nbsp; * @throws Exception In case the log file could not be created/written to.<br>&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; public DefaultHandler() throws Exception {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File file = new File(fileName);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (file.exists()) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (file.isDirectory()) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new Exception("Log file \"" + fileName + "\" could not be created.");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (file.isFile()) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file.delete();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file.createNewFile();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (IOException e) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new Exception("Log file \"" + fileName + "\" could not be created.");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!file.canWrite()) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new Exception("Can not write in log file \"" + fileName + "\".");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fileWriter = new FileWriter(file);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (IOException e) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new Exception("Can not write in log file \"" + fileName + "\".");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // We&nbsp; use TextFormatter that we build latter.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setFormatter(new <span style="BACKGROUND-COLOR: #00ff00">TextFormatter</span>());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String str = "version: 1.0\n"&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; + "Java vendor: " + System.getProperty("java.vendor") + "\n"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + "Java version: " + System.getProperty("java.version") + "\n"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + "Java WM name: " + System.getProperty("java.vm.name") + "\n"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + "Java WM vendor: " + System.getProperty("java.vm.vendor") + "\n"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + "Java WM version: " + System.getProperty("java.vm.version") + "\n\n"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + "OS name: " + System.getProperty("os.name") + "\n"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + "OS architecture: " + System.getProperty("os.arch") + "\n"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + "OS version: " + System.getProperty("os.version") + "\n\n";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fileWriter.write(str, 0, str.length());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (IOException e) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp; * Closes this handler so that it will stop handling log records.<br>&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; public void close() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fileWriter.close();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (IOException e) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }</p>
<p><br>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp; * Flushes the data that this handler has logged.<br>&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; public void flush() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fileWriter.flush();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (IOException e) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }</p>
<p><br>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp; * Publishes the given LogRecord by writing its data to a file using<br>&nbsp;&nbsp;&nbsp; * a TextFormatter.<br>&nbsp;&nbsp;&nbsp; *<br>&nbsp;&nbsp;&nbsp; * @param record The log record to publish.<br>&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; public void publish(LogRecord record) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (record.getLevel().intValue() &lt; getLevel().intValue()) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String str = getFormatter().format(record);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fileWriter.write(str, 0, str.length());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (IOException e) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; flush();<br>&nbsp;&nbsp;&nbsp; }<br>}<br>&nbsp;&nbsp;&nbsp;<br>4、定义自己的Formatter格式。<br><br>/**<br>* Formats a log record's data into human-readable text.<br>*/<br>final class <span style="BACKGROUND-COLOR: #00ff00">TextFormatter</span> extends Formatter {</p>
<p>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp; * The constructor to use.<br>&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; public TextFormatter() {<br>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp; * Formats the given log record's data into human-readable text.<br>&nbsp;&nbsp;&nbsp; *<br>&nbsp;&nbsp;&nbsp; * @param record The log record whose data needs to be formatted.<br>&nbsp;&nbsp;&nbsp; * @return The log record's data as a string.<br>&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp;&nbsp; public String format(LogRecord record) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String level;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (record.getLevel() == Level.INFO) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; level = "INFO";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (record.getLevel() == Level.ALL) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; level = "ALL";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (record.getLevel() == Level.SEVERE) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; level = "SEVERE";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (record.getLevel() == Level.WARNING) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; level = "WARNING";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; level = "UNKNOWN";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//you can build your own result format</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String result = record.getSourceClassName() + ' ' + record.getSourceMethodName();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result += "\n\t" + level + ": " + record.getMessage().replaceAll("\n", "\n\t");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result += "\n\t" + new Date(record.getMillis()).toString();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result += "\n\tThread ID: " + record.getThreadID() + '\n';</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return result;<br>&nbsp;&nbsp;&nbsp; }<br>}<br></p>
<p>5、实际应用中的使用.<br><br>public class Client {<br>&nbsp;&nbsp;&nbsp; private static final Logger logger = Logger.getLogger(Client.class.getName());<br><br>&nbsp;&nbsp;&nbsp; private void createDirs() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String dir = System.getProperty("user.home");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String fileSeparator = System.getProperty("file.separator");</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!dir.endsWith(fileSeparator)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dir += fileSeparator;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dir += "test";</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File file = new File(dir);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (file.exists() &amp;&amp; file.isFile()) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: red">logger.warning</span>("Could not create .freecol under ~ because there already exists a regular file with the same name.");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (!file.exists()) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file.mkdir();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: red">logger.info</span>("Could not create .freecol under ~ because there already exists a regular file with the same name.");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>}</p>
</div>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/119145.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2007-05-22 16:06 <a href="http://www.blogjava.net/zhangzhong1018/articles/119145.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>modrian </title><link>http://www.blogjava.net/zhangzhong1018/articles/118147.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Thu, 17 May 2007 10:33:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/118147.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/118147.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/118147.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/118147.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/118147.html</trackback:ping><description><![CDATA[&nbsp;以前一直是用MS Anylize Service的，最近要做的项目是java的，小项目预算有限，所以想找一个开源的java的数据仓库解决方案来用用。
<p>&nbsp; 在网上查了一下，发现了Mondrian。Mondrian是基于JAVA的数据仓库引擎，可以集成到web项目中，这一点最吸引我。另外与他搭配的表现层的方案也有不少选择，Jpivot是元老，pentaho，openi看起来是后起之秀。不管怎样，还是先研究一下modrian吧</p>
<p>&nbsp; 网上的中文资源比较少，在csdn上找了一下，只发现了两篇比较有用的</p>
<p><a href="http://dev.csdn.net/develop/article/31/31791.shtm">http://dev.csdn.net/develop/article/31/31791.shtm</a>&nbsp;<strong>&nbsp; </strong><span id=ArticleTitle1_ArticleTitle1_lblTitle><span id=ArticleTitle1_ArticleTitle1_lblTitle><strong>Mondrian——有影响的&#8220;艺术家&#8221;</strong></span>&nbsp;&nbsp;&nbsp;&nbsp; 选择自 <a id=ArticleTitle1_ArticleTitle1_AuthorLink href="http://dev.csdn.net/user/kswaking">kswaking</a> 的 Blog </span></p>
<p><span id=ArticleTitle1_ArticleTitle1_lblTitle><strong><a href="http://dev.csdn.net/develop/article/68/68661.shtm">http://dev.csdn.net/develop/article/68/68661.shtm</a>&nbsp; 穷人的通用OLAP方案III--JPivot表现层</strong></span>&nbsp;&nbsp;&nbsp;&nbsp; 选择自 <a id=ArticleTitle1_ArticleTitle1_AuthorLink href="http://dev.csdn.net/user/calvinxiu">calvinxiu</a> 的 Blog </p>
<p>照着做了一下，发现了一些问题，也有了一些心得。</p>
<p>一.环境准备</p>
<p>1.1 首先介绍一下环境</p>
<p>操作系统：Linux </p>
<p>服务器：Tomcat 5.5</p>
<p>数据库：MySQL 5.0.21</p>
<p>1.2&nbsp;下载程序。Mondrian在<a href="http://mondrian.sourceforge.net/">http://mondrian.sourceforge.net</a> 可以下载，最早他是用MS Analyze Service的教程中FoodMart数据库作为demo的，那个是access的数据库。还好现在他有了Platform-Independent的版本，我就下载了那个<a href="http://prdownloads.sourceforge.net/mondrian/mondrian-2.1.1-derby.zip?download"><font color=#0033cc>mondrian-2.1.1-derby.zip</font></a>&nbsp;解压缩之后在lib目录里面有一个mondrian-embedded.war，把这个直接放到tomcat的webapps目录里面就能够看到mondrian的demo了。不过后面的测试，我把这个war解开之后放到webapps里面去，并且目录把名字改短了点mondrian。启动tomcat，在浏览器输入<a href="http://localhost/mondiran">http://localhost/mondiran</a> 看到了demo。需要说明一下的是，mondrian的发布包含了Jpivot，用它来做展示层，所以不用再去单独下载Jpivot了。</p>
<p>1.3&nbsp;数据库建表，在MySQL数据库里面建立table，借用了kswaking的数据库结构</p>
<p><span>在这个<span>tiny</span>的系统中，数据库有<span>3</span>个表<span>tb_employee</span>（职员表）<span>,tb_time</span>（时间表）<span>,tb_salary</span>（薪酬表）。表结构如下：</span></p>
<p><span>drop table tb_employee;</span></p>
<p><span>create table tb_employee</span></p>
<p><span>(</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>employee_id<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>number,<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--</span><span>职员<span>id<span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>employee_name<span>&nbsp;&nbsp; </span>varchar2(10)<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--</span><span>职员姓名</span></p>
<p><span>);</span></p>
<p>&nbsp;</p>
<p><span>drop table tb_time;</span></p>
<p><span>create table tb_time</span></p>
<p><span>(</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>time_id<span>&nbsp;&nbsp; </span>number,<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--</span><span>时间<span>id</span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>the_year&nbsp;char(4),<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--</span><span>年</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>the_month char(2)<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--</span><span>月</span></p>
<p><span>);</span></p>
<p>&nbsp;</p>
<p><span>drop table tb_salary;</span></p>
<p><span>create&nbsp;table tb_salary</span></p>
<p><span>(</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>employee_id&nbsp;number,<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--</span><span>职员<span>id<span>&nbsp;&nbsp;&nbsp; </span></span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>time_id<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>number,<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--</span><span>时间<span>id</span></span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>salary<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>number(19,4)<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>--</span><span>薪酬</span></p>
<p><span>);</span></p>
<p>&nbsp;</p>
<p><span>当然，为了使系统能够运行，还需要读者向数据库表中插入一些数据。</span></p>
<p>二. mondrian测试</p>
<p>&nbsp; 需要说明的是mondrian使用了MS一样的<font face=宋体><span>MDX</span>语言实现查询，这对于从MS Analyze Services入门的人真是一个好消息。</font></p>
<p>2.1 先编写schema。</p>
<p>&lt;?xml version="1.0"?&gt;<br>&nbsp; &lt;Schema name="Mondrian"&gt;<br>&nbsp; &nbsp; &lt;Cube name="CubeTest"&gt;<br>&nbsp;&nbsp;&nbsp; &lt;Table name="tb_salary"/&gt;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;Dimension name="Employee" foreignKey="employee_id"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Hierarchy hasAll="true" primaryKey="employee_id"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Table name="tb_employee"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&lt;Level name="employeeID" column="employee_id" uniqueMembers="true"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&lt;Property name="employeeName" column="employee_name"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&lt;/Level&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/Hierarchy&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/Dimension&gt;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;Dimension name="Time" foreignKey="time_id"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Hierarchy hasAll="false" primaryKey="time_id"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Table name="tb_time"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Level name="year" column="the_year" uniqueMembers="false"/&gt;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Level name="month" column="the_month" uniqueMembers="false"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/Hierarchy&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/Dimension&gt;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;Measure name="Salary" column="salary" aggregator="sum"/&gt;</p>
<p>&nbsp; &lt;/Cube&gt;<br>&lt;/Schema&gt;</p>
<p>这个schema定义了一个cube，包含两个Dimension和一个Measure。很容易看懂，就不解释了。<br><span>文件路径为webapps/mondrian/<span>WEB-INF/queries/mondriantest.xml。</span></span></p>
<p><span><span>为了后面的测试方便，我把文件放到了queries目录里面。</span></span></p>
<p><span><span>因为用MySQL建表的时候都用小写的，所以schema里面的字段名也都用了小写（我一开始也使用大写的，结果出错，找不到字段），<a id=ArticleTitle1_ArticleTitle1_AuthorLink href="http://dev.csdn.net/user/calvinxiu"><font face=Arial>calvinxiu</font></a>的文章说如果是Oracle数据库，这里的字段要用大写。</span></span></p>
<p><span></span>&nbsp;</p>
<p><span></span>&nbsp;</p>
<p><span><span>2.2 编写JSP</span></span></p>
<p><span></span>&nbsp;</p>
<p><span><span>&lt;%@ page import="mondrian.olap.*"%&gt;<br>&lt;%<br>&nbsp; Connection connection = DriverManager.getConnection("Provider=mondrian; Jdbc=jdbc:mysql://localhost/mondrian; JdbcUser=root; JdbcPassword=; Catalog=file:///usr/local/apache-tomcat-5.5.12/webapps/mondrian/WEB-INF/queries/mondriantest.xml; JdbcDriver=com.mysql.jdbc.Driver", null, false);<br></span></span></p>
<p><span><span>&nbsp; String querystr = " select {[Measures].[Salary]} ON COLUMNS, {[Employee].[employeeId].Members} ON ROWS from CubeTest ";<br></span></span></p>
<p><span><span>&nbsp; Query query=connection.parseQuery(querystr);<br>&nbsp; Result result = connection.execute(query);<br>&nbsp; out.println("get result");<br>%&gt;<br></span></span></p>
<p><span><span>可以看到mondrian也使用jdbc来连接数据库的，其中要特别注意的是Catalog指名了schema的位置。</span></span></p>
<p><span></span>&nbsp;</p>
<p><span><span>文件路径webapps/mondrian/mondriantestmdx.jsp</span></span></p>
<p><span></span>&nbsp;</p>
<p><span><span>2.3 测试</span></span></p>
<p><span><span>在浏览器输入<a href="http://localhost/mondrian/mondriantestmdx.jsp">http://localhost/mondrian/mondriantestmdx.jsp</a> 可以看到显示的结果 get result，说明一切正常。</span></span></p>
<p><span></span>&nbsp;</p>
<p><span></span>&nbsp;</p>
<p><span><span>到目前为止，我们只测试了Mondrian，它只负责数据的提取和组织，所以在画面上没有看到任何的数据，下一篇文章将继续研究数据的展现 - Jpivot。</span></span></p>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/118147.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2007-05-17 18:33 <a href="http://www.blogjava.net/zhangzhong1018/articles/118147.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ssh 配置 （转 http://blog.csdn.net/daryl715）</title><link>http://www.blogjava.net/zhangzhong1018/articles/112995.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Mon, 23 Apr 2007 09:19:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/112995.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/112995.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/112995.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/112995.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/112995.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 网上有很多关于SSH架构的实例文章，但都显得复杂，我想，入门的朋友，还是希望从最简单的CRUD操作开始，一些复杂的数据库关系，逻辑关系，以后在项目中就能碰到，所以，本文定位于从零开始的一个SSH架构的例子，功能很简单，就是完成一个人员的CRUD操作，麻雀虽小，五脏俱全，希望能对从来没有接触过三者结合开发的朋友带来一点点帮助，这个例子，也算是我的入门实例，从此，开始Struts+Spring+Hib...&nbsp;&nbsp;<a href='http://www.blogjava.net/zhangzhong1018/articles/112995.html'>阅读全文</a><img src ="http://www.blogjava.net/zhangzhong1018/aggbug/112995.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2007-04-23 17:19 <a href="http://www.blogjava.net/zhangzhong1018/articles/112995.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大小写 中文转换</title><link>http://www.blogjava.net/zhangzhong1018/articles/112976.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Mon, 23 Apr 2007 08:23:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/112976.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/112976.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/112976.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/112976.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/112976.html</trackback:ping><description><![CDATA[<p>public class Test {<br>&nbsp;/*<br>&nbsp; *&nbsp; &lt;p&gt;Description: 字符串处理的公共类&lt;/p&gt;<br>&nbsp; *&nbsp; &lt;p&gt;Copyright 2006 &lt;/p&gt;<br>&nbsp; *&nbsp; @author&nbsp; leonards<br>&nbsp; *&nbsp; @Create Date : 2006-11-23<br>&nbsp; */</p>
<p>&nbsp;/*<br>&nbsp; *&nbsp; 将字符串转换成中文的大写货币值<br>&nbsp; *&nbsp; @param&nbsp;&nbsp; moneyStr<br>&nbsp; *&nbsp; @return<br>&nbsp; */<br>&nbsp;public static String convertToCapitalMoney(String moneyStr) {<br>&nbsp;&nbsp;double money = 0;<br>&nbsp;&nbsp;try {<br>&nbsp;&nbsp;&nbsp;money = Double.parseDouble(moneyStr);<br>&nbsp;&nbsp;} catch (Exception e) {</p>
<p>&nbsp;&nbsp;}<br>&nbsp;&nbsp;return convertToCapitalMoney(money);<br>&nbsp;}</p>
<p>&nbsp;/*<br>&nbsp; *&nbsp; 将数字转换成中文的大写货币值<br>&nbsp; *&nbsp; @param&nbsp;&nbsp; moneyValue<br>&nbsp; *&nbsp; @return<br>&nbsp; */<br>&nbsp;public static String convertToCapitalMoney(double moneyValue) {<br>&nbsp;&nbsp;double money = moneyValue + 0.005; //&nbsp; 防止浮点数四舍五入造成误差<br>&nbsp;&nbsp;String Result = "";<br>&nbsp;&nbsp;String capitalLetter = "零壹贰叁肆伍陆柒捌玖";<br>&nbsp;&nbsp;String moneytaryUnit = "分角圆拾佰仟万拾佰仟亿拾佰仟万拾佰仟亿拾佰仟";<br>&nbsp;&nbsp;String tempCapital, tempUnit;</p>
<p>&nbsp;&nbsp;int integer; //&nbsp; 钱的整数部分<br>&nbsp;&nbsp;int point; //&nbsp; 钱的小数部分<br>&nbsp;&nbsp;int tempValue; //&nbsp; 钱的每一位的值<br>&nbsp;&nbsp;integer = (int) money;<br>&nbsp;&nbsp;point = (int) (100 * (money - (float) integer));</p>
<p>&nbsp;&nbsp;if (integer == 0)<br>&nbsp;&nbsp;&nbsp;Result = "零圆";<br>&nbsp;&nbsp;/*<br>&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp; 货币整数部分操作<br>&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp; 1.&nbsp;&nbsp;&nbsp; 依次取得每一位上的值<br>&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp; 2.&nbsp;&nbsp;&nbsp; 转换成大写<br>&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp; 3.&nbsp;&nbsp;&nbsp; 确定货币单位<br>&nbsp;&nbsp; */<br>&nbsp;&nbsp;for (int i = 1; integer &gt; 0; i++) {<br>&nbsp;&nbsp;&nbsp;tempValue = (integer % 10);<br>&nbsp;&nbsp;&nbsp;tempCapital = capitalLetter.substring(tempValue, tempValue + 1);<br>&nbsp;&nbsp;&nbsp;tempUnit = moneytaryUnit.substring(i + 1, i + 2);<br>&nbsp;&nbsp;&nbsp;Result = tempCapital + tempUnit + Result;<br>&nbsp;&nbsp;&nbsp;integer = integer / 10;<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;/*<br>&nbsp;&nbsp; *&nbsp; 货币小数部分操作<br>&nbsp;&nbsp; */<br>&nbsp;&nbsp;tempValue = (point / 10);<br>&nbsp;&nbsp;for (int i = 1; i &gt; -1; i--) {<br>&nbsp;&nbsp;&nbsp;tempCapital = capitalLetter.substring(tempValue, tempValue + 1);<br>&nbsp;&nbsp;&nbsp;tempUnit = moneytaryUnit.substring(i, i + 1);<br>&nbsp;&nbsp;&nbsp;Result = Result + tempCapital + tempUnit;<br>&nbsp;&nbsp;&nbsp;tempValue = point % 10;<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;return Result;<br>&nbsp;}</p>
<p>&nbsp;public static void main(String[] args) {</p>
<p>&nbsp;&nbsp;String money1 = Test.convertToCapitalMoney("400000000.215");<br>&nbsp;&nbsp;System.out.println(money1);<br>&nbsp;&nbsp;String money = Test.convertToCapitalMoney(40000000.215);<br>&nbsp;&nbsp;System.out.println(money);<br>&nbsp;}</p>
<p>}</p>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/112976.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2007-04-23 16:23 <a href="http://www.blogjava.net/zhangzhong1018/articles/112976.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java 日期数字</title><link>http://www.blogjava.net/zhangzhong1018/articles/112940.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Mon, 23 Apr 2007 05:55:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/112940.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/112940.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/112940.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/112940.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/112940.html</trackback:ping><description><![CDATA[<div><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)&nbsp;</span><span id=_39_355_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">...</span><span id=_39_355_Open_Text><span style="COLOR: #000000">{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&nbsp;a</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">100011</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&nbsp;b</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">200022</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Double&nbsp;d</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;Double(b</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">a);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DecimalFormat&nbsp;&nbsp;&nbsp;fmt&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;DecimalFormat(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">##,###,###,###,##0.00</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(fmt.format(d</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">100</span><span style="COLOR: #000000">));&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NumberFormat&nbsp;nf&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;NumberFormat.getCurrencyInstance();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(nf.format(</span><span style="COLOR: #000000">88888.88</span><span style="COLOR: #000000">));<br><br><br>}<br><br><br>&nbsp;&nbsp;&nbsp; Calendar calendar = Calendar.getInstance();<br>&nbsp;&nbsp;&nbsp; //getTime()方法是取得当前的日期，其返回值是一个java.util.Date类的对象<br>&nbsp;&nbsp;&nbsp; res.setResOpenDate(calendar.getTime());<br>&nbsp;&nbsp;&nbsp; int day = calendar.get(Calendar.DAY_OF_YEAR);<br>&nbsp;&nbsp;&nbsp; calendar.set(Calendar.DAY_OF_YEAR, day + 30);<br>&nbsp;&nbsp;&nbsp; //投票的有效期30天<br>&nbsp;&nbsp;&nbsp; res.setResEndDate(calendar.getTime());</span></span></div>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/112940.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2007-04-23 13:55 <a href="http://www.blogjava.net/zhangzhong1018/articles/112940.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java 面试题</title><link>http://www.blogjava.net/zhangzhong1018/articles/112935.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Mon, 23 Apr 2007 05:48:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/112935.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/112935.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/112935.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/112935.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/112935.html</trackback:ping><description><![CDATA[<strong><font color=#993300>第一，谈谈final，&nbsp;finally，&nbsp;finalize的区别。</font></strong>&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;final？修饰符（关键字）如果一个类被声明为final，意味着它不能再派生出新的子类，不能作为父类被继承。因此一个类不能既被声明为&nbsp;abstract的，又被声明为final的。将变量或方法声明为final，可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值，而在以后的引用中只能读取，不可修改。被声明为final的方法也同样只能使用，不能重载finally？再异常处理时提供&nbsp;finally&nbsp;块来执行任何清除操作。如果抛出一个异常，那么相匹配的&nbsp;catch&nbsp;子句就会执行，然后控制就会进入&nbsp;finally&nbsp;块（如果有的话）。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;finalize？方法名。Java&nbsp;技术允许使用&nbsp;finalize（）&nbsp;方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在&nbsp;Object&nbsp;类中定义的，因此所有的类都继承了它。子类覆盖&nbsp;finalize（）&nbsp;方法以整理系统资源或者执行其他清理工作。finalize（）&nbsp;方法是在垃圾收集器删除对象之前对这个对象调用的。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #993300"><strong>第二，Anonymous&nbsp;Inner&nbsp;Class&nbsp;（匿名内部类）&nbsp;是否可以extends（继承）其它类，是否可以implements（实现）interface（接口）？&nbsp;<br></strong></span><br>&nbsp;&nbsp;&nbsp;&nbsp;匿名的内部类是没有名字的内部类。不能extends（继承）&nbsp;其它类，但一个内部类可以作为一个接口，由另一个内部类实现。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<strong><span style="COLOR: #993300">第三，Static&nbsp;Nested&nbsp;Class&nbsp;和&nbsp;Inner&nbsp;Class的不同，说得越多越好（面试题有的很笼统）。</span></strong>&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;Nested&nbsp;Class&nbsp;（一般是C++的说法），Inner&nbsp;Class&nbsp;（一般是JAVA的说法）。Java内部类与C++嵌套类最大的不同就在于是否有指向外部的引用上。具体可见http：&nbsp;//www.frontfree.net/articles/services/view.asp？id=704&amp;page=1&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;注：&nbsp;静态内部类（Inner&nbsp;Class）意味着1创建一个static内部类的对象，不需要一个外部类对象，2不能从一个static内部类的一个对象访问一个外部类对象&nbsp;<br><br>&nbsp;&nbsp;&nbsp;<strong style="COLOR: #993300">&nbsp;第四，&amp;和&amp;&amp;的区别。</strong>&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&amp;是位运算符。&amp;&amp;是布尔逻辑运算符。&nbsp;<br><br>&nbsp;&nbsp;<strong style="COLOR: #993300">&nbsp;&nbsp;第五，HashMap和Hashtable的区别。&nbsp;<br></strong><br>&nbsp;&nbsp;&nbsp;&nbsp;都属于Map接口的类，实现了将惟一键映射到特定的值上。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;HashMap&nbsp;类没有分类或者排序。它允许一个&nbsp;null&nbsp;键和多个&nbsp;null&nbsp;值。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;Hashtable&nbsp;类似于&nbsp;HashMap，但是不允许&nbsp;null&nbsp;键和&nbsp;null&nbsp;值。它也比&nbsp;HashMap&nbsp;慢，因为它是同步的。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #993300"><strong>第六，Collection&nbsp;和&nbsp;Collections的区别。</strong>&nbsp;<br></span><br>&nbsp;&nbsp;&nbsp;&nbsp;Collections是个java.util下的类，它包含有各种有关集合操作的静态方法。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;Collection是个java.util下的接口，它是各种集合结构的父接口。&nbsp;<br><br>&nbsp;&nbsp;&nbsp; <strong style="COLOR: #993300">第七，什么时候用assert。</strong>&nbsp;&nbsp;<br><br>　　断言是一个包含布尔表达式的语句，在执行这个语句时假定该表达式为&nbsp;true。如果表达式计算为&nbsp;false，那么系统会报告一个&nbsp;AssertionError。它用于调试目的：&nbsp;&nbsp;<br><br>assert(a&nbsp;&gt;&nbsp;0);&nbsp;//&nbsp;throws&nbsp;an&nbsp;AssertionError&nbsp;if&nbsp;a&nbsp;&lt;=&nbsp;0&nbsp;&nbsp;<br><br>　　断言可以有两种形式：&nbsp;&nbsp;<br><br>　　assert&nbsp;Expression1&nbsp;;&nbsp;&nbsp;<br>　　assert&nbsp;Expression1&nbsp;:&nbsp;Expression2&nbsp;;&nbsp;&nbsp;<br><br>　　Expression1&nbsp;应该总是产生一个布尔值。&nbsp;&nbsp;<br>　　Expression2&nbsp;可以是得出一个值的任意表达式。这个值用于生成显示更多调试信息的&nbsp;String&nbsp;消息。&nbsp;&nbsp;<br>断言在默认情况下是禁用的。要在编译时启用断言，需要使用&nbsp;source&nbsp;1.4&nbsp;标记：&nbsp;&nbsp;<br><br>　　javac&nbsp;-source&nbsp;1.4&nbsp;Test.java&nbsp;&nbsp;<br><br>　　要在运行时启用断言，可使用&nbsp;-enableassertions&nbsp;或者&nbsp;-ea&nbsp;标记。&nbsp;&nbsp;<br>　　要在运行时选择禁用断言，可使用&nbsp;-da&nbsp;或者&nbsp;-disableassertions&nbsp;标记。&nbsp;&nbsp;<br>　　要系统类中启用断言，可使用&nbsp;-esa&nbsp;或者&nbsp;-dsa&nbsp;标记。还可以在包的基础上启用或者禁用断言。&nbsp;&nbsp;<br><br>　　可以在预计正常情况下不会到达的任何位置上放置断言。断言可以用于验证传递给私有方法的参数。不过，断言不应该用于验证传递给公有方法的参数，因为不管是否启用了断言，公有方法都必须检查其参数。不过，既可以在公有方法中，也可以在非公有方法中利用断言测试后置条件。另外，断言不应该以任何方式改变程序的状态。&nbsp;&nbsp;<br><br><br>　　<span style="COLOR: #993300"><strong>第八，GC是什么?&nbsp;为什么要有GC?&nbsp;(基础)。&nbsp;&nbsp;<br></strong></span><br>　　GC是垃圾收集器。Java&nbsp;程序员不用担心内存管理，因为垃圾收集器会自动进行管理。要请求垃圾收集，可以调用下面的方法之一：&nbsp;&nbsp;<br><br>　　System.gc()&nbsp;&nbsp;<br>　　Runtime.getRuntime().gc()&nbsp;&nbsp;<br><br>　　<span style="COLOR: #993300"><strong>第九，String&nbsp;s&nbsp;=&nbsp;new&nbsp;String("xyz");创建了几个String&nbsp;Object?&nbsp;&nbsp;<br></strong></span><br>　　两个对象，一个是&#8220;xyx&#8221;,一个是指向&#8220;xyx&#8221;的引用对象s。&nbsp;&nbsp;<br><br>　　<strong style="COLOR: #993300">第十，Math.round(11.5)等於多少?&nbsp;Math.round(-11.5)等於多少?</strong>&nbsp;&nbsp;<br><br>　　Math.round(11.5)返回（long）12，Math.round(-11.5)返回（long）-11;&nbsp;&nbsp;<br><br>　　<strong style="COLOR: #993300">第十一，short&nbsp;s1&nbsp;=&nbsp;1;&nbsp;s1&nbsp;=&nbsp;s1&nbsp;+&nbsp;1;有什么错?&nbsp;short&nbsp;s1&nbsp;=&nbsp;1;&nbsp;s1&nbsp;+=&nbsp;1;有什么错?&nbsp;&nbsp;<br></strong><br>　　short&nbsp;s1&nbsp;=&nbsp;1;&nbsp;s1&nbsp;=&nbsp;s1&nbsp;+&nbsp;1;有错，s1是short型，s1+1是int型,不能显式转化为short型。可修改为s1&nbsp;=(short)(s1&nbsp;+&nbsp;1)&nbsp;。short&nbsp;s1&nbsp;=&nbsp;1;&nbsp;s1&nbsp;+=&nbsp;1正确。&nbsp;&nbsp;<br><br>　　<span style="COLOR: #993300"><strong>第十二，sleep()&nbsp;和&nbsp;wait()&nbsp;有什么区别?&nbsp;搞线程的最爱</strong></span>&nbsp;&nbsp;<br><br>　　sleep()方法是使线程停止一段时间的方法。在sleep&nbsp;时间间隔期满后，线程不一定立即恢复执行。这是因为在那个时刻，其它线程可能正在运行而且没有被调度为放弃执行，除非(a)&#8220;醒来&#8221;的线程具有更高的优先级，(b)正在运行的线程因为其它原因而阻塞。&nbsp;&nbsp;<br><br>　　wait()是线程交互时，如果线程对一个同步对象x&nbsp;发出一个wait()调用，该线程会暂停执行，被调对象进入等待状态，直到被唤醒或等待时间到。&nbsp;&nbsp;<br><br>　　<strong><span style="COLOR: #993300">第十三，Java有没有goto?</span>&nbsp;</strong>&nbsp;<br><br>　　Goto?java中的保留字，现在没有在java中使用。&nbsp;&nbsp;<br><br>　　<strong style="COLOR: #993300">第十四，数组有没有length()这个方法?&nbsp;String有没有length()这个方法？</strong>&nbsp;&nbsp;<br><br>　　数组没有length()这个方法，有length的属性。&nbsp;&nbsp;<br>　　String有有length()这个方法。&nbsp;&nbsp;<br><br>　　<strong><span style="COLOR: #993300">第十五，Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?</span>&nbsp;</strong>&nbsp;<br><br>　　方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现，重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数，我们说该方法被重写&nbsp;(Overriding)。子类的对象使用这个方法时，将调用子类中的定义，对它而言，父类中的定义如同被&#8220;屏蔽&#8221;了。如果在一个类中定义了多个同名的方法，它们或有不同的参数个数或有不同的参数类型，则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。&nbsp;&nbsp;<br><br>　　<span style="COLOR: #993300"><strong>第十六，Set里的元素是不能重复的，那么用什么方法来区分重复与否呢?&nbsp;是用==还是equals()?&nbsp;它们有何区别</strong></span>?&nbsp;&nbsp;<br><br>　　Set里的元素是不能重复的，那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等。&nbsp;&nbsp;<br><br>　　equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖，为的是当两个分离的对象的内容和类型相配的话，返回真值。&nbsp;&nbsp;<br><br>　　<strong style="COLOR: #993300">第十七，给我一个你最常见到的runtime&nbsp;exception</strong>。&nbsp;&nbsp;<br><br>　　ArithmeticException,&nbsp;ArrayStoreException,&nbsp;BufferOverflowException,&nbsp;BufferUnderflowException,&nbsp;&nbsp;CannotRedoException,&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CannotUndoException,&nbsp;&nbsp;ClassCastException,&nbsp;CMMException,&nbsp;&nbsp;&nbsp;ConcurrentModificationException,&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DOMException,&nbsp;EmptyStackException,&nbsp;IllegalArgumentException,&nbsp;&nbsp;IllegalMonitorStateException,&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IllegalPathStateException,&nbsp;&nbsp;IllegalStateException,&nbsp;ImagingOpException,&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IndexOutOfBoundsException,&nbsp;&nbsp;MissingResourceException,&nbsp;&nbsp;NegativeArraySizeException,&nbsp;&nbsp;NoSuchElementException,&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NullPointerException,&nbsp;&nbsp;ProfileDataException,&nbsp;ProviderException,&nbsp;&nbsp;RasterFormatException,&nbsp;&nbsp;SecurityException,&nbsp;SystemException,&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UndeclaredThrowableException,&nbsp;&nbsp;UnmodifiableSetException,&nbsp;&nbsp;UnsupportedOperationException&nbsp;&nbsp;&nbsp;<br><br>　　<span style="COLOR: #800000"><strong>第十八，error和exception有什么区别?&nbsp;&nbsp;<br></strong></span><br>　　error&nbsp;表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。&nbsp;<br><br>　　exception&nbsp;表示一种设计或实现问题。也就是说，它表示如果程序运行正常，从不会发生的情况。&nbsp;&nbsp;<br><br><br>　　<span style="COLOR: #800000"><strong>第十九，List,&nbsp;Set,&nbsp;Map是否继承自Collection接口?&nbsp;&nbsp;<br></strong></span><br>　　List，Set是&nbsp;&nbsp;<br><br>　　Map不是&nbsp;&nbsp;<br><br>　　<span style="COLOR: #800000"><strong>第二十，abstract&nbsp;class和interface有什么区别?&nbsp;&nbsp;<br></strong></span><br>　　声明方法的存在而不去实现它的类被叫做抽象类（abstract&nbsp;class），它用于要创建一个体现某些基本行为的类，并为该类声明方法，但不能在该类中实现该类的情况。不能创建abstract&nbsp;类的实例。然而可以创建一个变量，其类型是一个抽象类，并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract&nbsp;类的子类为它们父类中的所有抽象方法提供实现，否则它们也是抽象类为。取而代之，在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。&nbsp;&nbsp;<br><br>　　接口（interface）是抽象类的变体。在接口中，所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的，没有一个有程序体。接口只可以定义static&nbsp;final成员变量。接口的实现与子类相似，除了该实现类不能从接口定义中继承行为。当类实现特殊接口时，它定义（即将程序体给予）所有这种接口的方法。然后，它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类，它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换，instanceof&nbsp;运算符可以用来决定某对象的类是否实现了接口。&nbsp;&nbsp;<br><br>　　<span style="COLOR: #800000"><strong>第二十一，abstract的method是否可同时是static,是否可同时是native，是否可同时是synchronized?&nbsp;&nbsp;<br><br></strong></span>　　都不能&nbsp;&nbsp;<br><br>　　<strong style="COLOR: #800000"><span style="COLOR: #800000">第二十二，接口是否可继承接口?&nbsp;抽象类是否可实现(implements)接口?&nbsp;抽象类是否可继承实体类(concrete&nbsp;class)?</span><span style="COLOR: #800000">&nbsp;&nbsp;</span><br></strong><br>　　接口可以继承接口。抽象类可以实现(implements)接口，抽象类是否可继承实体类，但前提是实体类必须有明确的构造函数。&nbsp;&nbsp;<br><br>　　<span style="COLOR: #800000"><strong>第二十三，启动一个线程是用run()还是start()?&nbsp;&nbsp;<br></strong></span><br>　　启动一个线程是调用start()方法，使线程所代表的虚拟处理机处于可运行状态，这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。&nbsp;&nbsp;<br><br><br><br>　　<strong style="COLOR: #800000">第二十四，构造器Constructor是否可被override?&nbsp;&nbsp;<br></strong><br>　　构造器Constructor不能被继承，因此不能重写Overriding，但可以被重载Overloading。&nbsp;&nbsp;<br><br>　　<span style="COLOR: #800000"><strong>第二十五，是否可以继承String类?&nbsp;&nbsp;<br></strong></span><br>　　String类是final类故不可以继承。&nbsp;&nbsp;<br><br>　<span style="COLOR: #800000"><strong>　第二十六，当一个线程进入一个对象的一个synchronized方法后，其它线程是否可进入此对象的其它方法?&nbsp;&nbsp;<br></strong></span><br>　　不能，一个对象的一个synchronized方法只能由一个线程访问。<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong> <span style="COLOR: red">(此答案有错误.其他线程可以进入此对象的其他方法,但不能进入此对象的synchronized方法)</span></strong>&nbsp;&nbsp;<br><br>　　<span style="COLOR: #800000"><strong>第二十七，try&nbsp;{}里有一个return语句，那么紧跟在这个try后的finally&nbsp;{}里的code会不会被执行，什么时候被执行，在return前还是后?</strong></span>&nbsp;&nbsp;<br><br>　　会执行，在return前执行。&nbsp;&nbsp;<br><br>　　<span style="COLOR: #800000"><strong>第二十八，编程题:&nbsp;用最有效率的方法算出2乘以8等於几?&nbsp;&nbsp;<br></strong></span><br>　　有C背景的程序员特别喜欢问这种问题。&nbsp;&nbsp;<br><br>　　2&nbsp;&lt;&lt;&nbsp;3&nbsp;&nbsp;<br><br>　　<span style="COLOR: #800000"><strong>第二十九，两个对象值相同(x.equals(y)&nbsp;==&nbsp;true)，但却可有不同的hash&nbsp;code，这句话对不对?&nbsp;&nbsp;<br></strong></span><br>　　不对，有相同的hash&nbsp;code。&nbsp;&nbsp;<br><br>　　<strong><span style="COLOR: #800000">第三十，当一个对象被当作参数传递到一个方法后，此方法可改变这个对象的属性，并可返回变化后的结果，那么这里到底是值传递还是引用传递?</span>&nbsp;&nbsp;<br></strong><br>　　是值传递。Java&nbsp;编程语言只由值传递参数。当一个对象实例作为一个参数被传递到方法中时，参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变，但对象的引用是永远不会改变的。&nbsp;&nbsp;<br><br><br>　　<strong style="COLOR: #800000">第三十一，swtich是否能作用在byte上，是否能作用在long上，是否能作用在String上?&nbsp;&nbsp;<br></strong><br>　　switch（expr1）中，expr1是一个整数表达式。因此传递给&nbsp;switch&nbsp;和&nbsp;case&nbsp;语句的参数应该是&nbsp;int、&nbsp;short、&nbsp;char&nbsp;或者&nbsp;byte。long,string&nbsp;都不能作用于swtich。&nbsp;&nbsp;<br><br>　　<span style="COLOR: #800000"><strong>第三十二，编程题:&nbsp;写一个Singleton出来。&nbsp;<br></strong></span><br>　　Singleton模式主要作用是保证在Java应用程序中，一个类Class只有一个实例存在。&nbsp;&nbsp;<br><br>　　一般Singleton模式通常有几种种形式:&nbsp;&nbsp;<br><br>　　第一种形式:&nbsp;定义一个类，它的构造函数为private的，它有一个static的private的该类变量，在类初始化时实例话，通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。&nbsp;&nbsp;<br><br>public&nbsp;class&nbsp;Singleton&nbsp;{&nbsp;&nbsp;<br>　　private&nbsp;Singleton(){}&nbsp;&nbsp;<br>　　//在自己内部定义自己一个实例，是不是很奇怪？&nbsp;&nbsp;<br>　　//注意这是private&nbsp;只供内部调用&nbsp;&nbsp;<br>　　private&nbsp;static&nbsp;Singleton&nbsp;instance&nbsp;=&nbsp;new&nbsp;Singleton();&nbsp;&nbsp;<br>　　//这里提供了一个供外部访问本class的静态方法，可以直接访问　　&nbsp;&nbsp;<br>　　public&nbsp;static&nbsp;Singleton&nbsp;getInstance()&nbsp;{&nbsp;&nbsp;<br>　　　　return&nbsp;instance;&nbsp;　　&nbsp;&nbsp;<br>　　&nbsp;}&nbsp;&nbsp;<br>}&nbsp;&nbsp;<br><br>　　第二种形式:&nbsp;&nbsp;<br><br>public&nbsp;class&nbsp;Singleton&nbsp;{&nbsp;&nbsp;<br>　　private&nbsp;static&nbsp;Singleton&nbsp;instance&nbsp;=&nbsp;null;&nbsp;&nbsp;<br>　　public&nbsp;static&nbsp;synchronized&nbsp;Singleton&nbsp;getInstance()&nbsp;{&nbsp;&nbsp;<br>　　//这个方法比上面有所改进，不用每次都进行生成对象，只是第一次　　　&nbsp;　&nbsp;&nbsp;<br>　　//使用时生成实例，提高了效率！&nbsp;&nbsp;<br>　　if&nbsp;(instance==null)&nbsp;&nbsp;<br>　　　　instance＝new&nbsp;Singleton();&nbsp;&nbsp;<br>return&nbsp;instance;&nbsp;　　}&nbsp;&nbsp;<br>}&nbsp;&nbsp;<br><br>　　其他形式:&nbsp;&nbsp;<br><br>　　定义一个类，它的构造函数为private的，所有方法为static的。&nbsp;&nbsp;<br><br>　　一般认为第一种形式要更加安全些&nbsp;&nbsp;<br><br>　　第三十三&nbsp;Hashtable和HashMap&nbsp;&nbsp;<br><br>　　Hashtable继承自Dictionary类，而HashMap是Java1.2引进的Map&nbsp;interface的一个实现&nbsp;&nbsp;<br><br>　　HashMap允许将null作为一个entry的key或者value，而Hashtable不允许&nbsp;&nbsp;<br><br>　　还有就是，HashMap把Hashtable的contains方法去掉了，改成containsvalue和containsKey。因为contains方法容易让人引起误解。&nbsp;&nbsp;<br><br>　　最大的不同是，Hashtable的方法是Synchronize的，而HashMap不是，在多个线程访问Hashtable时，不需要自己为它的方法实现同步，而HashMap就必须为之提供外同步。&nbsp;&nbsp;<br><br>　　Hashtable和HashMap采用的hash/rehash算法都大概一样，所以性能不会有很大的差异。&nbsp;&nbsp;<br>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/112935.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2007-04-23 13:48 <a href="http://www.blogjava.net/zhangzhong1018/articles/112935.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>丁磊：当时理想是有房有车睡懒觉不准时上班有钱去旅游</title><link>http://www.blogjava.net/zhangzhong1018/articles/107979.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Mon, 02 Apr 2007 06:43:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/107979.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/107979.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/107979.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/107979.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/107979.html</trackback:ping><description><![CDATA[<span class=oblog_text><span id=BlogViewId>&nbsp;
<div id=msgcns!4DFBD1BB0A2A5AC5!367>
<div>
<p style="TEXT-INDENT: 2em"><font color=#000066>经历过的事情是一种收获。我是学工科的，我今天演讲的主题，选了李白的《行路难》：&#8220;长风破浪会有时，直挂云帆济沧海&#8221;，其实前面还有两句：行路难，行路难，多歧路，今安在？我有时候自己也不知道创业，从93大学本科毕业到现在，12年来怎么走过来的，跌跌撞撞，非常契合。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>其实我也和在座的大家一起，我自己不认为自己是一个非常聪明和有智慧的人。我在89年考大学，我是班上第10名，只高出重点分数线1分。我隔壁班的同学现在是你们浙大的老师，他当时是第一名呀，他高考的分数刚好比我高出100分。</font></p>
<p><font color=#000066>我当时89年的时候，看学校的介绍，叫电子科技大学，这个大学1956年成立的，在四川成都，我也不知道成都在什么地方，我看它地处天府之国应该挺好玩的，我不想在浙江读大学，就填了志愿电子科技大学，没想到第一批就收到录取通知书了。其实我填的专业的也是很被动的，坦白地讲我在中学的并不是一个成绩非常优秀的学生。我在读初中的时候，我们所在的中学从来没人考上过大学，好在我在高中考上了奉化一中，我在奉化一中的第一学期，全班54个人，我的成绩倒数第6 名，还被老师痛骂一顿，说你们这6个人拖了班上后腿，我</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>印象非常深刻。后来我的成绩慢慢上升，考大学的时候最好，上升到班里的第10名。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>我在选择专业的时候，我很喜欢电脑，我在高中时候就在苹果电脑上写游戏，我自学完了 BASIC语言。我很想选计算机专业，我父母说什么专业都可以选，计算机不要选，因为计算机对人体有害，你每天坐在电脑前就像照X光。这个说法不是没道理的，因为当年计算机显象管的辐射的非常大的，对健康多少是有影响的。所以，我就填了成都电子科技大学的通讯专业，我被分到了全校最小的系——微波通讯，一个系只有30个人。我有个同乡说，你们这个系历来是最难分配的，而且分配之后的地方也非常不好，通常要跑到山沟沟里去，因为微波和卫星通讯都是在边远的农村。所以我在大学四年的时候，挺郁闷的，认为自己的专业不好。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>我那时经常跑图书馆去看计算机方面的书，还到计算机系里坐到后面去蹭课旁听。我觉得我在大学最大的收获就是学习方法，我可以坦诚地对同学们说，我在大学里学到的知识在我后来的工作里基本上就从来没有用到过。我经常在上课的时候看另外专业的书，每次到考试前我只要把书翻出来，复习一个星期就足够了。我在97年开始搞互联网的时候，没有几个人能教你互联网是什么，关于互联网的书还非常少，我印象中 TCPIP的书还要请别人吃饭才能借到，而且看书的时候要不停做笔记，因为那时候原版书非常少。我上大学的时候，如果对课程感兴趣，基本上能快速地掌握和领悟，这样的学习过程对我后来创业影响非常大。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>后来我自己也在思考，为什么我还比较顺利，我觉得我蛮顺利，<strong>我想有一点要向今天的同学们交流——你一定要做你喜欢做的事情，你不要勉强自己去干一件自己不喜欢的事情，这我觉得是非常非常重要的。当你喜欢做一件事情的时候，你一定很愿意把它做好，一定会钻进去，会成为一个领域的专家。</strong>我从高中毕业1986年到2005年，我根本没有离开过计算机相关专业领域，一个人像我这样专注于一个行业将近20年，当然也会成为一个专家。所以同学们喜欢一件事的时候，一定要深入下去，不要浅尝辄止，这是我非常深刻的一个体验。我前些日子在网上看一篇文章，苹果电脑创始人史帝夫.乔伊斯在读大学的时候退学，他发现大学的英文书法很好，就去听英文书法的课。他说英文书法的课对他日后创建苹果电脑公司有巨大的帮助——他发现电脑用来做排版没有一点艺术性可言，所以他把苹果电脑一出来就定位在艺术家专用的排版服务，而且他把大学里学习的书法艺术利用到了苹果电脑排版软件中，他第一个发明了人机交换图形操作界面，这一灵感完全来自于他读大学时对书法的爱好。所以我给同学们的一个建议就是，如果你在读大学的时候喜欢一件事情，就一定要深入下去。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>我在读大学四年的时候，有一件事情很辛苦，我每年四此往返宁波和成都，都是坐72个小时的火车硬座，我读大学时候从来没坐过一趟飞机。我后来在创业时候，回想到当年坐火车那么脏、那么拥挤，这种环境都过来了，创业时候遇到点困难算什么？对我人生的磨砺很大，这点我要感谢我的父母，他们一直不鼓励我坐飞机或者卧铺，他们说：你长大了，你应该自己去开拓，人生有甜也有苦。我非常感谢父母对我的教育。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>我1993年分配到宁波电信局，我在哪里度过了将近2年，我不喜欢电信局那里的环境，论资排辈很严重，年轻人没有什么机会，同时每天做的工作又是重复和枯燥，没有一点创新性，没有一点开拓。1995 年的时候，我一个人离开宁波去了广州。那时我要离开电信局的时候，电信局领导说：&#8220;我们这里从来没有大学生辞职的，你是国家培养的大学生，你怎么能够辞职？&#8221;单位说不能辞职，只能除名。后来到了 1995年4月，我跟领导说，我明天不来上班了，十几天后单位出了个文件，说丁磊旷工两个多星期，被除名了。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>我去广州之前经过选择。我在宁波时候就考虑过，95年时候的浙江不是一个做IT的好环境，比较保守。我的几个朋友对我说，广州自从邓小平南巡讲话后，经济发展很快；而且临近香港，人的思想意识都比内地开放。所以我一个人提个皮箱，辞职以后就跑到广州去了。</font></p>
<p><font color=#000066>到广州第一步是找个工作糊口，我当时找了一个美国的数据库公司Sybase找了份编程的工作。工作之余，我开始寻思创业的问题。当时没有人可以教我怎么创业，我父母都是国企员工，那时也没有一本书教你怎么当个老板。广州当时就有些年轻人很积极地办公司创业，这个给我启发很深刻。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066><strong>我在1997年5月的时候创办了网易公司，那时中国的互联网用户不到10万人。我们取名叫&#8220;网易&#8221;的意思，就是希望上网变得容易一点，这是一个很简单的想法。</strong>当时开公司要2个人，2个身份证，我就问朋友借了一个身份证，2个人到工商局去登记注册。在登记之前，我跟朋友说，我们要写个合约，合约中规定你要把股份无条件地转让给我，因为我是唯一的出资投资人。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>注册好了之后，我们找了一个很小的房间，大概只有8平方米，没空调，很热。我们成立网易后的第一个业务是帮人家写软件，先生存下来。有一天我和几个同事在商量，我们做互联网一定要找到一个好的商业模式。我们发现我们电脑的硬盘很大，有9个G的容量，大家不要笑，在1997年的时候，9个G的电脑硬盘是当时最大的了，不像现在硬盘可以有300G、 500G。而我们当时网易的网页页面一共才3页，加上图片1M都不到。我当时和我同事说，9G的硬盘浪费了好可惜啊，要不我们做个免费的个人主页吧！于是我们就推出了 20M的免费个人主页业务。就是这样一个非常简单的想法，对我们的公司产生了巨大的影响。我们当时抱着一个好玩的心态，做免费个人主页，给中国不到10万的互联网用户，让大家上传个人主页到我们一台服务器上。结果很莫名其妙的，我的印象中有2万多个人，包括国外的人，来申请我们的免费个人主页。结果我们在 CNNIC的年度最佳网站排名，我们就排到了第一名。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>自从我们被CNNIC排到中文优秀网站第一名后，华尔街的投资人就在我们门口排队了，我是隔三差五地接待香港过来的投资银行的人，他们抢着要给我们钱。那时候是1998年中，我们公司才10个人左右。那时候我们除了会写软件，什么也不会做，我们当时开发了一套免费电子软件，我自己当销售，我另外两个搭档是开发软件的，我就拿着</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>软件到处卖，我们卖得挺贵的，一套软件能卖10万美金。投资人认为我们这个10个人的小公司很厉害，又能写软件又能赚钱。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>我们当时的机会真的是很好的，非常重要一点就是把公司开在广州，离香港近，风险投资银行主动找我们，要给我们钱。从1999年年初到2000年6月30日美国上市，18个月时间我们一共融资了1亿1 千5百万美金。我作为公司的领导，不知道那么多钱怎么用，感到很困惑。公司本来是赚钱的，搞上市之后，不但不赚钱，而且老亏钱。我们当时的主要业务是网络广告，而2000年7月以后，全球互联网泡沫破灭，纳指从50000点跌到了1500点，市值蒸发了2/3。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>所以我在2000年的时候，我也面临着一个很大的转型。创办网易的时候，我只是想做一个小老板，我从来没有一个远大的理想，从来没有想要成为一个很有钱。我那时的理想就是，有个房子有辆汽车，不用准时上班可以睡懒觉，有钱可以出去旅游。你们千万不要以为我当时抱着一个伟大的理想去创办一个伟大的公司，绝对没有这个想法。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>到2000年以后，我们面临一个非常大的挑战，除了经济衰退，网络广告大滑坡，公司内部也面临了严重的问题。我那时很苦闷，员工也很没信心，不知道公司该往哪里走。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>我觉得当时有件事情做得很对，我苦闷的时候不是每天闷在办公室里，而是自己跑下去做市场调查，问了好多人，调查过好多行业，去调查人家怎么赢利。我后来发现了短信业务，一毛钱一条短信，成本只要5分 5厘，我非常积极地与移动合作。我说，网易有用户，有邮箱，有免费个人主页，如果我们每月从一个用户身上赚一块钱的话，</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>我们公司就能赢利持平。就这么一个很简单的4分多钱的生意，我们跟移动合作，利用自己巨大的用户资源和移动的接入平台，我们从广告的阴影中走出来。</font></p>
<p><font color=#000066>第二件事情，我跟我们同事说，我们做网页这个东西没有多少技术含量，我们每次出现点有创意的东西，我们的竞争对手新浪搜狐他们老抄我们，而且抄的速度很快。<strong>我说我们一定要做一个东西出来，技术含量很高，这帮人抄不了。所以我们决定做游戏，做网络游戏。</strong>其实网络游戏这个东西，我在1996年的时候就打过主意，那时侯主要是文字MUD。到了2000年，索尼和EA已经开发出了图形的网络游戏，我就找索尼和 EA，要做代理把他们的产品引进到中国。但是索尼和EA公司很高傲地说，不和中国公司合作，说中国都是盗版，不考虑中国市场，他们就直接把我赶出来。我回来之后很生气，我就对同事们讲，第一个，老美能做出来的东西，我们也一定能够做出来；第二个，我们有钱。我们虽然从来没有做过游戏，但我们可以出钱买一家做过游戏的公司。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>我后来在广州找到一家很小的公司，跟我几年钱创业的时候一样，7、8个人拨号上网在做游戏。我问他们怎么做游戏，他们一五一十地跟我说了，我就把他们这个公司买下来了，很便宜的，花了30万美金。<strong>我对网络游戏的信心非常强，因为网络游戏能防止盗版。网络游戏做出来之后，必须联到服务器上才能玩；同时网络游戏的技术含量相对高，我相信我的竞争对手像新浪抄不会，抄起来要很漫长。</strong>买下这个公司后，我还抽调了公司最优秀的技术团队过来参与开发游戏。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>游戏开发的时间很漫长，我们从2001年开发，到2002 年1月的时候，出来了第一款网络游戏产品——《大话西游》，结果这个游戏是失败的。失败的原因是，我们有一个工程师想创新，在我们的游戏客户端里嵌入了一个IE浏览器，结果这个IE5.0浏览器很不争气，经常导致游戏客户端crash，电脑要重启。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>我没有放弃，我对我们同事说，能不能重写一下，我的目标是稳定。同事说，老板没问题，给我们 6个月时间。2002年6月，我们的《大话西游2》诞生，从客户端到服务器都很稳定。但是开始的时候用户不多，大概只有3000人。我对同事说，不要怕，只要产品好，我去做营销。我当时也不知道怎么做营销，所以我就买了好多营销的书一个人看。光看书没有用，我翻开通讯录找。我想，中国谁的营销做得好，我去请教他总可以吧。后来我就找到了步步高的老总段永平，他当时在东莞。我找到他的名片后，就打电话给他请教，能不能去拜访他，他很客气地说：&#8220;那你就过来吧&#8221;。见面之后，我就请教他营销怎么做。我就是这样一边看书一边请教学习营销知识的。我们的《大话西游2》，也是从最初的3000人的规模，到现在最高在线人数达到55万人。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066><strong>我总结《大话西游2》的成功营销原则是，（1）我们的定价原则，我们定了市场上最高的价格。</strong>当时市场上别人都是三毛钱一小时，我四毛钱一小时，当时我的同事听说我定四毛钱一小时都认为我发疯了，韩国游戏都只有三毛钱一小时，你敢定四毛钱一小时？我说我敢这样定，是因为真正想玩这个游戏的人不会在意这一毛钱，在网吧玩一小</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>时就就需要2元钱，产品好多一毛钱是值得的。而四毛钱和三毛钱相比，给公司增加了33%的利润，在公司起步阶段是非常重要的<strong>。（</strong><strong>2</strong><strong>）我们从来不做短期利益的事情，那时很多游戏都有包月，一个月</strong><strong>35</strong><strong>元或者</strong><strong>40</strong><strong>元可以无限制玩。我说我们千万不要做包月制度，</strong>首先包月会缩短游戏的寿命；此外我们做游戏的目的，是&#8220;你玩游戏&#8221;而不是&#8220;游戏玩你&#8221;，包月制度会造成玩家过度沉迷。由于不包月产生的经济压力，我们的玩家相对都比较理性。而我们的竞争对手，由于包月，把游戏产品的寿命缩短了。前几年整个市场上大概有140多个游戏，其实真正做得好的就这么5、6个，真正赚到钱的也就是这么三四家公司。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066><strong>所以我想对大家说的是，我在做企业的时候，是个不断学习的过程，从来没有人教过我们怎么运作这个公司。做企业的时候，一些优秀的人才对公司非常重要。我认为虚心求教和咨询很重要。</strong>同时，我认为公司人才储备很重要。公司人不是越多越好，而是优秀的人才越多越好，一个出色的人才能顶好几个人。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>我们希望，员工在这个公司的时候是自己的兴趣，因为有兴趣你才会钻进去；第二个要&#8220;自我学习，自我管理&#8221;，要有不断进取的精神。这个行业进步很快，你不学习就会落后。我们当时派过去作游戏的几个工程师，自己都是非常热爱游戏的，所以他们能把游戏做好。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>我要跟大家分享的是，<strong>&#8220;信心&#8220;很重要。</strong><strong>2001年的时候，我刚开始做游戏的时候，所有的媒体所有的同行都说我疯了。那时候的报纸我还留着，都是一片责骂声。员工也不相信。但我有信心。</strong>结果呢，当时说我们坏话的儿女，他们现在都眼馋我们了。所以我送一句话给大家：&#8221;有信心不一定会成功，但没有信心一定不会成功。&#8221;</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066><strong>除了&#8220;信心&#8221;，我要跟大家讲的另外一个单词是&#8220;付出&#8221;。我们做企业那么久，每个项目时间很长，做游戏三年，做免费邮箱则是从</strong><strong>1998</strong><strong>年到</strong><strong>2006</strong><strong>年，积累了大批免费用户。我始终相信一句话：&#8220;付出不一定有回报，但是不断地付出，你一定有回报。&#8221;</strong><strong>&nbsp;</strong></font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066><strong>我觉得&#8220;创新&#8221;是个很危险的事情，我这个公司到今天，我很害怕创新。我觉得创新的风险非常大，尤其对于新公司来说，一不小心创新就把一家公司搞死了。创新的风险为什么大？首先创新需要很多钱，其次创新的东西需要用户有一个逐步接受的过程，还有创新要克服很多技术难关。</strong></font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>我坦白地讲，如果你要创新的话，你首先要把别人的东西搞明白了，摸透了，你再去搞创新。我看一本书讲微软公司的。微软公司的很多产品都不是自己发明的，譬如window，word和excel等等，都是follow别人的，但是它不断地做，不断地改进，就做成功了<strong>。所以我说，我们一定要做正确的事情，这个在我们企业里叫战略，战略要正确，动作可以慢，但战略一定要正确，看准了再跟上去，这样风险比较小，这样别人犯过的错误就不会再犯。</strong>我们现在在制定营销战略的时候，都首先看我们的竞争对手在干什么，他们做完了，我们把他们的问题全都找出来，这样我们就不再犯了，少走很多弯路。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>但是，你光有&#8220;战略&#8221;不行，还需要&#8220;执行&#8221;，要正确地做事。我们认为人是关键，同样的事情，不同的人做出来是不同的。微软的成功，</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>跟他的创始人非常专注在产品上很有关系。所以我说，一个企业的成功，产品是最至关重要的。我现在很郁闷，一些媒体老是说资本运作，我到现在搞不清楚资本运作是怎么回事情。现在很多企业沉迷于兼并和收购，我最不敢作收购和兼并，我觉得兼并和收购我看不懂。我公司除了20001年收购了这个7、8人的游戏公司外，没做过收购兼并。做事情就是踏踏实实地，把你的产品做好，当你的产品做得好，赢利才是顺理成章的。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>最后，我觉得我在做企业的过程中一直在学习。网易现在已经成为中国互联网行业中赢利能力最高的公司，我们现在有1800人，其中还包括400个客户服务人员。<strong>我做梦都没想到我有朝一日会掌握一家赢利超过</strong><strong>2</strong><strong>亿</strong><strong>5</strong><strong>千万人民币的公司，我也是一路跌跌撞撞，边打边学的走过来的。我最后要送给同学们两句话，是句英语的</strong><strong>&nbsp;</strong></font></p>
<p><font color=#000066><strong>stay hungry 保持饥饿的状态，stay fulish 保持充实，保持求知状态，因为只有这样，你在人生的路上才能不停地进步。<br></strong></font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066><strong>回答同学们提问： </strong></font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>问：您最喜欢的书是什么：</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>答：如果你们对管理感兴趣的话，我推荐三本书《基业常青》、《从优秀到卓越》、《你的灯还亮着吗？》此外，我最近看得比较多的是《道德经》等哲学方面的书。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>问：您对网易的未来设想是什么？</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>答：网易要做优秀和卓越的中国互联网服务公司，能够为未来2亿的中国网民服务。我们要把产品做好，这是我的人生目标。而且我想证明，外国人能做好的产品，我们也能做好，譬如我们的免费邮箱就做得比外国好。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>问：中国的富豪似乎不太热衷慈善事业，您怎样认为？</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>答：我认识的几个富豪朋友，都对慈善事业很关心，但中国目前的情况下做慈善事业不够成熟。我今年1月5日，我捐助了1000万人民币给中国红十字会，捐给印度洋海啸。我其实很想做慈善，但找不到好方法，我很担心中国慈善机构的执行能力。但我有一点可以告诉大家，我一生用不掉那么多钱，我也不会把多余的钱留给我孩子，也不希望孩子继承公司，我想等环境成熟时候，有更多的时间能服务中国慈善事业。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>问：您刚才说不喜欢兼并其他公司，我想问的是，你是否考虑过网易公司是否会被别人兼并。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>答：我认为网易被别人收购的可能性不大，首先我个人是个超过股份50%的大股东，如果我不愿意，收购不太可能会成功；此外，阻止恶意收购还有&#8220;毒丸计划&#8221;这样的方式。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>问：网易和其他竞争对手似乎没什么不同？网易未来会采用什么什么新的形式？</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>答：<strong>我觉得专注能把一件事情做好是非常不容易的事情。</strong>有人问我，你应该多一点东西啊？譬如我们的邮件系统，能把这个系统做好，已经是个非常不容易的事情了，譬如反垃圾，反病毒。加一些花里胡哨的东西，不是一个理性企业的选择。虽然是一个邮箱，但竞争对手很难超越我们。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>我很佩服你们杭州的一个企业家——娃哈哈的宗庆后，我很佩服他。我说你能把卖水都做成这样，不容易啊。水的产品差异化很小，但水是生活中的必需品。我去年去新疆的喀那斯玩，在山沟沟里，没有可口可乐，却有娃哈哈的非常可乐。水这样的产品，再过十年还是这样的一瓶水。我觉得有时候做企业就是这样，在一个领域里做深做精了非常不容易。美国可口可乐，这么多年就做可口可乐；吉列这么多年来一直只做刮胡须刀；把一个产品做深做精很重要。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>问：网易游戏部门的长远发展规划是什么？</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>答：游戏的成功，除了产品好，还有渠道好，还要定价好，很多相关因素在里面。在我们游戏部门中，我们有很多经验可以共享，我们有很多失败的教训可以汲取。</font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>未来中国的游戏市场非常大，我们目前有四个游戏在同时做。我们认为做游戏非常关键的一点是&#8220;设计者的水平&#8221;，就像一部电影导演比<strong>演员更重要。我认为未来游戏的成功在于设计游戏的玩法上，这个很重要。</strong></font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066><strong></strong></font></p>
<p style="TEXT-INDENT: 2em"><font color=#000066>问：最后，我要代表所有毕业生问您，假设您现在是个毕业生，您有两个选择，一是出去创办一个未来可以成为像网易这样成功的公司，二是在网易这样一个成功的公司工作，您会选择哪个？</font></p>
<p><font color=#000066>答：我不鼓励毕业之后马上创业，因为你的经验不够，你会跌得很惨，甚至跌倒后站不起来。我当年就跌过一次，我们网易被停过牌，还被美国小股东告过，好在我们运气好，活过来了。<strong>如果我今天是个毕业生，我一定会找一个我喜欢的工作，而且我会努力把这个工作做好。</strong>现在很多同学投简历，是为了解决自己就业的问题。我建议同学们在毕业时候找工作时候，一定要找一份自己喜欢的工作，把自己的兴趣放进去。只要你有信心，坚持努力，终有一天你会心想事成的。</font></p>
</div>
</div>
</span></span>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/107979.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2007-04-02 14:43 <a href="http://www.blogjava.net/zhangzhong1018/articles/107979.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>单例模式</title><link>http://www.blogjava.net/zhangzhong1018/articles/107959.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Mon, 02 Apr 2007 06:12:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/107959.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/107959.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/107959.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/107959.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/107959.html</trackback:ping><description><![CDATA[<span class=oblog_text>&nbsp;
<p>概要 <br>单例模式是最简单的设计模式之一，但是对于Java的开发者来说，它却有很多缺陷。在本月的专栏中，David Geary探讨了单例模式以及在面对多线程（multithreading)、类装载器（classloaders）和序列化(serialization)时如何处理这些缺陷。</p>
<p>单例模式适合于一个类只有一个实例的情况，比如窗口管理器，打印缓冲池和文件系统，它们都是原型的例子。典型的情况是，那些对象的类型被遍及一个软件系统的不同对象访问，因此需要一个全局的访问指针，这便是众所周知的单例模式的应用。当然这只有在你确信你不再需要任何多于一个的实例的情况下。 <br>单例模式的用意在于前一段中所关心的。通过单例模式你可以：</p>
<p>确保一个类只有一个实例被建立 <br>提供了一个对对象的全局访问指针 <br>在不影响单例类的客户端的情况下允许将来有多个实例</p>
<p>尽管单例设计模式如在下面的图中的所显示的一样是最简单的设计模式，但对于粗心的Java开发者来说却呈现出许多缺陷。这篇文章讨论了单例模式并揭示了那些缺陷。 <br>注意：你可以从Resources下载这篇文章的源代码。</p>
<p>单例模式</p>
<p>在《设计模式》一书中，作者这样来叙述单例模式的：确保一个类只有一个实例并提供一个对它的全局访问指针。 <br>下图说明了单例模式的类图。 <br>（图1）&nbsp;<br>&nbsp;<a href="http://www.javaworld.com/javaworld/jw-04-2003/images/jw-0425-designpatterns1.jpg" target=_blank><img onmousewheel="return bbimg(this)" title=点击在新窗口查看原始图片 style="ZOOM: 110%" alt="" src="http://www.javaworld.com/javaworld/jw-04-2003/images/jw-0425-designpatterns1.jpg" onload="java_script_:if(this.width>500)this.width=500" border=0></a><br>单例模式的类图</p>
<p>正如你在上图中所看到的，这不是单例模式的完整部分。此图中单例类保持了一个对唯一的单例实例的静态引用，并且会从静态getInstance()方法中返回对那个实例的引用。 <br>例1显示了一个经典的单例模式的实现。 <br>例1.经典的单例模式</p>
<p>代码<br>public class ClassicSingleton {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; private static ClassicSingleton instance = null;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; protected ClassicSingleton() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Exists only to defeat instantiation.&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; public static ClassicSingleton getInstance() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(instance == null) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; instance = new ClassicSingleton();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return instance;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>}&nbsp;&nbsp;&nbsp; </p>
<p>在例1中的单例模式的实现很容易理解。ClassicSingleton类保持了一个对单独的单例实例的静态引用，并且从静态方法getInstance()中返回那个引用。 <br>关于ClassicSingleton类，有几个让我们感兴趣的地方。首先，ClassicSingleton使用了一个众所周知的懒汉式实例化去创建那个单例类的引用;结果，这个单例类的实例直到getInstance()方法被第一次调用时才被创建。这种技巧可以确保单例类的实例只有在需要时才被建立出来。其次，注意ClassicSingleton实现了一个protected的构造方法，这样客户端不能直接实例化一个ClassicSingleton类的实例。然而，你会惊奇的发现下面的代码完全合法： <br>代码<br>public class SingletonInstantiator {&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; public SingletonInstantiator() {&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; ClassicSingleton instance = ClassicSingleton.getInstance();&nbsp;&nbsp;&nbsp; <br>ClassicSingleton anotherInstance =&nbsp;&nbsp;&nbsp; <br>new ClassicSingleton();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp; <br>}&nbsp;&nbsp;&nbsp; </p>
<p>前面这个代码片段为何能在没有继承ClassicSingleton并且ClassicSingleton类的构造方法是protected的情况下创建其实例？答案是protected的构造方法可以被其子类以及在同一个包中的其它类调用。因为ClassicSingleton和SingletonInstantiator位于相同的包（缺省的包），所以SingletonInstantiator方法能创建ClasicSingleton的实例。 <br>这种情况下有两种解决方案：一是你可以使ClassicSingleton的构造方法变化私有的（private）这样只有ClassicSingleton的方法能调用它;然而这也意味着ClassicSingleton不能有子类。有时这是一种很合意的解决方法，如果确实如此，那声明你的单例类为final是一个好主意，这样意图明确，并且让编译器去使用一些性能优化选项。另一种解决方法是把你的单例类放到一个外在的包中，以便在其它包中的类（包括缺省的包）无法实例化一个单例类。 <br>关于ClassicSingleton的第三点感兴趣的地方是，如果单例由不同的类装载器装入，那便有可能存在多个单例类的实例。假定不是远端存取，例如一些servlet容器对每个servlet使用完全不同的类装载器，这样的话如果有两个servlet访问一个单例类，它们就都会有各自的实例。 <br>第四点，如果ClasicSingleton实现了java.io.Serializable接口，那么这个类的实例就可能被序列化和复原。不管怎样，如果你序列化一个单例类的对象，接下来复原多个那个对象，那你就会有多个单例类的实例。 <br>最后也许是最重要的一点，就是例1中的ClassicSingleton类不是线程安全的。如果两个线程，我们称它们为线程1和线程2，在同一时间调用ClassicSingleton.getInstance()方法，如果线程1先进入if块，然后线程2进行控制，那么就会有ClassicSingleton的两个的实例被创建。</p>
<p>正如你从前面的讨论中所看到的，尽管单例模式是最简单的设计模式之一，在Java中实现它也是决非想象的那么简单。这篇文章接下来会揭示Java规范对单例模式进行的考虑，但是首先让我们近水楼台的看看你如何才能测试你的单例类。</p>
<p>测试单例模式</p>
<p>接下来，我使用与log4j相对应的JUnit来测试单例类，它会贯穿在这篇文章余下的部分。如果你对JUnit或log4j不很熟悉，请参考相关资源。</p>
<p>例2是一个用JUnit测试例1的单例模式的案例： <br>例2.一个单例模式的案例</p>
<p>代码<br>import org.apache.log4j.Logger;&nbsp;&nbsp;&nbsp; <br>import junit.framework.Assert;&nbsp;&nbsp;&nbsp; <br>import junit.framework.TestCase;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>public class SingletonTest extends TestCase {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; private ClassicSingleton sone = null, stwo = null;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; private static Logger logger = Logger.getRootLogger();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; public SingletonTest(String name) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(name);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; public void setUp() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("getting singleton...");&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sone = ClassicSingleton.getInstance();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("...got singleton: " + sone);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("getting singleton...");&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stwo = ClassicSingleton.getInstance();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("...got singleton: " + stwo);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; public void testUnique() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("checking singletons for equality");&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertEquals(true, sone == stwo);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>}&nbsp;&nbsp;&nbsp; </p>
<p>例2两次调用ClassicSingleton.getInstance()，并且把返回的引用存储在成员变量中。方法testUnique()会检查这些引用看它们是否相同。例3是这个测试案例的输出： <br>例3.是这个测试案例的输出</p>
<p>代码<br>Buildfile: build.xml&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>init:&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [echo] Build 20030414 (14-04-2003 03:08)&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>compile:&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>run-test-text:&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [java] .INFO main: &lt;b&gt;getting singleton...&lt;/b&gt;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [java] INFO main: &lt;b&gt;created singleton:&lt;/b&gt; <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#83;&#105;&#110;&#103;&#108;&#101;&#116;&#111;&#110;&#64;&#101;&#56;&#54;&#102;&#52;&#49;"><u><font color=#0000ff>Singleton@e86f41</font></u></a>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [java] INFO main: ...got singleton: <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#83;&#105;&#110;&#103;&#108;&#101;&#116;&#111;&#110;&#64;&#101;&#56;&#54;&#102;&#52;&#49;"><u><font color=#0000ff>Singleton@e86f41</font></u></a>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [java] INFO main: &lt;b&gt;getting singleton...&lt;/b&gt;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [java] INFO main: ...got singleton: <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#83;&#105;&#110;&#103;&#108;&#101;&#116;&#111;&#110;&#64;&#101;&#56;&#54;&#102;&#52;&#49;"><u><font color=#0000ff>Singleton@e86f41</font></u></a>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [java] INFO main: checking singletons for equality&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [java] Time: 0.032&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [java] OK (1 test)&nbsp;&nbsp; </p>
<p>正如前面的清单所示，例2的简单测试顺利通过----通过ClassicSingleton.getInstance()获得的两个单例类的引用确实相同;然而，你要知道这些引用是在单线程中得到的。下面的部分着重于用多线程测试单例类。</p>
<p>多线程因素的考虑</p>
<p>在例1中的ClassicSingleton.getInstance()方法由于下面的代码而不是线程安全的： <br>代码<br>1: if(instance == null) {&nbsp;&nbsp;&nbsp; <br>2:&nbsp;&nbsp;&nbsp; instance = new Singleton();&nbsp;&nbsp;&nbsp; <br>3: }&nbsp;&nbsp;&nbsp; </p>
<p>如果一个线程在第二行的赋值语句发生之前切换，那么成员变量instance仍然是null，然后另一个线程可能接下来进入到if块中。在这种情况下，两个不同的单例类实例就被创建。不幸的是这种假定很少发生，这样这种假定也很难在测试期间出现（译注：在这可能是作者对很少出现这种情况而导致无法测试从而使人们放松警惕而感到叹惜）。为了演示这个线程轮换，我得重新实现例1中的那个类。例4就是修订后的单例类： <br>例4.人为安排的方式</p>
<p>代码<br>import org.apache.log4j.Logger;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>public class Singleton {&nbsp;&nbsp;&nbsp; <br>&nbsp; private static Singleton singleton = null;&nbsp;&nbsp;&nbsp; <br>&nbsp; private static Logger logger = Logger.getRootLogger();&nbsp;&nbsp;&nbsp; <br>&nbsp; private static boolean firstThread = true;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; protected Singleton() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; // Exists only to defeat instantiation.&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp; public static Singleton getInstance() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; if(singleton == null) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; simulateRandomActivity();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; singleton = new Singleton();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; logger.info("created singleton: " + singleton);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; return singleton;&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp; private static void simulateRandomActivity() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; try {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(firstThread) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; firstThread = false;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("sleeping...");&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // This nap should give the second thread enough time&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // to get by the first thread.&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.currentThread().sleep(50);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; catch(InterruptedException ex) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.warn("Sleep interrupted");&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp;&nbsp; <br>}&nbsp;&nbsp;&nbsp; </p>
<p>除了在这个清单中的单例类强制使用了一个多线程错误处理，例4类似于例1中的单例类。在getInstance()方法第一次被调用时，调用这个方法的线程会休眠50毫秒以便另外的线程也有时间调用getInstance()并创建一个新的单例类实例。当休眠的线程觉醒时，它也会创建一个新的单例类实例，这样我们就有两个单例类实例。尽管例4是人为如此的，但它却模拟了第一个线程调用了getInstance()并在没有完成时被切换的真实情形。 <br>例5测试了例4的单例类： <br>例5.失败的测试</p>
<p>代码<br>import org.apache.log4j.Logger;&nbsp;&nbsp;&nbsp; <br>import junit.framework.Assert;&nbsp;&nbsp;&nbsp; <br>import junit.framework.TestCase;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>public class SingletonTest extends TestCase {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; private static Logger logger = Logger.getRootLogger();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; private static Singleton singleton = null;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; public SingletonTest(String name) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(name);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; public void setUp() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; singleton = null;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; public void testUnique() throws InterruptedException {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Both threads call Singleton.getInstance().&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread threadOne = new Thread(new SingletonTestRunnable()),&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; threadTwo = new Thread(new SingletonTestRunnable());&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; threadOne.start();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; threadTwo.start();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; threadOne.join();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; threadTwo.join();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; private static class SingletonTestRunnable implements Runnable {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void run() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Get a reference to the singleton.&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Singleton s = Singleton.getInstance();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Protect singleton member variable from&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // multithreaded access.&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized(SingletonTest.class) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(singleton == null) // If local reference is null...&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; singleton = s;&nbsp;&nbsp;&nbsp;&nbsp; // ...set it to the singleton&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Local reference must be equal to the one and&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // only instance of Singleton; otherwise, we have two&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Singleton instances.&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertEquals(true, s == singleton);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>}&nbsp;&nbsp;&nbsp; </p>
<p>例5的测试案例创建两个线程，然后各自启动，等待完成。这个案例保持了一个对单例类的静态引用，每个线程都会调用Singleton.getInstance()。如果这个静态成员变量没有被设置，那么第一个线程就会将它设为通过调用getInstance()而得到的引用，然后这个静态变量会与一个局部变量比较是否相等。 <br>在这个测试案例运行时会发生一系列的事情：第一个线程调用getInstance()，进入if块，然后休眠;接着，第二个线程也调用getInstance()并且创建了一个单例类的实例。第二个线程会设置这个静态成员变量为它所创建的引用。第二个线程检查这个静态成员变量与一个局部备份的相等性。然后测试通过。当第一个线程觉醒时，它也会创建一个单例类的实例，并且它不会设置那个静态成员变量（因为第二个线程已经设置过了），所以那个静态变量与那个局部变量脱离同步，相等性测试即告失败。例6列出了例5的输出： <br>例6.例5的输出</p>
<p>代码<br>Buildfile: build.xml&nbsp;&nbsp;&nbsp; <br>init:&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [echo] Build 20030414 (14-04-2003 03:06)&nbsp;&nbsp;&nbsp; <br>compile:&nbsp;&nbsp;&nbsp; <br>run-test-text:&nbsp;&nbsp;&nbsp; <br>INFO Thread-1: sleeping...&nbsp;&nbsp;&nbsp; <br>INFO Thread-2: created singleton: <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#83;&#105;&#110;&#103;&#108;&#101;&#116;&#111;&#110;&#64;&#55;&#101;&#53;&#99;&#98;&#100;"><u><font color=#0000ff>Singleton@7e5cbd</font></u></a>&nbsp;&nbsp;&nbsp; <br>INFO Thread-1: created singleton: <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#83;&#105;&#110;&#103;&#108;&#101;&#116;&#111;&#110;&#64;&#55;&#48;&#52;&#101;&#98;&#98;"><u><font color=#0000ff>Singleton@704ebb</font></u></a>&nbsp;&nbsp;&nbsp; <br>junit.framework.AssertionFailedError: expected: but was:&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; at junit.framework.Assert.fail(Assert.java:47)&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; at junit.framework.Assert.failNotEquals(Assert.java:282)&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; at junit.framework.Assert.assertEquals(Assert.java:64)&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; at junit.framework.Assert.assertEquals(Assert.java:149)&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; at junit.framework.Assert.assertEquals(Assert.java:155)&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; at SingletonTest$SingletonTestRunnable.run(Unknown Source)&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; at java.lang.Thread.run(Thread.java:554)&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [java] .&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [java] Time: 0.577&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [java] OK (1 test)&nbsp;&nbsp;&nbsp; </p>
<p>到现在为止我们已经知道例4不是线程安全的，那就让我们看看如何修正它。</p>
<p>同步</p>
<p>要使例4的单例类为线程安全的很容易----只要像下面一个同步化getInstance()方法： <br>代码<br>public synchronized static Singleton getInstance() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; if(singleton == null) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; simulateRandomActivity();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; singleton = new Singleton();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; logger.info("created singleton: " + singleton);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; return singleton;&nbsp;&nbsp;&nbsp; <br>}&nbsp;&nbsp;&nbsp; </p>
<p>在同步化getInstance()方法后，我们就可以得到例5的测试案例返回的下面的结果： <br>代码<br>Buildfile: build.xml&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>init:&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [echo] Build 20030414 (14-04-2003 03:15)&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>compile:&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; [javac] Compiling 2 source files&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>run-test-text:&nbsp;&nbsp;&nbsp; <br>INFO Thread-1: sleeping...&nbsp;&nbsp;&nbsp; <br>INFO Thread-1: created singleton: <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#83;&#105;&#110;&#103;&#108;&#101;&#116;&#111;&#110;&#64;&#101;&#102;&#53;&#55;&#55;&#100;"><u><font color=#0000ff>Singleton@ef577d</font></u></a>&nbsp;&nbsp;&nbsp; <br>INFO Thread-2: created singleton: <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#83;&#105;&#110;&#103;&#108;&#101;&#116;&#111;&#110;&#64;&#101;&#102;&#53;&#55;&#55;&#100;"><u><font color=#0000ff>Singleton@ef577d</font></u></a>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [java] .&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [java] Time: 0.513&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [java] OK (1 test)&nbsp;&nbsp;&nbsp; <br>&nbsp; </p>
<p>这此，这个测试案例工作正常，并且多线程的烦恼也被解决;然而，机敏的读者可能会认识到getInstance()方法只需要在第一次被调用时同步。因为同步的性能开销很昂贵（同步方法比非同步方法能降低到100次左右），或许我们可以引入一种性能改进方法，它只同步单例类的getInstance()方法中的赋值语句。</p>
<p>一种性能改进的方法</p>
<p>寻找一种性能改进方法时，你可能会选择像下面这样重写getInstance()方法： <br>代码<br>public static Singleton getInstance() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; if(singleton == null) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized(Singleton.class) {&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; singleton = new Singleton();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; return singleton;&nbsp;&nbsp;&nbsp; <br>}&nbsp;&nbsp;&nbsp; </p>
<p>这个代码片段只同步了关键的代码，而不是同步整个方法。然而这段代码却不是线程安全的。考虑一下下面的假定：线程1进入同步块，并且在它给singleton成员变量赋值之前线程1被切换。接着另一个线程进入if块。第二个线程将等待直到第一个线程完成，并且仍然会得到两个不同的单例类实例。有修复这个问题的方法吗？请读下去。</p>
<p>双重加锁检查</p>
<p>初看上去，双重加锁检查似乎是一种使懒汉式实例化为线程安全的技术。下面的代码片段展示了这种技术： <br>代码<br>public static Singleton getInstance() {&nbsp;&nbsp;&nbsp; <br>&nbsp; if(singleton == null) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; synchronized(Singleton.class) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(singleton == null) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; singleton = new Singleton();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp; return singleton;&nbsp;&nbsp;&nbsp; <br>}&nbsp;&nbsp;&nbsp; </p>
<p>如果两个线程同时访问getInstance()方法会发生什么？想像一下线程1进行同步块马上又被切换。接着，第二个线程进入if 块。当线程1退出同步块时，线程2会重新检查看是否singleton实例仍然为null。因为线程1设置了singleton成员变量，所以线程2的第二次检查会失败，第二个单例类实例也就不会被创建。似乎就是如此。 <br>不幸的是，双重加锁检查不会保证正常工作，因为编译器会在Singleton的构造方法被调用之前随意给singleton赋一个值。如果在singleton引用被赋值之后而被初始化之前线程1被切换，线程2就会被返回一个对未初始化的单例类实例的引用。</p>
<p>一个改进的线程安全的单例模式实现</p>
<p>例7列出了一个简单、快速而又是线程安全的单例模式实现： <br>例7.一个简单的单例类 <br>代码<br>public class Singleton {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; public final static Singleton INSTANCE = new Singleton();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; private Singleton() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Exists only to defeat instantiation.&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>}&nbsp;&nbsp;&nbsp; <br>&nbsp; </p>
<p>这段代码是线程安全的是因为静态成员变量一定会在类被第一次访问时被创建。你得到了一个自动使用了懒汉式实例化的线程安全的实现;你应该这样使用它： <br>代码<br>Singleton singleton = Singleton.INSTANCE;&nbsp;&nbsp;&nbsp; <br>singleton.dothis();&nbsp;&nbsp;&nbsp; <br>singleton.dothat();&nbsp;&nbsp;&nbsp; <br>...&nbsp;&nbsp;&nbsp; </p>
<p>当然万事并不完美，前面的Singleton只是一个折衷的方案;如果你使用那个实现，你就无法改变它以便后来你可能想要允许多个单例类的实例。用一种更折哀的单例模式实现(通过一个getInstance()方法获得实例)你可以改变这个方法以便返回一个唯一的实例或者是数百个实例中的一个．你不能用一个公开且是静态的（public static)成员变量这样做．</p>
<p>你可以安全的使用例７的单例模式实现或者是例１的带一个同步的getInstance()方法的实现．然而，我们必须要研究另一个问题：你必须在编译期指定这个单例类，这样就不是很灵活．一个单例类的注册表会让我们在运行期指定一个单例类． </p>
<p>使用注册表 <br>使用一个单例类注册表可以：</p>
<p>在运行期指定单例类</p>
<p>防止产生多个单例类子类的实例 <br>在例8的单例类中，保持了一个通过类名进行注册的单例类注册表： <br>例8 带注册表的单例类</p>
<p>代码<br>import java.util.HashMap;&nbsp;&nbsp;&nbsp; <br>import org.apache.log4j.Logger;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>public class Singleton {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; private static HashMap map = new HashMap();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; private static Logger logger = Logger.getRootLogger();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; protected Singleton() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Exists only to thwart instantiation&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; public static synchronized Singleton getInstance(String classname) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(classname == null) throw new IllegalArgumentException("Illegal classname");&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Singleton singleton = (Singleton)map.get(classname);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(singleton != null) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("got singleton from map: " + singleton);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return singleton;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(classname.equals("SingeltonSubclass_One"))&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; singleton = new SingletonSubclass_One();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(classname.equals("SingeltonSubclass_Two"))&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; singleton = new SingletonSubclass_Two();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; map.put(classname, singleton);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("created singleton: " + singleton);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return singleton;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; // Assume functionality follows that's attractive to inherit&nbsp;&nbsp;&nbsp; <br>}&nbsp;&nbsp;&nbsp; </p>
<p>这段代码的基类首先创建出子类的实例，然后把它们存储在一个Map中。但是基类却得付出很高的代价因为你必须为每一个子类替换它的getInstance()方法。幸运的是我们可以使用反射处理这个问题。</p>
<p>使用反射</p>
<p>在例9的带注册表的单例类中，使用反射来实例化一个特殊的类的对象。与例8相对的是通过这种实现，Singleton.getInstance()方法不需要在每个被实现的子类中重写了。 <br>例9 使用反射实例化单例类 <br>代码<br>import java.util.HashMap;&nbsp;&nbsp;&nbsp; <br>import org.apache.log4j.Logger;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>public class Singleton {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; private static HashMap map = new HashMap();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; private static Logger logger = Logger.getRootLogger();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; protected Singleton() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Exists only to thwart instantiation&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; public static synchronized Singleton getInstance(String classname) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Singleton singleton = (Singleton)map.get(classname);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(singleton != null) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("got singleton from map: " + singleton);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return singleton;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; singleton = (Singleton)Class.forName(classname).newInstance();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(ClassNotFoundException cnf) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.fatal("Couldn't find class " + classname);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(InstantiationException ie) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.fatal("Couldn't instantiate an object of type " + classname);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(IllegalAccessException ia) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.fatal("Couldn't access class " + classname);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; map.put(classname, singleton);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("created singleton: " + singleton);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return singleton;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>}&nbsp;&nbsp;&nbsp; </p>
<p>关于单例类的注册表应该说明的是：它们应该被封装在它们自己的类中以便最大限度的进行复用。</p>
<p>封装注册表</p>
<p>例10列出了一个单例注册表类。 <br>例10 一个SingletonRegistry类</p>
<p>代码<br>import java.util.HashMap;&nbsp;&nbsp;&nbsp; <br>import org.apache.log4j.Logger;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>public class SingletonRegistry {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; public static SingletonRegistry REGISTRY = new SingletonRegistry();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; private static HashMap map = new HashMap();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; private static Logger logger = Logger.getRootLogger();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; protected SingletonRegistry() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Exists to defeat instantiation&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; public static synchronized Object getInstance(String classname) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object singleton = map.get(classname);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(singleton != null) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return singleton;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; singleton = Class.forName(classname).newInstance();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("created singleton: " + singleton);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(ClassNotFoundException cnf) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.fatal("Couldn't find class " + classname);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(InstantiationException ie) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.fatal("Couldn't instantiate an object of type " +&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; classname);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(IllegalAccessException ia) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.fatal("Couldn't access class " + classname);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; map.put(classname, singleton);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return singleton;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>}&nbsp;&nbsp;&nbsp; <br>&nbsp; </p>
<p>注意我是把SingletonRegistry类作为一个单例模式实现的。我也通用化了这个注册表以便它能存储和取回任何类型的对象。例11显示了的Singleton类使用了这个注册表。 <br>例11 使用了一个封装的注册表的Singleton类</p>
<p>代码<br>import java.util.HashMap;&nbsp;&nbsp;&nbsp; <br>import org.apache.log4j.Logger;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>public class Singleton {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; protected Singleton() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Exists only to thwart instantiation.&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; public static Singleton getInstance() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (Singleton)SingletonRegistry.REGISTRY.getInstance(classname);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>}&nbsp;&nbsp;&nbsp; </p>
<p>上面的Singleton类使用那个注册表的唯一实例通过类名取得单例对象。 <br>现在我们已经知道如何实现线程安全的单例类和如何使用一个注册表去在运行期指定单例类名，接着让我们考查一下如何安排类载入器和处理序列化。</p>
<p>Classloaders</p>
<p>在许多情况下，使用多个类载入器是很普通的--包括servlet容器--所以不管你在实现你的单例类时是多么小心你都最终可以得到多个单例类的实例。如果你想要确保你的单例类只被同一个的类载入器装入，那你就必须自己指定这个类载入器;例如：</p>
<p>代码<br>private static Class getClass(String classname)&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws ClassNotFoundException {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ClassLoader classLoader = Thread.currentThread().getContextClassLoader();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(classLoader == null)&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; classLoader = Singleton.class.getClassLoader();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (classLoader.loadClass(classname));&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>}&nbsp;&nbsp;&nbsp; </p>
<p>这个方法会尝试把当前的线程与那个类载入器相关联;如果classloader为null，这个方法会使用与装入单例类基类的那个类载入器。这个方法可以用Class.forName()代替。</p>
<p>序列化</p>
<p>如果你序列化一个单例类，然后两次重构它，那么你就会得到那个单例类的两个实例，除非你实现readResolve()方法，像下面这样： <br>例12 一个可序列化的单例类</p>
<p>代码<br>import org.apache.log4j.Logger;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>public class Singleton implements java.io.Serializable {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; public static Singleton INSTANCE = new Singleton();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; protected Singleton() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Exists only to thwart instantiation.&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; private Object readResolve() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return INSTANCE;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; </p>
<p>上面的单例类实现从readResolve()方法中返回一个唯一的实例;这样无论Singleton类何时被重构，它都只会返回那个相同的单例类实例。 <br>例13测试了例12的单例类： <br>例13 测试一个可序列化的单例类</p>
<p>代码<br>import java.io.*;&nbsp;&nbsp;&nbsp; <br>import org.apache.log4j.Logger;&nbsp;&nbsp;&nbsp; <br>import junit.framework.Assert;&nbsp;&nbsp;&nbsp; <br>import junit.framework.TestCase;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>public class SingletonTest extends TestCase {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; private Singleton sone = null, stwo = null;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; private static Logger logger = Logger.getRootLogger();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; public SingletonTest(String name) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(name);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; public void setUp() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sone = Singleton.INSTANCE;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stwo = Singleton.INSTANCE;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; public void testSerialize() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("testing singleton serialization...");&nbsp;&nbsp;&nbsp; <br>&lt;b&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeSingleton();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Singleton s1 = readSingleton();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Singleton s2 = readSingleton();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertEquals(true, s1 == s2);&lt;/b&gt;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; private void writeSingleton() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileOutputStream fos = new FileOutputStream("serializedSingleton");&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjectOutputStream oos = new ObjectOutputStream(fos);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Singleton s = Singleton.INSTANCE;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oos.writeObject(Singleton.INSTANCE);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oos.flush();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(NotSerializableException se) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.fatal("Not Serializable Exception: " + se.getMessage());&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(IOException iox) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.fatal("IO Exception: " + iox.getMessage());&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; private Singleton readSingleton() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Singleton s = null;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileInputStream fis = new FileInputStream("serializedSingleton");&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjectInputStream ois = new ObjectInputStream(fis);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s = (Singleton)ois.readObject();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(ClassNotFoundException cnf) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.fatal("Class Not Found Exception: " + cnf.getMessage());&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(NotSerializableException se) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.fatal("Not Serializable Exception: " + se.getMessage());&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(IOException iox) {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.fatal("IO Exception: " + iox.getMessage());&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return s;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; public void testUnique() {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("testing singleton uniqueness...");&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Singleton another = new Singleton();&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("checking singletons for equality");&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertEquals(true, sone == stwo);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br>}&nbsp;&nbsp;&nbsp; </p>
<p>前面这个测试案例序列化例12中的单例类，并且两次重构它。然后这个测试案例检查看是否被重构的单例类实例是同一个对象。下面是测试案例的输出：</p>
<p>代码<br>Buildfile: build.xml&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>init:&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [echo] Build 20030422 (22-04-2003 11:32)&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>compile:&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>run-test-text:&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [java] .INFO main: testing singleton serialization...&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [java] .INFO main: testing singleton uniqueness...&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [java] INFO main: checking singletons for equality&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [java] Time: 0.1&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; [java] OK (2 tests)&nbsp;&nbsp;&nbsp; <br>&nbsp; </p>
<p>单例模式结束语</p>
<p>单例模式简单却容易让人迷惑，特别是对于Java的开发者来说。在这篇文章中，作者演示了Java开发者在顾及多线程、类载入器和序列化情况如何实现单例模式。作者也展示了你怎样才能实现一个单例类的注册表，以便能够在运行期指定单例类。&nbsp;</p>
</span>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/107959.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2007-04-02 14:12 <a href="http://www.blogjava.net/zhangzhong1018/articles/107959.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>代理模式</title><link>http://www.blogjava.net/zhangzhong1018/articles/107957.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Mon, 02 Apr 2007 06:06:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/107957.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/107957.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/107957.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/107957.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/107957.html</trackback:ping><description><![CDATA[1. 代理模式<br><br>代理模式的作用是：为其他对象提供一种代理以控制对这个对象的访问。在某些情况下，一个客户不想或者不能直接引用另一个对象，而代理对象可以在客户端和目标对象之间起到中介的作用。<br><br>代理模式一般涉及到的角色有：<br><br>抽象角色：声明真实对象和代理对象的共同接口；<br><br>代理角色：代理对象角色内部含有对真实对象的引用，从而可以操作真实对象，同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时，代理对象可以在执行真实对象操作时，附加其他的操作，相当于对真实对象进行封装。<br><br>真实角色：代理角色所代表的真实对象，是我们最终要引用的对象。(参见文献1)<br><br>以下以《Java与模式》中的示例为例：<br><br>抽象角色：<br><br>abstract public class Subject<br><br>{<br><br>abstract public void request();<br><br>}<br><br>真实角色：实现了Subject的request()方法。<br><br>public class RealSubject extends Subject <br><br>{<br><br>public RealSubject()<br><br>{ <br><br>}<br><br><br><br>public void request()<br><br>{ <br><br>System.out.println("From real subject.");<br><br>}<br><br>}<br><br>代理角色：<br><br>public class ProxySubject extends Subject <br><br>{<br><br>private RealSubject realSubject; //以真实角色作为代理角色的属性<br><br><br><br>public ProxySubject()<br><br>{<br><br>}<br><br><br><br>public void request() //该方法封装了真实对象的request方法<br><br>{<br><br>preRequest(); <br><br>if( realSubject == null )<br><br>{<br><br>realSubject = new RealSubject();<br><br>}<br><br>realSubject.request(); //此处执行真实对象的request方法<br><br>postRequest(); <br><br>}<br><br><br><br>private void preRequest()<br><br>{<br><br>//something you want to do before requesting<br><br>}<br><br><br><br>private void postRequest()<br><br>{<br><br>//something you want to do after requesting<br><br>}<br><br>}<br><br>客户端调用：<br><br>Subject sub=new ProxySubject();<br><br>Sub.request();<br><br>由以上代码可以看出，客户实际需要调用的是RealSubject类的request()方法，现在用ProxySubject来代理 RealSubject类，同样达到目的，同时还封装了其他方法(preRequest(),postRequest())，可以处理一些其他问题。<br><br>另外，如果要按照上述的方法使用代理模式，那么真实角色必须是事先已经存在的，并将其作为代理对象的内部属性。但是实际使用时，一个真实角色必须对应一个代理角色，如果大量使用会导致类的急剧膨胀；此外，如果事先并不知道真实角色，该如何使用代理呢？这个问题可以通过Java的动态代理类来解决。<br><br><br><br>2.动态代理类<br><br>Java动态代理类位于Java.lang.reflect包下，一般主要涉及到以下两个类：<br><br>(1). Interface InvocationHandler：该接口中仅定义了一个方法Object：invoke(Object obj,Method method, Object[] args)。在实际使用时，第一个参数obj一般是指代理类，method是被代理的方法，如上例中的request()，args为该方法的参数数组。这个抽象方法在代理类中动态实现。<br><br><br>(2).Proxy：该类即为动态代理类，作用类似于上例中的ProxySubject，其中主要包含以下内容：<br><br>Protected Proxy(InvocationHandler h)：构造函数，估计用于给内部的h赋值。<br><br>Static Class getProxyClass (ClassLoader loader, Class[] interfaces)：获得一个代理类，其中loader是类装载器，interfaces是真实类所拥有的全部接口的数组。<br><br>Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)：返回代理类的一个实例，返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。<br><br><br><br>所谓Dynamic Proxy是这样一种class：它是在运行时生成的class，在生成它时你必须提供一组interface给它，然后该class就宣称它实现了这些 interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦，这个Dynamic Proxy其实就是一个Proxy，它不会替你作实质性的工作，在生成它的实例时你必须提供一个handler，由它接管实际的工作。(参见文献3)<br><br>在使用动态代理类时，我们必须实现InvocationHandler接口，以第一节中的示例为例：<br><br>抽象角色(之前是抽象类，此处应改为接口)：<br><br>public interface Subject<br><br>{<br><br>abstract public void request();<br><br>}<br><br>具体角色RealSubject：同上；<br><br><br><br>代理角色：<br><br>import java.lang.reflect.Method;<br><br>import java.lang.reflect.InvocationHandler;<br><br><br><br>public class DynamicSubject implements InvocationHandler {<br><br>private Object sub;<br><br><br><br>public DynamicSubject() {<br><br>}<br><br><br><br>public DynamicSubject(Object obj) {<br><br>sub = obj;<br><br>}<br><br><br><br><br><br>public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {<br><br>System.out.println("before calling " + method);<br><br><br><br>method.invoke(sub,args);<br><br><br><br>System.out.println("after calling " + method);<br><br>return null;<br><br>}<br><br><br><br>}<br><br><br><br>该代理类的内部属性为Object类，实际使用时通过该类的构造函数DynamicSubject(Object obj)对其赋值；此外，在该类还实现了invoke方法，该方法中的<br><br>method.invoke(sub,args);<br><br>其实就是调用被代理对象的将要被执行的方法，方法参数sub是实际的被代理对象，args为执行被代理对象相应操作所需的参数。通过动态代理类，我们可以在调用之前或之后执行一些相关操作。<br><br>客户端：<br><br>import java.lang.reflect.InvocationHandler;<br><br>import java.lang.reflect.Proxy;<br><br>import java.lang.reflect.Constructor;<br><br>import java.lang.reflect.Method;<br><br><br><br>public class Client<br><br>{<br><br><br><br>static public void main(String[] args) throws Throwable<br><br>{<br><br>RealSubject rs = new RealSubject(); //在这里指定被代理类<br><br>InvocationHandler ds = new DynamicSubject(rs); //初始化代理类<br><br>Class cls = rs.getClass();<br><br>//以下是分解步骤<br><br>/*<br><br>Class c = Proxy.getProxyClass(cls.getClassLoader(),cls.getInterfaces()) ;<br><br>Constructor ct=c.getConstructor(new Class[]{InvocationHandler.class});<br><br>Subject subject =(Subject) ct.newInstance(new Object[]{ds});<br><br>*/<br><br>//以下是一次性生成<br><br>Subject subject = (Subject) Proxy.newProxyInstance(cls.getClassLoader(),<br><br>cls.getInterfaces(),ds );<br><br><br><br>subject.request();<br><br>}<br><br>通过这种方式，被代理的对象(RealSubject)可以在运行时动态改变，需要控制的接口(Subject接口)可以在运行时改变，控制的方式(DynamicSubject类)也可以动态改变，从而实现了非常灵活的动态代理关系(参见文献2)。<br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td height=3>&nbsp;</td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td>
            <div align=right><span class=textbox-urls><a href="http://blogger.org.cn/blog/User_blog.asp?Action=isbest&amp;ID=17619" target=_blank><u><font color=#0000ff></font></u></a></span>&nbsp;</div>
            </td>
        </tr>
    </tbody>
</table>
<table height=14 cellSpacing=0 cellPadding=0 width="100%" align=center border=0>
    <tbody>
        <tr>
            <td>&nbsp;</td>
        </tr>
    </tbody>
</table>
<style type=text/css>
.style3 {color: #006699}
</style>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td>
            <table cellSpacing=0 cellPadding=0 width="100%" align=center border=0>
                <tbody>
                    <tr>
                        <td><span class=oblog_text>
                        <div class=postTitle><a id=viewpost1_TitleUrl href="http://www.blogjava.net/zhaijianhui/archive/2006/07/15/58363.html"><u><font color=#0000ff>java利用反射得到实例，和代理类proxy</font></u></a> </div>
                        <div class=postText>
                        <p>对于面向接口编程的项目免不了要一反射相接触，动态得到实例:<br>public interface a {<br>&nbsp;public void sayHello();<br>}<br>---------------------------<br>第一种情况是当<br>aImpl实现类为默认的构造方法：<br>根据类名aImpl动态得到实例<br>Class c=Class.forName("aImpl");<br>a instance=(a)c.newInstance();<br>a.sayHello();<br>－－－－－－－－－－－－<br>第二种情况当<br>aImpl为带参数的构造方法时：<br>Class o=Class.forName("aImpl");//aImpl为要实例化的例名，可以从配置文件当中获取<br>&nbsp;&nbsp;&nbsp;Constructor cous = null;<br>&nbsp;&nbsp;&nbsp;cous=o.getConstructor(new Class[]{String.class});//构造器的参数类型<br>&nbsp;&nbsp;&nbsp;a ao=(a) cous.newInstance(new Object[]{"xxx"});//"xxx为传入的参数值<br>&nbsp;&nbsp;&nbsp;ao.sayHello();<br>第三种就是构造器为私有的时候，我们通过方法获取实例getInstance()(自己定的)<br>Class o=Class.forName("aImpl");<br>&nbsp;&nbsp;&nbsp;Method method=o.getMethod("getInstance",new Class[]{String.class});<br>//getInstance为返回为aImpl实例的方法名<br>&nbsp;&nbsp;&nbsp; a ao=(a) method.invoke(null,new Object[]{"xxx"});//注意了前面的参数为null，是有<br>//条件的,就是要求getInstance为static类型的，我想大家都会这样设计的<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ao.sayHello();<br>做连接池的话，一种方式就是使用动态代理类，当Connection调用close()方法时，我们可以利用方法拦截器，在调用close方法的时候把连接放到缓存里面去,供以后再次利用．．<br>a ao=(a)Proxy.newProxyInstance(aImpl.class.getClassLoader(),aImpl.class.getInterfaces(),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new InvocationHandler()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
                        <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object re=null;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("before--------"+method.getName());<br>//在这里我们添加自己的一些处理方法，如把连接放到缓存去撒!<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//re=method.invoke(new aImpl(),args);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return re;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br>&nbsp;&nbsp;&nbsp;ao.sayHello();</p>
                        </div>
                        </span></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/107957.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2007-04-02 14:06 <a href="http://www.blogjava.net/zhangzhong1018/articles/107957.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>依赖－－关联</title><link>http://www.blogjava.net/zhangzhong1018/articles/107955.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Mon, 02 Apr 2007 06:03:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/107955.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/107955.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/107955.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/107955.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/107955.html</trackback:ping><description><![CDATA[<span>&nbsp;
<p align=left><span>依赖是比关联弱的关系，关联代表一种结构化的关系，体现在生成的代码中，以</span><span>java</span><span>为例：</span><span> &nbsp; <br>&nbsp; </span><span>若类</span><span>A</span><span>单向关联指向类</span><span>B</span><span>，则在类</span><span>A</span><span>中存在一个属性</span><span>B &nbsp; b</span><span>。</span><span> &nbsp; <br>&nbsp; </span><span>若类</span><span>A</span><span>依赖类</span><span>B</span><span>，则不会有这个属性，类</span><span>B</span><span>的实例可能存在于某个方法调用的参数中，或某个方法的局部变量中。</span></p>
<p align=left><span>关联会对关系的类增加属性</span><span> &nbsp; <br>&nbsp; </span><span>依赖则并不对关系的类增加属性</span>&nbsp;</p>
<p align=left><span>从业务角度来讲：关联表示的是</span><span>&#8220;</span><span>拥有</span><span>&#8221;</span><span>关系（根据拥有的程度又可分为一般关联，聚合，合成），依赖表示的是</span><span>&#8220;</span><span>涉及</span><span>&#8221;</span><span>关系。如汽车跟轮子，车身的关系是关联，但跟汽油、公路的关系就是依赖。</span><span> &nbsp; <br>&nbsp;</span><strong></strong></p>
<p align=left><span>关联关系就是两个类谁都知道谁，可以相互通信，也就是说只要存在相互通信的连接，就是关联。关联关系分为</span><span><font face="Times New Roman">7</font></span><span>类：普通、递归、限定、或、有序、三元、聚合关联。如人类和计算机类，</span><span><font face="Times New Roman">&#8220;</font></span><span>使用</span><span><font face="Times New Roman">&#8221;</font></span><span>就是他们的关联。</span><span><font face="Times New Roman"> &nbsp; <br>&nbsp; </font></span><span>依赖：类</span><span><font face="Times New Roman">A</font></span><span>是独立的，若类</span><span><font face="Times New Roman">A</font></span><span>的改变将导致类</span><span><font face="Times New Roman">B</font></span><span>的改变，则说明类</span><span><font face="Times New Roman">B</font></span><span>依赖于类</span><span><font face="Times New Roman">A</font></span><span>，他们是依赖关系。</span></p>
<div>
<p align=left><span>在建立对象模型时，很容易把依赖、关联和聚集关系混淆。当对象</span><span><font face="Times New Roman">A</font></span><span>和对象</span><span><font face="Times New Roman">B</font></span><span>之间存在依赖、关联或聚集关系时，对象</span><span><font face="Times New Roman">A</font></span><span>都有可能调用对象</span><span><font face="Times New Roman">B</font></span><span>的方法，这是三种关系之间的相同之处，除此之外，它们有着不同的特征。</span></p>
<p align=left><span><font face="Times New Roman">1</font></span><span>．依赖关系的特征</span></p>
<p align=left><span><br></span><span>对于两个相对独立的系统，当一个系统负责构造另一个系统的实例，或者依赖另一个系统的服务时，这两个系统之间主要体现为依赖关系，例如生产零件的机器和零件，机器负责构造零件对象。再例如充电电池和充电器，充电电池通过充电器来充电。再例如自行车</span><span><font face="Times New Roman">Bicycle</font></span><span>和打气筒</span><span><font face="Times New Roman">Pump</font></span><span>，自行车通过打气筒来充气。图</span><span><font face="Times New Roman">1-39</font></span><span>为</span><span><font face="Times New Roman">Bicycle</font></span><span>类与</span><span><font face="Times New Roman">Pump</font></span><span>类的类框图。</span><span><font face="Times New Roman"> </font></span></p>
<p align=left><span><a href="file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/01/clip_image001.gif" target=_blank></a><font face="Times New Roman"></font><br><br></span><span>图</span><span><font face="Times New Roman">1-39 Bicycle</font></span><span>类与</span><span><font face="Times New Roman">Pump</font></span><span>类的依赖关系</span></p>
<p align=left><span><font face="Times New Roman">Bicycle</font></span><span>类和</span><span><font face="Times New Roman">Pump</font></span><span>类之间是依赖关系，在</span><span><font face="Times New Roman">Bicycle</font></span><span>类中无需定义</span><span><font face="Times New Roman">Pump</font></span><span>类型的变量。</span><span><font face="Times New Roman">Bicycle</font></span><span>类的定义如下：</span></p>
<p align=left><span><font face="Times New Roman">public class Bicycle{<br>/** </font></span><span>给轮胎充气</span><span><font face="Times New Roman"> */<br>public void expand(Pump pump){<br>pump.blow();<br>}<br>}</font></span></p>
<p align=left><span><br></span><span>在现时生活中，通常不会为某一辆自行车配备专门的打气筒，而是在需要充气的时候，从附近某个修车棚里借个打气筒打气。在程序代码中，表现为</span><span><font face="Times New Roman">Bicycle</font></span><span>类的</span><span><font face="Times New Roman">expand()</font></span><span>方法有个</span><span><font face="Times New Roman">Pump</font></span><span>类型的参数。以下程序代码表示某辆自行车先后到两个修车棚里充气：</span></p>
<p align=left><span><font face="Times New Roman">myBicycle.expand(pumpFromRepairShed1); //</font></span><span>到第一个修车棚里充气</span><span><br><font face="Times New Roman">myBicycle.expand(pumpFromRepairShed2); //</font></span><span>若干天后，到第二个修车棚里充气</span></p>
<p align=left><span><font face="Times New Roman">2</font></span><span>．关联关系的特征</span><span><br></span><span>对于两个相对独立的系统，当一个系统的实例与另一个系统的一些特定实例存在固定的对应关系时，这两个系统之间为关联关系。例如客户和订单，每个订单对应特定的客户，每个客户对应一些特定的订单；再例如公司和员工，每个公司对应一些特定的员工，每个员工对应一特定的公司；再例如自行车和主人，每辆自行车属于特定的主人，每个主人有特定的自行车，图</span><span><font face="Times New Roman">1-40</font></span><span>显示了主人和自行车的关联关系。而充电电池和充电器之间就不存在固定的对应关系，同样自行车和打气筒之间也不存在固定的对应关系。</span><span><br><br><a href="file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/01/clip_image002.gif" target=_blank></a></span></p>
<p align=left><span>图</span><span><font face="Times New Roman">1-40 </font></span><span>主人和自行车的关联关系</span></p>
<p align=left><span><br><font face="Times New Roman">Person</font></span><span>类与</span><span><font face="Times New Roman">Bicycle</font></span><span>类之间存在关联关系，这意味着在</span><span><font face="Times New Roman">Person</font></span><span>类中需要定义一个</span><span><font face="Times New Roman">Bicycle</font></span><span>类型的成员变量。以下是</span><span><font face="Times New Roman">Person</font></span><span>类的定义：</span></p>
<p align=left><span><font face="Times New Roman">public class Person{<br>private Bicycle bicycle; //</font></span><span>主人的自行车</span><span><br><br><font face="Times New Roman">public Bicycle getBicycle(){<br>return bicycle;<br>}<br>public void setBicycle(Bicycle bicycle){<br>this.bicycle=bicycle;<br>}<br>/** </font></span><span>骑自行车去上班</span><span><font face="Times New Roman"> */<br>public void goToWork(){<br>bicycle.run();<br>}<br>}</font></span></p>
<p align=left><span><br></span><span>在现时生活中，当你骑自行车去上班时，只要从家里推出自己的自行车就能上路了，不象给自行车打气那样，在需要打气时，还要四处去找修车棚。因此，在</span><span><font face="Times New Roman">Person</font></span><span>类的</span><span><font face="Times New Roman">goToWork()</font></span><span>方法中，调用自身的</span><span><font face="Times New Roman">bicycle</font></span><span>对象的</span><span><font face="Times New Roman">run()</font></span><span>方法。假如</span><span><font face="Times New Roman">goToWork()</font></span><span>方法采用以下的定义方式：</span></p>
<p align=left><span><font face="Times New Roman">/** </font></span><span>骑自行车去上班</span><span><font face="Times New Roman"> */<br>public void goToWork(Bicycle bicycle){<br>bicycle.run();<br>}</font></span></p>
</div>
<p><span>那就好比去上班前，还要先四处去借一辆自行车，然后才能去上班。</span></p>
</span>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/107955.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2007-04-02 14:03 <a href="http://www.blogjava.net/zhangzhong1018/articles/107955.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设计模式 （java）</title><link>http://www.blogjava.net/zhangzhong1018/articles/107951.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Mon, 02 Apr 2007 05:57:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/107951.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/107951.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/107951.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/107951.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/107951.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;Christopher Alexander 说过：&#8220;每一个模式描述了一个在我们周围不断重复发生的问题，以及该问题的解决方案的核心。这样，你就能一次又一次地使用该方案而不必做重复劳动&#8221;。模式描述为：在一定环境中解决某一问题的方案，包括三个基本元素--问题，解决方案和环境。阅读类图和对象图请先学习UML创建模式 结构模式 行为模式创建模式：对类的...&nbsp;&nbsp;<a href='http://www.blogjava.net/zhangzhong1018/articles/107951.html'>阅读全文</a><img src ="http://www.blogjava.net/zhangzhong1018/aggbug/107951.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2007-04-02 13:57 <a href="http://www.blogjava.net/zhangzhong1018/articles/107951.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>eclipse</title><link>http://www.blogjava.net/zhangzhong1018/articles/97017.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Wed, 31 Jan 2007 09:11:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/97017.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/97017.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/97017.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/97017.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/97017.html</trackback:ping><description><![CDATA[
		<strong>相关JAR包：<br /><br />spring-framework-1.1.5</strong> ：http://voxel.dl.sourceforge.net/sourceforge/springframework/spring-framework-1.1.5.p<br /><strong>spring-framework-1.1.5-with-dependencies</strong> ： http://nchc.dl.sourceforge.net/sourceforge/springframework/spring-framework-1.1.5-with-dependencies.p<br /><p><strong>相关JAR包：<br /><br />spring-framework-1.1.5</strong> ：http://voxel.dl.sourceforge.net/sourceforge/springframework/spring-framework-1.1.5.p<br /><strong>spring-framework-1.1.5-with-dependencies</strong> ： http://nchc.dl.sourceforge.net/sourceforge/springframework/spring-framework-1.1.5-with-dependencies.p<br /><strong>hibernate-2.1.8</strong> ：http://voxel.dl.sourceforge.net/sourceforge/hibernate/hibernate-2.1.8.p<br /><strong>hibernate-extensions-2.1.3</strong> ：http://nchc.dl.sourceforge.net/sourceforge/hibernate/hibernate-extensions-2.1.3.p<br /><strong>struts-menu-2.3</strong> ：http://optusnet.dl.sourceforge.net/sourceforge/struts-menu/struts-menu-2.3.p<br /><strong>struts-menu.war</strong> ：http://jaist.dl.sourceforge.net/sourceforge/struts-menu/struts-menu.war<br /><strong>Appfuse </strong>：http://appfuse.dev.java.net<br /><br /><br /><strong>eclipse和相关开发插件及插件更新地址：</strong><br /><br /><strong>eclipse download</strong> ： http://eclipse.cis.sinica.edu.tw/downloads/drops/R-3.0.1-200409161125/eclipse-SDK-3.0.1-win32.p<br /><strong>eclipse 3.0.X多国语言包</strong> ：http://download.eclipse.org/eclipse/downloads/drops/L-3.0.1_Translations-200409161125/NLpack-eclipse-SDK-3.0.x-win32.p<br /><strong>lomboz.301</strong> ： http://download.us.forge.objectweb.org/lomboz/lomboz.301.p<br /><strong>emf-sdo-runtime-2.0.0</strong> ： http://download.us.forge.objectweb.org/lomboz/emf-sdo-runtime-2.0.0.p<br /><strong>lomboz_3.0.1.N20050106</strong> ： http://download.us.forge.objectweb.org/lomboz/org.objectweb.lomboz_3.0.1.N20050106.p<br /><span><strong><span align="justify">Easy Strut 0.6.4 for Eclipse : </span></strong></span>http://easystruts.sourceforge.net/index.html#plugin<br /><br /><br /><strong>插件更新地址：<br /><br />Spring plugin</strong> ：http://springframework.sourceforge.net/spring-ide/eclipse/updatesite/<br /><strong>hibernate plugin</strong> ：http://www.binamics.com/hibernatesync<br /><strong>代码折叠</strong><strong> plugin</strong>：http://www.coffee-bytes.com/eclipse/update-site/site.xml<br /><strong>visual editor plugin 1.0</strong>：http://update.eclipse.org/tools/ve/updates/1.0<br /><strong>EMF/SDO/XSD Secondary </strong><strong>plugin</strong> ：http://download.eclipse.org/tools/emf/updates/site.xml<br /><strong>UML 2.0 plugin</strong> ：http://download.eclipse.org/tools/uml2/updates/site.xml<br /><strong>C# plugin</strong> ：http://www.improve-technologies.com/alpha/updates/site.xml<br /><br /><br /><br />不断更新中......<br /><br /><strong>网上收集的--&gt;&gt;<br /><br /></strong><span style="FONT-FAMILY: arial">sourceforge <a href="http://www.sourceforge.net/"><span style="COLOR: navy">http://www.sourceforge.net</span></a></span></p><p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align="left"><span style="FONT-FAMILY: arial">java.net <a href="http://www.java.net/"><span style="COLOR: navy">http://www.java.net</span></a></span></p><p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align="left"><span style="FONT-FAMILY: arial"><a href="http://www.eclipse.org/"><span style="COLOR: navy">www.eclipse.org</span></a></span></p><p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align="left"><span style="FONT-FAMILY: arial"><a href="http://www.opensource.org/"><span style="COLOR: navy">www.opensource.org</span></a></span></p><p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align="left"><span style="FONT-FAMILY: arial">Lomboz <a href="http://www.objectlearn.com/index.jsp"><span style="COLOR: navy">http://www.objectlearn.com/index.jsp</span></a> (J2EE plugin for Eclipse)<br />htmlArea <a href="http://sourceforge.net/projects/itools-htmlarea/"><span style="COLOR: navy">http://sourceforge.net/projects/itools-htmlarea/</span></a> (</span><span style="FONT-FAMILY: 宋体">所见即所得的在线</span><span style="FONT-FAMILY: arial">HTML</span><span style="FONT-FAMILY: 宋体">编辑器</span><span style="FONT-FAMILY: arial">)<br />XmlBuddy <a href="http://www.xmlbuddy.com/"><span style="COLOR: navy">http://www.xmlbuddy.com/</span></a> (XML Editor plugin for Eclipse)<br />JFreeChart <a href="http://www.jfree.org/"><span style="COLOR: navy">http://www.jfree.org/</span></a> (</span><span style="FONT-FAMILY: 宋体">用于生成图表的项目</span><span style="FONT-FAMILY: arial">)<br />EclipseME <a href="http://eclipseme.sourceforge.net/"><span style="COLOR: navy">http://eclipseme.sourceforge.net/</span></a> (J2ME Developmnt Plugin for Eclipse)<br />mvnForum <a href="http://sourceforge.net/projects/mvnforum/"><span style="COLOR: navy">http://sourceforge.net/projects/mvnforum/</span></a> (</span><span style="FONT-FAMILY: 宋体">论坛</span><span style="FONT-FAMILY: arial">)<br />jChatBox <a href="http://www.javazoom.net/index.shtml"><span style="COLOR: navy">http://www.javazoom.net/index.shtml</span></a> (</span><span style="FONT-FAMILY: 宋体">用</span><span style="FONT-FAMILY: arial">servlet</span><span style="FONT-FAMILY: 宋体">实现的</span><span style="FONT-FAMILY: arial">WEB</span><span style="FONT-FAMILY: 宋体">聊天引擎</span><span style="FONT-FAMILY: arial">)<br />POI <a href="http://jakarta.apache.org/poi/index.html"><span style="COLOR: navy">http://jakarta.apache.org/poi/index.html</span></a> (</span><span style="FONT-FAMILY: 宋体">用于处理</span><span style="FONT-FAMILY: arial">Excel,WORD</span><span style="FONT-FAMILY: 宋体">等文档的项目</span><span style="FONT-FAMILY: arial">)<br />FileUpload <a href="http://jakarta.apache.org/commons/fileupload/"><span style="COLOR: navy">http://jakarta.apache.org/commons/fileupload/</span></a> (</span><span style="FONT-FAMILY: 宋体">用于处理</span><span style="FONT-FAMILY: arial">HTTP</span><span style="FONT-FAMILY: 宋体">文件上传得项目</span><span style="FONT-FAMILY: arial">)<br />PDFBox <a href="http://sourceforge.net/projects/pdfbox/"><span style="COLOR: navy">http://sourceforge.net/projects/pdfbox/</span></a> (</span><span style="FONT-FAMILY: 宋体">处理</span><span style="FONT-FAMILY: arial">PDF</span><span style="FONT-FAMILY: 宋体">文档的项目</span><span style="FONT-FAMILY: arial">)<br />Lucene <a href="http://jakarta.apache.org/lucene/index.html"><span style="COLOR: navy">http://jakarta.apache.org/lucene/index.html</span></a> (</span><span style="FONT-FAMILY: 宋体">搜索引擎</span><span style="FONT-FAMILY: arial">)<br />Digester <a href="http://jakarta.apache.org/commons/digester/"><span style="COLOR: navy">http://jakarta.apache.org/commons/digester/</span></a> (</span><span style="FONT-FAMILY: 宋体">处理</span><span style="FONT-FAMILY: arial">XML</span><span style="FONT-FAMILY: 宋体">信息的项目</span><span style="FONT-FAMILY: arial">)<br />DBCP <a href="http://jakarta.apache.org/commons/dbcp/"><span style="COLOR: navy">http://jakarta.apache.org/commons/dbcp/</span></a> (</span><span style="FONT-FAMILY: 宋体">数据库连接池</span><span style="FONT-FAMILY: arial">)<br />AXIS <a href="http://ws.apache.org/axis/"><span style="COLOR: navy">http://ws.apache.org/axis/</span></a> (WebService </span><span style="FONT-FAMILY: 宋体">的实现框架</span><span style="FONT-FAMILY: arial">)<br />Jetspeed <a href="http://portals.apache.org/jetspeed-1/"><span style="COLOR: navy">http://portals.apache.org/jetspeed-1/</span></a> (Portal)<br />HSQLDB <a href="http://sourceforge.net/projects/hsqldb/"><span style="COLOR: navy">http://sourceforge.net/projects/hsqldb/</span></a> (Im memory Database Engine)<br />CEWOLF <a href="http://sourceforge.net/projects/cewolf/"><span style="COLOR: navy">http://sourceforge.net/projects/cewolf/</span></a> (</span><span style="FONT-FAMILY: 宋体">一套标签库实现</span><span style="FONT-FAMILY: arial">Web</span><span style="FONT-FAMILY: 宋体">报表</span><span style="FONT-FAMILY: arial">,</span><span style="FONT-FAMILY: 宋体">使用的是</span><span style="FONT-FAMILY: arial">jFreeChart</span><span style="FONT-FAMILY: 宋体">引擎</span><span style="FONT-FAMILY: arial">)<br />Struts Menu <a href="http://sourceforge.net/projects/struts-menu/"><span style="COLOR: navy">http://sourceforge.net/projects/struts-menu/</span></a> (</span><span style="FONT-FAMILY: 宋体">基于</span><span style="FONT-FAMILY: arial">Struts</span><span style="FONT-FAMILY: 宋体">的</span><span style="FONT-FAMILY: arial">Web</span><span style="FONT-FAMILY: 宋体">菜单项目</span><span style="FONT-FAMILY: arial">)<br />htmlparser <a href="http://sourceforge.net/projects/htmlparser/"><span style="COLOR: navy">http://sourceforge.net/projects/htmlparser/</span></a> (</span><span style="FONT-FAMILY: 宋体">用于解析</span><span style="FONT-FAMILY: arial">HTML</span><span style="FONT-FAMILY: 宋体">信息的项目</span><span style="FONT-FAMILY: arial">)<br />Mondrian <span style="COLOR: navy"><a href="http://sourceforge.net/projects/mondrian/%28Open">http://sourceforge.net/projects/mondrian/</a></span>(Open Source OLAP Database)<br />ProGuard <span style="COLOR: navy"><a href="http://sourceforge.net/projects/proguard/%28Java">http://sourceforge.net/projects/proguard/</a></span>(Java</span><span style="FONT-FAMILY: 宋体">的混淆器</span><span style="FONT-FAMILY: arial">)<br />InfoGlue <a href="http://sourceforge.net/projects/infoglue/"><span style="COLOR: navy">http://sourceforge.net/projects/infoglue/</span></a> (J2EE </span><span style="FONT-FAMILY: 宋体">内容管理系统</span><span style="FONT-FAMILY: arial">)<br />JPivot <a href="http://sourceforge.net/projects/jpivot/"><span style="COLOR: navy">http://sourceforge.net/projects/jpivot/</span></a> (</span><span style="FONT-FAMILY: 宋体">基于</span><span style="FONT-FAMILY: arial">WEB</span><span style="FONT-FAMILY: 宋体">的</span><span style="FONT-FAMILY: arial">OLAP </span><span style="FONT-FAMILY: 宋体">展现</span><span style="FONT-FAMILY: arial">)<br /><a href="http://java-source.net/"><span style="COLOR: navy">http://java-source.net/</span></a></span></p><p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align="left"><span style="FONT-FAMILY: arial">(5)</span><span style="FONT-FAMILY: 宋体">几个常用</span><span style="FONT-FAMILY: arial">JAVA</span><span style="FONT-FAMILY: 宋体">开源项目的地址荟萃</span><span style="FONT-FAMILY: arial">:<br />Lomboz <a href="http://www.objectlearn.com/index.jsp">http://www.objectlearn.com/index.jsp</a> (J2EE plugin for Eclipse)<br />htmlArea <a href="http://sourceforge.net/projects/itools-htmlarea/">http://sourceforge.net/projects/itools-htmlarea/</a> (</span><span style="FONT-FAMILY: 宋体">所见即所得的在线</span><span style="FONT-FAMILY: arial">HTML</span></p><p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align="left"><span style="FONT-FAMILY: 宋体">编辑器</span><span style="FONT-FAMILY: arial">)<br />XmlBuddy <a href="http://www.xmlbuddy.com/">http://www.xmlbuddy.com/</a> (XML Editor plugin for Eclipse)<br />JFreeChart <a href="http://www.jfree.org/">http://www.jfree.org/</a> (</span><span style="FONT-FAMILY: 宋体">用于生成图表的项目</span><span style="FONT-FAMILY: arial">)<br />EclipseME <a href="http://eclipseme.sourceforge.net/">http://eclipseme.sourceforge.net/</a> (J2ME Developmnt Plugin for Eclipse)<br />mvnForum <a href="http://sourceforge.net/projects/mvnforum/">http://sourceforge.net/projects/mvnforum/</a> (</span><span style="FONT-FAMILY: 宋体">论坛</span><span style="FONT-FAMILY: arial">)<br />jChatBox <a href="http://www.javazoom.net/index.shtml">http://www.javazoom.net/index.shtml</a> (</span><span style="FONT-FAMILY: 宋体">用</span><span style="FONT-FAMILY: arial">servlet</span><span style="FONT-FAMILY: 宋体">实现的</span><span style="FONT-FAMILY: arial">WEB</span><span style="FONT-FAMILY: 宋体">聊天引擎</span><span style="FONT-FAMILY: arial">)<br />POI <a href="http://jakarta.apache.org/poi/index.html">http://jakarta.apache.org/poi/index.html</a> (</span><span style="FONT-FAMILY: 宋体">用于处理</span><span style="FONT-FAMILY: arial">Excel,WORD</span><span style="FONT-FAMILY: 宋体">等文档</span></p><p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align="left"><span style="FONT-FAMILY: 宋体">的项目</span><span style="FONT-FAMILY: arial">)<br />FileUpload <a href="http://jakarta.apache.org/commons/fileupload/">http://jakarta.apache.org/commons/fileupload/</a> (</span><span style="FONT-FAMILY: 宋体">用于处理</span><span style="FONT-FAMILY: arial">HTTP</span><span style="FONT-FAMILY: 宋体">文件上传得项</span></p><p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align="left"><span style="FONT-FAMILY: 宋体">目</span><span style="FONT-FAMILY: arial">)<br />PDFBox <a href="http://sourceforge.net/projects/pdfbox/">http://sourceforge.net/projects/pdfbox/</a> (</span><span style="FONT-FAMILY: 宋体">处理</span><span style="FONT-FAMILY: arial">PDF</span><span style="FONT-FAMILY: 宋体">文档的项目</span><span style="FONT-FAMILY: arial">)<br />Lucene <a href="http://jakarta.apache.org/lucene/index.html">http://jakarta.apache.org/lucene/index.html</a> (</span><span style="FONT-FAMILY: 宋体">搜索引擎</span><span style="FONT-FAMILY: arial">)<br />Digester <a href="http://jakarta.apache.org/commons/digester/">http://jakarta.apache.org/commons/digester/</a> (</span><span style="FONT-FAMILY: 宋体">处理</span><span style="FONT-FAMILY: arial">XML</span><span style="FONT-FAMILY: 宋体">信息的项目</span><span style="FONT-FAMILY: arial">)<br />DBCP <a href="http://jakarta.apache.org/commons/dbcp/">http://jakarta.apache.org/commons/dbcp/</a> (</span><span style="FONT-FAMILY: 宋体">数据库连接池</span><span style="FONT-FAMILY: arial">)<br />AXIS <a href="http://ws.apache.org/axis/">http://ws.apache.org/axis/</a> (WebService </span><span style="FONT-FAMILY: 宋体">的实现框架</span><span style="FONT-FAMILY: arial">)<br />Jetspeed <a href="http://portals.apache.org/jetspeed-1/">http://portals.apache.org/jetspeed-1/</a> (Portal)<br />HSQLDB <a href="http://sourceforge.net/projects/hsqldb/">http://sourceforge.net/projects/hsqldb/</a> (Im memory Database Engine)<br />CEWOLF <a href="http://sourceforge.net/projects/cewolf/">http://sourceforge.net/projects/cewolf/</a></span></p><p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align="left"><span style="FONT-FAMILY: arial">(</span><span style="FONT-FAMILY: 宋体">一套标签库实现</span><span style="FONT-FAMILY: arial">Web</span><span style="FONT-FAMILY: 宋体">报表</span><span style="FONT-FAMILY: arial">,</span><span style="FONT-FAMILY: 宋体">使用的是</span><span style="FONT-FAMILY: arial">jFreeChart</span><span style="FONT-FAMILY: 宋体">引擎</span><span style="FONT-FAMILY: arial">)<br />Struts Menu <a href="http://sourceforge.net/projects/struts-menu/">http://sourceforge.net/projects/struts-menu/</a> (</span><span style="FONT-FAMILY: 宋体">基于</span><span style="FONT-FAMILY: arial">Struts</span><span style="FONT-FAMILY: 宋体">的</span><span style="FONT-FAMILY: arial">Web</span><span style="FONT-FAMILY: 宋体">菜单项目</span></p><p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align="left"><span style="FONT-FAMILY: arial">)<br />htmlparser <a href="http://sourceforge.net/projects/htmlparser/">http://sourceforge.net/projects/htmlparser/</a> (</span><span style="FONT-FAMILY: 宋体">用于解析</span><span style="FONT-FAMILY: arial">HTML</span><span style="FONT-FAMILY: 宋体">信息的项目</span></p><p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align="left"><span style="FONT-FAMILY: arial">)<br />Mondrian <a href="http://sourceforge.net/projects/mondrian/">http://sourceforge.net/projects/mondrian/</a> (Open Source OLAP </span></p><p style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align="left"><span style="FONT-FAMILY: arial">Database)<br />ProGuard <a href="http://sourceforge.net/projects/proguard/">http://sourceforge.net/projects/proguard/</a> (Java</span><span style="FONT-FAMILY: 宋体">的混淆器</span><span style="FONT-FAMILY: arial">)<br />InfoGlue <a href="http://sourceforge.net/projects/infoglue/">http://sourceforge.net/projects/infoglue/</a> (J2EE </span><span style="FONT-FAMILY: 宋体">内容管理系统</span><span style="FONT-FAMILY: arial">)<br />JPivot <a href="http://sourceforge.net/projects/jpivot/">http://sourceforge.net/projects/jpivot/</a> (</span><span style="FONT-FAMILY: 宋体">基于</span><span style="FONT-FAMILY: arial">WEB</span><span style="FONT-FAMILY: 宋体">的</span><span style="FONT-FAMILY: arial">OLAP </span><span style="FONT-FAMILY: 宋体">展现</span><span style="FONT-FAMILY: arial">)<br />HttpClient <a href="http://jakarta.apache.org/commons/httpclient/">http://jakarta.apache.org/commons/httpclient/</a></span><span style="FONT-FAMILY: 宋体">处理</span><span style="FONT-FAMILY: arial">http</span><span style="FONT-FAMILY: 宋体">客户端的接口<br /></span></p><p><font size="4"> </font><span class="javascript" id="text136548"><a class="ilink" href="http://www.tusc.com.au/tutorial/html/index.html" target="_blank"><font size="4">http://www.tusc.com.au/tutorial/html/index.html</font></a><br /><font size="4">利用Eclipse,LOMBOZ plugins,JBoss开发J2EE教学的文章（En）很精彩<br />1.? lomboz.301.zip 与emf-sdo-runtime-2.0.0.zip(著名的开发J2ee的插件)<br /><br />下载网址：http://forge.objectweb.org/project/showfiles.php?group_id=97? 　<br /><br /></font><a class="ilink" href="http://www.objectlearn.com/" target="_blank"><font size="4">http://www.objectlearn.com/</font></a><font size="4"><br /><br />Lomboz 可以做很多事情，是使用 Eclipse+JBoss 做 J2EE 的首选。 <br /><br />2.MyEclipse,最好的J2EE开发框架<br /><br />下载Myeclipse userId: ylfly? password: *******<br /></font><a class="ilink" href="http://www.myeclipseide.com/ContentExpress-display-ceid-47.html" target="_blank"><font size="4">http://www.myeclipseide.com/ContentExpress-display-ceid-47.html</font></a><br /><font size="4">MyEclipse的注册码：<br />for eclispe3.0版的：<br />IceCraft<br />VAR7ZL-819-56-54678656108018950<br />for eclispe2.1版的：<br />IceCraft<br />VAR7ZL-719-56-54678657538454123<br /><br />3.Log4j或者Apache commons Logger最得力的助手就是 Log4e： <br />??? 官方网站：http://log4e.jayefem.de/<br />??? 下载连接：http://log4e.jayefem.de/download/de.jayefem.log4e_0.5.5.zip<br /><br />4. Easy Struts支持Struts的插件 (0.64版只支持Eclipse2.X)<br />是开放源代码组织sourceforge.net上的一个项目，目前最新的版本是0.64， <br /><br /></font><a class="ilink" href="http://sourceforge.net/project/showfiles.php%C3%AF%C2%BC%C5%B8group_id=54542&amp;package_id=49230" target="_blank"><font size="4">http://sourceforge.net/project/showfiles.php？group_id=54542&amp;package_id=49230</font></a><font size="4"><br /><br /></font><a class="ilink" href="http://easystruts.sourceforge.net/" target="_blank"><font size="4">http://easystruts.sourceforge.net/</font></a><font size="4"><br /><br />5. TomcatPlugin 支持Tomcat插件 <br /></font><a class="ilink" href="http://www.sysdeo.com/eclipse/tomcatPlugin.html" target="_blank"><font size="4">http://www.sysdeo.com/eclipse/tomcatPlugin.html</font></a><font size="4"><br /><br />6.Hibernate Synchronizer<br />Hibernate Synchronizer is a free Eclipse plugin code generation tool to be used with the Hibernate persistence framework. The plugin will automatically generate java code when your hibernate mapping files are modified. Objects are created with generated code in an abstract base class and a user-modifiable extension class so user code does not get deleted when the generation is performed. <br /></font><a class="ilink" href="http://www.binamics.com/hibernatesync/" target="_blank"><font size="4">http://www.binamics.com/hibernatesync/</font></a><br /><a class="ilink" href="https://sourceforge.net/project/showfiles.php?group_id=99370" target="_blank"><font size="4">https://sourceforge.net/project/showfiles.php?group_id=99370</font></a><br /><font size="4">HibernateSynchronizer-2.1.25-Eclipse3M6.zip?? 只支持到M7<br /><br />7. SWT Designer 使GUI更cool，更in，更happy!<br /></font><a class="ilink" href="http://www.swt-designer.com/??" target="_blank"><font size="4">http://www.swt-designer.com/??</font></a><font size="4"> 14天<br /><br />8. XML Editor &amp; XSLT Debugger 编辑XML的插件 <br /></font><a class="ilink" href="http://www.oxygenxml.com/" target="_blank"><font size="4">http://www.oxygenxml.com/</font></a><font size="4"><br /><br />8.1支持Eclipse 3.0 的XML插件<br /></font><a class="ilink" href="http://www.xmlbuddy.com/" target="_blank"><font size="4">http://www.xmlbuddy.com/</font></a><br /><br /><font size="4">8.2XML Viewer <br />Version: 1.1.7<br /></font><a class="ilink" href="http://tabaquismo.freehosting.net/ignacio/eclipse/xmlview/index.html" target="_blank"><font size="4">http://tabaquismo.freehosting.net/ignacio/eclipse/xmlview/index.html</font></a><br /><br /><font size="4">9.UML Tool for Eclipse <br /></font><a class="ilink" href="http://www.visual-paradigm.com/download.php?shortName=sdeec" target="_blank"><font size="4">http://www.visual-paradigm.com/download.php?shortName=sdeec</font></a><br /><br /><font size="4">9.1 UML插件 Omondo的(支持eclipse 3.0 的studio 1.0 只试用20天) <br /></font><a class="ilink" href="http://www.omondo.com/" target="_blank"><font size="4">http://www.omondo.com/</font></a><font size="4"><br />useId :ylfly password:*******<br /><br />9.2EclipseUML2? is Eclipse tools<br /><br /></font><a class="ilink" href="http://www.eclipse.org/uml2/" target="_blank"><font size="4">http://www.eclipse.org/uml2/</font></a><br /><br /><font size="4">10.Eclipse加速插件KeepResident <br /><br /></font><a class="ilink" href="http://suif.stanford.edu/pub/keepresident/" target="_blank"><font size="4">http://suif.stanford.edu/pub/keepresident/</font></a><br /><br /><font size="4">原理:利用两个 Windows API - SetProcessWorkingSetSize 与 VirtualLock (适用于 Windows 平台)。<br /><br />切换时果然快很多。<br /><br />官方建议最小值设定在 100 MB，最大值 250 MB 左右。<br /><br />11.RMI Plugin for Eclipse 1.6.0 for Eclipse 3.0<br /></font><a class="ilink" href="http://www.genady.net/rmi" target="_blank"><font size="4">http://www.genady.net/rmi</font></a><font size="4"><br /><br />12其它插件<br /><br />perl插件 </font><a class="ilink" href="http://e-p-i-c.sf.net/updates" target="_blank"><font size="4">http://e-p-i-c.sf.net/updates</font></a><br /><font size="4">C#插件? </font><a class="ilink" href="http://www.improve-technologies.com/alpha/updates/site.xml" target="_blank"><font size="4">http://www.improve-technologies.com/alpha/updates/site.xml</font></a><br /><font size="4">C插件??? </font><a class="ilink" href="http://update.eclipse.org/tools/cdt/releases/new" target="_blank"><font size="4">http://update.eclipse.org/tools/cdt/releases/new</font></a><br /><font size="4">Hex插件 </font><a class="ilink" href="http://ehep.sourceforge.net/update" target="_blank"><font size="4">http://ehep.sourceforge.net/update</font></a><br /><br /><font size="4">13.Eclipse插件使用links目录的用法：<br />　假设把插件安装在d:myplugin目录中，则myplugin的目录结构一定要是这样的：<br />　　d:myplugineclipseplugins插件 及 d:myplugineclipsefeatures插件<br />　　例如安装EclipseME插件到d:myplugin目录中，则目录结构<br /><br />d:myplugineclipsepluginseclipseme_0.4.5。<br />　　再假设eclipse安装在d:eclipse目录中，则在eclipse目录中创建名称为links的目录，在links目<br /><br />录中建立一个link文件，比如myplugin.link，该文件内容为path=d:myplugin。<br />　　启动eclipse，插件即安装上了，如果想暂时不启动插件，只需把myplugin.link文件删除即可。<br />补充说明：<br />　1. 插件可以分别安装在多个自定义的目录中。<br />　2. 一个自定义目录可以安装多个插件。<br />　3. link文件的文件名及扩展名可以取任意名称，比如myplugin.txt，goodplugin都可以。<br />　4. link文件可以有多行path=插件目录，对应多个自定义插件目录，每一行的path参数都将生效。<br />　5. 在links目录也可以有多个link文件，每个link文件中的path参数都将生效。<br />　6. 插件目录可以使用相对路径，如果我们把myplugin目录创建在eclipse安装目录中，如上例中的<br /><br />d:eclipse目录中，则只需设置path=myplugin即可。<br /><br />14.Eclipse tools<br /><br />1).ALL SDK bundle (includes Source, Runtime and Docs for EMF, XSD, and SDO). <br />?<br />2).The Graphical Editing Framework (GEF) allows developers to take an existing application <br /><br />model and quickly create a rich graphical editor.<br /><br />3).UML2 is an EMF-based implementation of the UML 2.0 metamodel for the Eclipse platform.<br /><br /></font><a class="ilink" href="http://www.eclipse.org/emf/" target="_blank"><font size="4">http://www.eclipse.org/emf/</font></a><br /><a class="ilink" href="http://www.eclipse.org/gef/" target="_blank"><font size="4">http://www.eclipse.org/gef/</font></a><br /><a class="ilink" href="http://www.eclipse.org/uml2/" target="_blank"><font size="4">http://www.eclipse.org/uml2/</font></a><br /><br /><font size="4">15.plug-in网址：<br /><br /></font><a class="ilink" href="http://www.eclipse-plugins.info/eclipse/index.jsp" target="_blank"><font size="4">http://www.eclipse-plugins.info/eclipse/index.jsp</font></a><br /><br /><a class="ilink" href="http://www.eclipse-workbench.com/jsp/" target="_blank"><font size="4">http://www.eclipse-workbench.com/jsp/</font></a><font size="4"><br /><br /></font><a class="ilink" href="http://eclipse-plugins.2y.net/eclipse/index.jsp" target="_blank"><font size="4">http://eclipse-plugins.2y.net/eclipse/index.jsp</font></a><font size="4"> （非常非常著名的插件更新网站） <br /><br /></font><a class="ilink" href="http://www.crionics.com/products/opensource/eclipse/eclipse.jsp" target="_blank"><font size="4">http://www.crionics.com/products/opensource/eclipse/eclipse.jsp</font></a><font size="4"> （分类清楚） <br /><br /></font><a class="ilink" href="http://www.eclipseplugincentral.com/" target="_blank"><font size="4">http://www.eclipseplugincentral.com/</font></a><br /><br /><font size="4">16.调试JSP时,在tomcat里改confserver.xml<br /><br />??????? docbase="C:eclipseworkspaceMyJ2EEProjectmyweb"<br /><br />????????? workDir="C:eclipseworkspaceMyJ2EEProjectj2src" /&gt;<br /><br />docBase="D:workspacemyJSP est"<br />path="/test" reloadable="true" workDir="D:workspacemyJSPj2src"/&gt;<br /><br /><br /><br />j2src不要改动<br /><br />17.CVS---并发版本系统(中文手册)v1.12.9<br /></font><a class="ilink" href="http://cvsdoc-zh.gro.clinux.org/cvsdoc/zh_CN/html/index.html" target="_blank"><font size="4">http://cvsdoc-zh.gro.clinux.org/cvsdoc/zh_CN/html/index.html</font></a><br /><a class="ilink" href="http://cvsdoc-zh.gro.clinux.org/" target="_blank"><font size="4">http://cvsdoc-zh.gro.clinux.org</font></a><br /><font size="4">另一个CVS手册：<br /></font><a class="ilink" href="http://www.chedong.com/tech/cvs_card.html" target="_blank"><font size="4">http://www.chedong.com/tech/cvs_card.html</font></a><br /><br /><font size="4">18.Preferences无法显示新安装的插件的解决办法<br /><br />删除C:eclipseconfigurationorg.eclipse.update下的platform.xml文件，重新启动Eclipse<br /><br />19.评价<br /><br />当前世界上最新最实用的IDE环境Eclipse。加上分析设计工具eclipseUML、MVC构架的Struts、<br /><br />对象数据绑定构架OJB，Web系统的自动单元测试工具JUnit和HttpUnit，还有最普及的数据库MySQL，最<br /><br />流行的版本管理服务器CVS，和支持Java/JSP/servlet的最佳Web引擎tomcat ,jboss。<br /><br />20.Eclipse的许可证是怎样的？<br />现在Eclipse相关的许可证是大多数基于Common Public License (CPL)，CPL是一个为Open Source <br /><br />Initiative (OSI)所认可的许可证。由于Eclipse Foundation的建立，Eclipse的许可证将逐渐趋向于使<br /><br />用Eclipse Public License (EPL)，EPL是一个与CPL相类似的许可证，正在进行OSI的认证工作。此外，<br /><br />Eclipse还涉及到多个开源项目和各类许可证，主要有 Apache Software License、IBM Public License<br /><br />、Metro Link Public License和Mozilla Public License。个人无需太关心许可证的问题，企业在使用<br /><br />Eclipse进行开发之前，最好请法律界人士研究一下。<br /><br />各许可证的网址是：<br /><br /></font><a class="ilink" href="http://www.eclipse.org/legal/cpl-v10.html%C3%A3%E2%82%AC?" target="_blank"><font size="4">http://www.eclipse.org/legal/cpl-v10.html、</font></a><br /><br /><a class="ilink" href="http://www.eclipse.org/legal/epl-v10.html%C3%A3%E2%82%AC?" target="_blank"><font size="4">http://www.eclipse.org/legal/epl-v10.html、</font></a><br /><br /><a class="ilink" href="http://www.apache.org/licenses/LICENSE%C3%A3%E2%82%AC?" target="_blank"><font size="4">http://www.apache.org/licenses/LICENSE、</font></a><br /><br /><a class="ilink" href="http://oss.software.ibm.com/developerworks/opensource/license10.html%C3%A3%E2%82%AC?" target="_blank"><font size="4">http://oss.software.ibm.com/developerworks/opensource/license10.html、</font></a><br /><br /><a class="ilink" href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html%C3%A3%E2%82%AC?" target="_blank"><font size="4">http://www.opengroup.org/openmotif/supporters/metrolink/license.html、</font></a><br /><br /><a class="ilink" href="http://www.mozilla.org/MPL/MPL-1.1." target="_blank"><font size="4">http://www.mozilla.org/MPL/MPL-1.1.</font></a><font size="4"></font></span><br /></p><p>eclipse你最常用的快捷键是什么?</p><p>ctrl  +  shift  +  g：查看引用  <br />ctrl  +  shift  +  n：重命名  <br />ctrl  +  shift  +  o：导入类  <br />ctrl  +  shift  +  r：启动上次运行  <br />ctrl  +  shift  +  f：格式化代码  <br />ctrl  +  c：复制  <br />ctrl  +  v：粘贴  <br />ctrl  +  x：切剪  <br />ctrl  +  a：全选  <br />ctrl  +  f：查找  <br />ctrl  +  z：撤销  <br />ctrl  +  y：重做  <br />ctrl  +  s：保存  <br />---------------------------------------------------------------  <br /> <br />用的最多的应该就是CTRL+SHIFT+S  <br />还有格式化用的也挺多。  <br />---------------------------------------------------------------  <br /> <br />ctrl  +  shift  +  f  格式化代码  <br />ctrl  +  shift  +  o  组织导入  <br />F3    打开声明  <br />Alt  +  shift  +  r    重命名变量  <br /> <br />---------------------------------------------------------------  <br /> <br />up  <br />---------------------------------------------------------------  <br /> <br />Alt+/        <br /> <br />---------------------------------------------------------------  <br /> <br />alt  +  left  <br />alt  +  right  <br />ctrl  +  q  <br />---------------------------------------------------------------  <br /> <br />ctrl  +  shift  +  g：查看引用  <br />ctrl  +  shift  +  n：重命名  <br />ctrl  +  shift  +  f：格式化代码  <br />ctrl  +  c：复制  <br />ctrl  +  v：粘贴  <br />ctrl  +  a：全选  <br />ctrl  +  f：查找  <br />ctrl  +  z：撤销  <br />ctrl  +  s：保存  <br />Alt    +  /  智能提示  <br />---------------------------------------------------------------  <br /> <br />ctrl  +  shift  +  g：查看引用  <br />ctrl  +  shift  +  n：重命名  <br />ctrl  +  shift  +  o：导入类  <br />ctrl  +  shift  +  r：启动上次运行  <br />ctrl  +  shift  +  f：格式化代码  <br />ctrl  +  c：复制  <br />ctrl  +  v：粘贴  <br />ctrl  +  x：切剪  <br />ctrl  +  a：全选  <br />ctrl  +  f：查找  <br />ctrl  +  z：撤销  <br />ctrl  +  y：重做  <br />ctrl  +  s：保存  <br />Alt    +  /  智能提示  <br />F3    打开声明  <br />Alt  +  shift  +  r    重命名变量  <br />其实最常用的就是下面几个：  <br /> <br />ctrl  +  shift  +  o：导入类  <br /> <br />ctrl  +  shift  +  f：格式化代码  <br />ctrl  +  c：复制  <br />ctrl  +  v：粘贴  <br />ctrl  +  x：切剪  <br />ctrl  +  z：撤销  <br />ctrl  +  s：保存  <br />Alt    +  /  智能提示  <br /> <br />---------------------------------------------------------------  <br /> <br />Ctrl+M:  工作区最大化/最小化  <br />Alt+/:    智能提示  <br />F3:          察看声明  <br />Crtl+1:  修正错误  <br /> <br />Shift+Alt+T:  重构  <br />Shift+Alt+M:  提取函数  <br />Shift+Alt+R:  重命名  <br />Shift+Alt+C:  更改函数标记  <br /> <br />Ctrl+Shitf+F:  格式化代码  <br /> <br />---------------------------------------------------------------  <br /> <br />ctrl  +  shift  +  o：导入类  <br />atl  +  /：提示  <br />ctrl  +  shift  +  t：查找相关信息  <br />---------------------------------------------------------------  <br /> <br />Eclipse快捷键指南                                                                          <br />编辑  <br />作用域            功能            快捷键  <br />全局            查找并替换            Ctrl+F  <br />文本编辑器            查找上一个            Ctrl+Shift+K  <br />文本编辑器            查找下一个            Ctrl+K  <br />全局            撤销            Ctrl+Z  <br />全局            复制            Ctrl+C  <br />全局            恢复上一个选择            Alt+Shift+↓  <br />全局            剪切            Ctrl+X  <br />全局            快速修正            Ctrl1+1  <br />全局            内容辅助            Alt+/  <br />全局            全部选中            Ctrl+A  <br />全局            删除            Delete  <br />全局            上下文信息            Alt+？  <br />Alt+Shift+?  <br />Ctrl+Shift+Space  <br />Java编辑器            显示工具提示描述            F2  <br />Java编辑器            选择封装元素            Alt+Shift+↑  <br />Java编辑器            选择上一个元素            Alt+Shift+←  <br />Java编辑器            选择下一个元素            Alt+Shift+→  <br />文本编辑器            增量查找            Ctrl+J  <br />文本编辑器            增量逆向查找            Ctrl+Shift+J  <br />全局            粘贴            Ctrl+V  <br />全局            重做            Ctrl+Y  <br />   <br />查看  <br />作用域            功能            快捷键  <br />全局            放大            Ctrl+=  <br />全局            缩小            Ctrl+-  <br />   <br />窗口  <br />作用域            功能            快捷键  <br />全局            激活编辑器            F12  <br />全局            切换编辑器            Ctrl+Shift+W  <br />全局            上一个编辑器            Ctrl+Shift+F6  <br />全局            上一个视图            Ctrl+Shift+F7  <br />全局            上一个透视图            Ctrl+Shift+F8  <br />全局            下一个编辑器            Ctrl+F6  <br />全局            下一个视图            Ctrl+F7  <br />全局            下一个透视图            Ctrl+F8  <br />文本编辑器            显示标尺上下文菜单            Ctrl+W  <br />全局            显示视图菜单            Ctrl+F10  <br />全局            显示系统菜单            Alt+-  <br />   <br />导航  <br />作用域            功能            快捷键  <br />Java编辑器            打开结构            Ctrl+F3  <br />全局            打开类型            Ctrl+Shift+T  <br />全局            打开类型层次结构            F4  <br />全局            打开声明            F3  <br />全局            打开外部javadoc            Shift+F2  <br />全局            打开资源            Ctrl+Shift+R  <br />全局            后退历史记录            Alt+←  <br />全局            前进历史记录            Alt+→  <br />全局            上一个            Ctrl+,  <br />全局            下一个            Ctrl+.  <br />Java编辑器            显示大纲            Ctrl+O  <br />全局            在层次结构中打开类型            Ctrl+Shift+H  <br />全局            转至匹配的括号            Ctrl+Shift+P  <br />全局            转至上一个编辑位置            Ctrl+Q  <br />Java编辑器            转至上一个成员            Ctrl+Shift+↑  <br />Java编辑器            转至下一个成员            Ctrl+Shift+↓  <br />文本编辑器            转至行            Ctrl+L  <br />   <br />搜索  <br />作用域            功能            快捷键  <br />全局            出现在文件中            Ctrl+Shift+U  <br />全局            打开搜索对话框            Ctrl+H  <br />全局            工作区中的声明            Ctrl+G  <br />全局            工作区中的引用            Ctrl+Shift+G  <br />   <br />文本编辑  <br />作用域            功能            快捷键  <br />文本编辑器            改写切换            Insert  <br />文本编辑器            上滚行            Ctrl+↑  <br />文本编辑器            下滚行            Ctrl+↓  <br />   <br />文件  <br />作用域            功能            快捷键  <br />全局            保存            Ctrl+X    <br />Ctrl+S  <br />全局            打印            Ctrl+P  <br />全局            关闭            Ctrl+F4  <br />全局            全部保存            Ctrl+Shift+S  <br />全局            全部关闭            Ctrl+Shift+F4  <br />全局            属性            Alt+Enter  <br />全局            新建            Ctrl+N  <br />   <br />项目  <br />作用域            功能            快捷键  <br />全局            全部构建            Ctrl+B  <br />   <br />源代码  <br />作用域            功能            快捷键  <br />Java编辑器            格式化            Ctrl+Shift+F  <br />Java编辑器            取消注释            Ctrl+  <br />Java编辑器            注释            Ctrl+/  <br />Java编辑器            添加导入            Ctrl+Shift+M  <br />Java编辑器            组织导入            Ctrl+Shift+O  <br />Java编辑器            使用try/catch块来包围            未设置，太常用了，所以在这里列出,建议自己设置。  <br />也可以使用Ctrl+1自动修正。  <br />   <br />运行  <br />作用域            功能            快捷键  <br />全局            单步返回            F7  <br />全局            单步跳过            F6  <br />全局            单步跳入            F5  <br />全局            单步跳入选择            Ctrl+F5  <br />全局            调试上次启动            F11  <br />全局            继续            F8  <br />全局            使用过滤器单步执行            Shift+F5  <br />全局            添加/去除断点            Ctrl+Shift+B  <br />全局            显示            Ctrl+D  <br />全局            运行上次启动            Ctrl+F11  <br />全局            运行至行            Ctrl+R  <br />全局            执行            Ctrl+U  <br />   <br />重构  <br />作用域            功能            快捷键  <br />全局            撤销重构            Alt+Shift+Z  <br />全局            抽取方法            Alt+Shift+M  <br />全局            抽取局部变量            Alt+Shift+L  <br />全局            内联            Alt+Shift+I  <br />全局            移动            Alt+Shift+V  <br />全局            重命名            Alt+Shift+R  <br />全局            重做            Alt+Shift+Y  <br /></p><img src ="http://www.blogjava.net/zhangzhong1018/aggbug/97017.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2007-01-31 17:11 <a href="http://www.blogjava.net/zhangzhong1018/articles/97017.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>tomcat 配置 （转载）</title><link>http://www.blogjava.net/zhangzhong1018/articles/96522.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Mon, 29 Jan 2007 07:51:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/96522.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/96522.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/96522.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/96522.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/96522.html</trackback:ping><description><![CDATA[
		<table cellspacing="0" cellpadding="0" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<th class="f24">
										<h1>Tomcat5.0+MySql配置JDBC，DBCP，SSL</h1>
								</th>
						</tr>
						<tr>
								<td align="middle" height="20">
										<font color="#999999">
												<small>作者：ycg01 来源:Java研究组织 (2005-07-21 10:28:13)</small>
										</font>
								</td>
						</tr>
						<tr>
								<td>
										<br />
								</td>
						</tr>
						<tr>
								<td>
										<!---广告 开- -->
										<!---广告 结- -->
								</td>
						</tr>
						<tr>
								<td class="l17">
										<font class="f14" id="zoom">
												<font color="#cccccc">
														<!-- 正文begin -->准备环境:<br /><br />1.j2sdk-1_4_2-windows-i586.exe<br /><br />//jdk<br /><br />2.mysql-4.0.20d-win.zip<br /><br />//m<span id="tech_art_center"><!-- Copyright 1999-2000 ThruPort Technologies http://www.thruport.com --><!-- end dynamic banner insert --></span>ysql数据库<br /><br />3.mysqlcc-0.9.4-win32.zip<br /><br />//mysqlGUI控制<br /><br />4.jakarta-tomcat-5.0.27.exe<br /><br />//tomcat服务器<br /><br />5.mysql-connector-java-3.0.14-production.zip<br /><br />//内含mysql驱动<br /><br />安装步骤:<br /><br />1.安装jdk<br /><br />2.安装tomcat<br /><br />3.安装mysql<br /><br />4.安装mysqlcc<br /><br />5.将驱动包解压,拷贝mysql-connector-java-3.0.14-production-bin.jar<br /><br />到tomcat/common/lib下<br /><br />或者下载mm.mysql-2.0.14-you-must-unjar-me.jar，<br /><br />解压后拷贝其中的mm.mysql-2.0.14-bin.jar<br /><br />Tomcat5.0配置 本例使用安装密码 198277<br /><br />1.配置manager 管理应用程序<br /><br />在conf/server.xml 中<br /><br />添加如下：<br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>&lt;Service name="Catalina"&gt;
...

    &lt;Context path="/manager"
	debug="0" privileged="true"
             docBase="/usr/local/kinetic
			/tomcat5/server/webapps/manager"&gt;
    &lt;/Context&gt;

&lt;/Service&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />限制IP访问配置 <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>&lt;Context path="/manager" 
debug="0" privileged="true"
         docBase="/usr/local/kinetic
		 /tomcat5/server/webapps/manager"&gt;
         &lt;Valve className="org.apache.
		 catalina.valves.RemoteAddrValve"
                allow="127.0.0.1"/&gt;
&lt;/Context&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />测试为:http://localhost:8080/manager/html <br /><br />2、配置JDBCRealm容器管理安全,以mysql-4.0数据库为例 <br /><br />a.拷贝驱动mm.mysql-2.0.14-bin.jar到common/lib/下 <br /><br />b.在数据库ycg中建表 <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>create table users 
(
  user_name         
  varchar(15) not null primary key,
  user_pass         
  varchar(15) not null
);

create table user_roles 
(
  user_name         
  varchar(15) not null,
  role_name         
  varchar(15) not null,
  primary key (user_name, role_name)
);</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />c.修改server.xml如下(默认数据库为root,无密码,如果有形如: <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>connectionURL="jdbc:mysql:
//localhost/authority?

user=dbuser&amp;password=dbpass")
      &lt;Realm  className="org.apache.catalina.
	  realm.JDBCRealm" debug="99"
             driverName="
			 org.gjt.mm.mysql.Driver"
          connectionURL="jdbc:mysql:
		  //localhost/ycg?user=root"
         connectionName="" 
		 connectionPassword=""
              userTable="users" 
			  userNameCol="user_name"
			  userCredCol="user_pass"
          userRoleTable="user_roles"
		  roleNameCol="role_name" /&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />d.在数据库中添加入tomcat的默认配置数据: <br /><br /><center><img src="http://tech.ccidnet.com/pub/attachment/2005/7/471933.jpg" /></center><br /><br />e.启动mysql,启动tomcat,此后tomcat将从数据库中读用户规则认证.默认的conf/tomcat-users.xml失效 <br /><br />3.DBCP的配置 <br /><br />a.设置 <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>&lt;parameter&gt;
    &lt;name&gt;removeAbandoned&lt;/name&gt;
        &lt;value&gt;true&lt;/value&gt;
            &lt;/parameter&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />可使失效的数据连接重新启用. <br /><br />配套设置 <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>&lt;parameter&gt;
    &lt;name&gt;removeAbandonedTimeout&lt;/name&gt;
          &lt;value&gt;60&lt;/value&gt;
            &lt;/parameter&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />失效时间 <br /><br />如果要写入日志 <br /><br />设置 <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>&lt;parameter&gt;
    &lt;name&gt;logAbandoned&lt;/name&gt;
         &lt;value&gt;true&lt;/value&gt;
            &lt;/parameter&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />以上三个默认都是false <br /><br />b.以mysql为例,配置数据连接池 <br /><br />c.配置新的用户与数据库,必须设定密码,空密码将导致连接失败 <br /><br />e. <br /><br />指定root密码: <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>mysqladmin -u root -h localhost 
password "198277"</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />(需修改上面的jdbcrealm设置connectionURL="jdbc:mysql://localhost/ycg?user=root&amp;password=198277") <br /><br />命令mysql进入匿名连接到服务器 <br /><br />密码访问 <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>shell&gt; mysql -h host -u user -p
Enter password: ********
//如果root没有密码,以下是不成功的.(试过了)
 mysql&gt; GRANT ALL PRIVILEGES ON *.*
 TO javauser@localhost 
    -&gt;   IDENTIFIED BY 'javadude' 
	WITH GRANT OPTION;
mysql&gt; create database javatest;
mysql&gt; use javatest;
mysql&gt; create table testdata
(
    -&gt;   id int not null 
	auto_increment primary key,
    -&gt;   foo varchar(25), 
    -&gt;   bar int);

在conf/server.xml中&lt;host&gt;&lt;/host&gt;
中添加
&lt;Context path="/DBTest" docBase="DBTest"
        debug="5" reloadable="true" 
		crossContext="true"&gt;

  &lt;Logger className="org.apache.
  catalina.logger.FileLogger"
             prefix="localhost_DBTest_log." 
			 suffix=".txt"
             timestamp="true"/&gt;

  &lt;Resource name="jdbc/TestDB"
               auth="Container"
               type="javax.sql.DataSource"/&gt;

  &lt;ResourceParams name="jdbc/TestDB"&gt;
    &lt;parameter&gt;
      &lt;name&gt;factory&lt;/name&gt;
      &lt;value&gt;org.apache.commons.dbcp.
	  BasicDataSourceFactory&lt;/value&gt;
    &lt;/parameter&gt;

    &lt;!-- Maximum number of dB connections 
	in pool. Make sure you
         configure your mysqld 
		 max_connections large enough to handle
         all of your db connections. 
		 Set to 0 for no limit.
         --&gt;
    &lt;parameter&gt;
      &lt;name&gt;maxActive&lt;/name&gt;
      &lt;value&gt;100&lt;/value&gt;
    &lt;/parameter&gt;

    &lt;!-- Maximum number of idle dB
	connections to retain in pool.
         Set to 0 for no limit.
         --&gt;
    &lt;parameter&gt;
      &lt;name&gt;maxIdle&lt;/name&gt;
      &lt;value&gt;30&lt;/value&gt;
    &lt;/parameter&gt;

    &lt;!-- Maximum time to wait for a 
	dB connection to become available
         in ms, in this example 10
		 seconds. An Exception is thrown if
         this timeout is exceeded. 
		 Set to -1 to wait indefinitely.
         --&gt;
    &lt;parameter&gt;
      &lt;name&gt;maxWait&lt;/name&gt;
      &lt;value&gt;10000&lt;/value&gt;
    &lt;/parameter&gt;

    &lt;!-- MySQL dB username and
	password for dB connections  --&gt;
    &lt;parameter&gt;
     &lt;name&gt;username&lt;/name&gt;
     &lt;value&gt;javauser&lt;/value&gt;
    &lt;/parameter&gt;
    &lt;parameter&gt;
     &lt;name&gt;password&lt;/name&gt;
     &lt;value&gt;javadude&lt;/value&gt;
    &lt;/parameter&gt;

    &lt;!-- Class name for the old mm.
	mysql JDBC driver - uncomment
	this entry and comment next
         if you want to use this driver
		 - we recommend using Connector/J though
    &lt;parameter&gt;
       &lt;name&gt;driverClassName&lt;/name&gt;
       &lt;value&gt;org.gjt.mm.mysql.Driver&lt;/value&gt;
    &lt;/parameter&gt;
     --&gt;
    
    &lt;!-- Class name for the official
	MySQL Connector/J driver --&gt;
    &lt;parameter&gt;
       &lt;name&gt;driverClassName&lt;/name&gt;
       &lt;value&gt;com.mysql.jdbc.Driver&lt;/value&gt;
    &lt;/parameter&gt;
    
    &lt;!-- The JDBC connection url for 
	connecting to your MySQL dB.
         The autoReconnect=true argument 
		 to the url makes sure that the
         mm.mysql JDBC Driver will 
		 automatically reconnect if mysqld closed the
         connection.  mysqld by default 
		 closes idle connections after 8 hours.
         --&gt;
    &lt;parameter&gt;
      &lt;name&gt;url&lt;/name&gt;
      &lt;value&gt;jdbc:mysql://localhost:3306
	 /javatest?autoReconnect=true&lt;/value&gt;
    &lt;/parameter&gt;


            &lt;parameter&gt;
              &lt;name&gt;removeAbandoned&lt;/name&gt;
              &lt;value&gt;true&lt;/value&gt;
            &lt;/parameter&gt;

             &lt;parameter&gt;
              &lt;name&gt;removeAbandonedTimeout&lt;/name&gt;
              &lt;value&gt;60&lt;/value&gt;
            &lt;/parameter&gt;
            &lt;parameter&gt;
              &lt;name&gt;logAbandoned&lt;/name&gt;
              &lt;value&gt;true&lt;/value&gt;
            &lt;/parameter&gt;
  &lt;/ResourceParams&gt;
&lt;/Context&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />f.在web服务中调用.配置web.xml 如: <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>&lt;web-app xmlns=
"http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi=
	"http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation=
	"http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4"&gt;
  &lt;description&gt;MySQL Test App&lt;/description&gt;
  &lt;resource-ref&gt;
      &lt;description&gt;DB Connection&lt;/description&gt;
      &lt;res-ref-name&gt;jdbc/TestDB&lt;/res-ref-name&gt;
      &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;
      &lt;res-auth&gt;Container&lt;/res-auth&gt;
  &lt;/resource-ref&gt;
&lt;/web-app&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />g.测试用test.jsp <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>&lt;%@ taglib uri=
"http://java.sun.com/jsp/jstl/sql"
prefix="sql" %&gt;
&lt;%@ taglib uri=
"http://java.sun.com/jsp/jstl/core"
prefix="c" %&gt;

&lt;sql:query var="rs"
dataSource="jdbc/TestDB"&gt;
select id, foo, bar from testdata
&lt;/sql:query&gt;

&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;DB Test&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;

  &lt;h2&gt;Results&lt;/h2&gt;
  
&lt;c:forEach var="row" items="${rs.rows}"&gt;
    Foo ${row.foo}&lt;br/&gt;
    Bar ${row.bar}&lt;br/&gt;
&lt;/c:forEach&gt;

  &lt;/body&gt;
&lt;/html&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />h.新建web应用 <br /><br />下载jakarta-taglibs-standard-1.1.0 <br /><br />copy jstl.jar and standard.jar to your web app's WEB-INF/lib <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>DBTest/
    WEB-INF/
        web.xml
        lib/
            jstl.jar
            standard.jar
    test.jsp</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />拷贝到webapps/ 下 <br /><br />i.启动mysql,tomcat <br /><br />访问: <br /><br />http://localhost:8080/DBTest/test.jsp <br /><br />显示: <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>Results
Foo hello
Bar 12345</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />4.ssl的配置,以jdk1.4.2为例 <br /><br />a.进入%JAVA_HOME%\bin <br /><br />运行命令:keytool -genkey -alias tomcat -keyalg RSA <br /><br />以tomcat 安装密码为198277,ketool设置密码为198277为例 <br /><br />输入keystore密码： 198277 <br /><br />您的名字与姓氏是什么？ <br /><br />[Unknown]： ycg <br /><br />您的组织单位名称是什么？ <br /><br />[Unknown]： nju <br /><br />您的组织名称是什么？ <br /><br />[Unknown]： nju <br /><br />您所在的城市或区域名称是什么？ <br /><br />[Unknown]： nanjing <br /><br />您所在的州或省份名称是什么？ <br /><br />[Unknown]： jiangsu <br /><br />该单位的两字母国家代码是什么 <br /><br />[Unknown]： nd <br /><br />CN=ycg, OU=nju, O=nju, L=nanjing, ST=jiangsu, C=nd 正确吗？ <br /><br />[否]： y <br /><br />输入<tomcat>的主密码 <br /><br />（如果和 keystore 密码相同，按回车）： 198277 <br /><br />b.在你的D:\Documents and Settings\的当前用户目录下可以找到.keystore文件.将其拷贝到conf/文件夹下. <br /><br />c.在server.xml 中找到 <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>&lt;!--
    &lt;Connector port="8443" 
   maxThreads="150" minSpareThreads="25" 
   maxSpareThreads="75"
   enableLookups="false" 
   disableUploadTimeout="true"
   acceptCount="100" debug="0"
   scheme="https" secure="true"
   clientAuth="false" sslProtocol="TLS" /&gt;
    --&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />去掉注释 <br /><br />添加配置字段:keystoreFile="/conf/.keystore" keystorePass="198277" <br /><br />如: <!-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 --><br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>&lt;Connector port="8443" 
 maxThreads="150" minSpareThreads=
 "25" maxSpareThreads="75"
  enableLookups="false" 
  disableUploadTimeout="true"
    acceptCount="100" debug="0" 
	scheme="https" secure="true"
     clientAuth="false" sslProtocol="TLS"
	 keystoreFile="/conf/.keystore"
       keystorePass="198277"/&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />d.测试为: <br /><br />https://localhost:8443 <br /><br />e.在自己的程序中添加ssl认证方式为: <br /><br />在web.xml 中<web-app></web-app>添加 <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>&lt;security-constraint&gt;
&lt;web-resource-collection&gt;
&lt;web-resource-name&gt;Success
&lt;/web-resource-name&gt;
&lt;url-pattern&gt;/&lt;/url-pattern&gt;
&lt;http-method&gt;GET&lt;/http-method&gt;
&lt;http-method&gt;POST&lt;/http-method&gt;
&lt;/web-resource-collection&gt;
&lt;user-data-constraint&gt;
&lt;transport-guarantee&gt;CONFIDENTIAL
&lt;/transport-guarantee&gt;
&lt;/user-data-constraint&gt;
&lt;/security-constraint&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />f.用上提为例就是 <br /><br />修改web.xml 为 <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>&lt;web-app xmlns=
"http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi=
	"http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation=
	"http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4"&gt;

    &lt;description&gt;MySQL Test App&lt;/description&gt;

&lt;security-constraint&gt;
&lt;web-resource-collection&gt;
&lt;web-resource-name&gt;Success
&lt;/web-resource-name&gt;
&lt;url-pattern&gt;/&lt;/url-pattern&gt;
&lt;http-method&gt;GET&lt;/http-method&gt;
&lt;http-method&gt;POST&lt;/http-method&gt;
&lt;/web-resource-collection&gt;
&lt;user-data-constraint&gt;
&lt;transport-guarantee&gt;CONFIDENTIAL
&lt;/transport-guarantee&gt;
&lt;/user-data-constraint&gt;
&lt;/security-constraint&gt;

  
  &lt;resource-ref&gt;
      &lt;description&gt;DB Connection&lt;/description&gt;
      &lt;res-ref-name&gt;jdbc/TestDB&lt;/res-ref-name&gt;
      &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;
      &lt;res-auth&gt;Container&lt;/res-auth&gt;
  &lt;/resource-ref&gt;
&lt;/web-app&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />访问: <br /><br />https://localhost:8443/DBTest/test.jsp <br /><br />g.如果与2配置的jdbcRealm结合起来进行表单认证 <br /><br />先在user_roles表中添加user_name:ycg role_name:web-user <br /><br />在users表中添加user_name:ycg user_pass:198277 <br /><br />然后在web.xml中添加 <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>&lt;auth-constraint&gt;
&lt;role-name&gt;web-user&lt;/role-name&gt;
&lt;/auth-constraint&gt;

&lt;login-config&gt;
 &lt;auth-method&gt;BASIC&lt;/auth-method&gt;
 &lt;realm-name&gt;My Member Area&lt;/realm-name&gt;
&lt;/login-config&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />修改后的web.xml如: <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>&lt;web-app xmlns=
"http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi=
	"http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation=
	"http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4"&gt;

    &lt;description&gt;MySQL Test App&lt;/description&gt;

&lt;security-constraint&gt;
&lt;web-resource-collection&gt;
&lt;web-resource-name&gt;Success
&lt;/web-resource-name&gt;
&lt;url-pattern&gt;/&lt;/url-pattern&gt;
&lt;http-method&gt;GET&lt;/http-method&gt;
&lt;http-method&gt;POST&lt;/http-method&gt;
&lt;/web-resource-collection&gt;
&lt;auth-constraint&gt;
&lt;role-name&gt;web-user&lt;/role-name&gt;
&lt;/auth-constraint&gt;
&lt;user-data-constraint&gt;
&lt;transport-guarantee&gt;CONFIDENTIAL
&lt;/transport-guarantee&gt;
&lt;/user-data-constraint&gt;
&lt;/security-constraint&gt;
&lt;login-config&gt;
 &lt;auth-method&gt;BASIC&lt;/auth-method&gt;
 &lt;realm-name&gt;My Member Area&lt;/realm-name&gt;
&lt;/login-config&gt;
  
  &lt;resource-ref&gt;
      &lt;description&gt;DB Connection&lt;/description&gt;
      &lt;res-ref-name&gt;jdbc/TestDB&lt;/res-ref-name&gt;
      &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;
      &lt;res-auth&gt;Container&lt;/res-auth&gt;
  &lt;/resource-ref&gt;
&lt;/web-app&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />测试: <br /><br />http://localhost:8080/DBTest/test.jsp <br /><br />将通过ssl连接,并进行表单认证.用户密码可在user_roles,和users中添加. <br /><br />5.中文乱码问题: <br /><br />mysql 默认编码 iso <br /><br />tomcat request 传输编码 iso <br /><br />如果要显示中文 <br /><br />在*.jsp中添加 <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>&lt;head&gt;
&lt;%@ page 
language="java"
contentType="text/html;
charset=GB18030"
pageEncoding="GB18030"
%&gt;
&lt;/head&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />如果是数据传输中的乱码(如用servlet从mysql数据库读出的数据)用以下两个转码函数转码，如果不清楚由哪种编码转成哪种编码，就多尝试。 <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>//转码GBK转ISO
    public String toISO(String input)
	{
        try
		{
                byte[] bytes = input.getBytes("GBK");
                return new String(bytes,"ISO8859-1");
        }catch(Exception ex) 
		{
        }
        return input;

    }
    
    //转码IS0转GBK
    public String toGBK(String input)
	{
        try {
            byte[] bytes = 
			input.getBytes("ISO8859-1");
            return new String(bytes,"GBK");
        }catch(Exception ex) {
        }
        return input;
    }</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br /><!-- 正文end --><br />(http://www.fanqiang.com)<br /></tomcat></font>
										</font>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/96522.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2007-01-29 15:51 <a href="http://www.blogjava.net/zhangzhong1018/articles/96522.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Lucene 学习 文章来自:http://lighter.javaeye.com</title><link>http://www.blogjava.net/zhangzhong1018/articles/96128.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Fri, 26 Jan 2007 05:41:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/96128.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/96128.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/96128.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/96128.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/96128.html</trackback:ping><description><![CDATA[
		<p>写文章的时候,感觉比较难写的就是标题,有时候不知道起什么名字好,反正这里写的都是关于lucene的一些简单的实例,就随便起啦.</p>
		<p>Lucene 其实很简单的,它最主要就是做两件事:建立索引和进行搜索 <br />来看一些在lucene中使用的术语,这里并不打算作详细的介绍,只是点一下而已----因为这一个世界有一种好东西，叫搜索。</p>
		<p>
				<span style="COLOR: blue">IndexWriter</span>:lucene中最重要的的类之一，它主要是用来将文档加入索引，同时控制索引过程中的一些参数使用。</p>
		<p>
				<span style="COLOR: blue">Analyzer</span>:分析器,主要用于分析搜索引擎遇到的各种文本。常用的有StandardAnalyzer分析器,StopAnalyzer分析器,WhitespaceAnalyzer分析器等。</p>
		<p>
				<span style="COLOR: blue">Directory</span>:索引存放的位置;lucene提供了两种索引存放的位置，一种是磁盘，一种是内存。一般情况将索引放在磁盘上；相应地lucene提供了FSDirectory和RAMDirectory两个类。</p>
		<p>
				<span style="COLOR: blue">Document</span>:文档;Document相当于一个要进行索引的单元，任何可以想要被索引的文件都必须转化为Document对象才能进行索引。</p>
		<p>
				<span style="COLOR: blue">Field</span>：字段。</p>
		<p>
				<span style="COLOR: blue">IndexSearcher</span>:是lucene中最基本的检索工具，所有的检索都会用到IndexSearcher工具;</p>
		<p>
				<span style="COLOR: blue">Query</span>:查询，lucene中支持模糊查询，语义查询，短语查询，组合查询等等,如有TermQuery,BooleanQuery,RangeQuery,WildcardQuery等一些类。</p>
		<p>
				<span style="COLOR: blue">QueryParser</span>: 是一个解析用户输入的工具，可以通过扫描用户输入的字符串，生成Query对象。</p>
		<p>
				<span style="COLOR: blue">Hits</span>:在搜索完成之后，需要把搜索结果返回并显示给用户，只有这样才算是完成搜索的目的。在lucene中，搜索的结果的集合是用Hits类的实例来表示的。</p>
		<p>上面作了一大堆名词解释，下面就看几个简单的实例吧: <br />1、简单的的StandardAnalyzer测试例子 <br /></p>
		<div class="code_title">代码</div>
		<div class="code_div">
				<div class="dp-highlighter">
						<div class="bar">
						</div>
						<ol class="dp-j">
								<li class="alt">
										<span>
												<span class="keyword">package</span>
												<span> lighter.javaeye.com;   </span>
										</span>
								</li>
								<li class="">
										<span>  </span>
								</li>
								<li class="alt">
										<span>
										</span>
										<span class="keyword">import</span>
										<span> java.io.IOException;   </span>
								</li>
								<li class="">
										<span>
										</span>
										<span class="keyword">import</span>
										<span> java.io.StringReader;   </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li class="">
										<span>
										</span>
										<span class="keyword">import</span>
										<span> org.apache.lucene.analysis.Analyzer;   </span>
								</li>
								<li class="alt">
										<span>
										</span>
										<span class="keyword">import</span>
										<span> org.apache.lucene.analysis.Token;   </span>
								</li>
								<li class="">
										<span>
										</span>
										<span class="keyword">import</span>
										<span> org.apache.lucene.analysis.TokenStream;   </span>
								</li>
								<li class="alt">
										<span>
										</span>
										<span class="keyword">import</span>
										<span> org.apache.lucene.analysis.standard.StandardAnalyzer;   </span>
								</li>
								<li class="">
										<span>  </span>
								</li>
								<li class="alt">
										<span>
										</span>
										<span class="keyword">public</span>
										<span> </span>
										<span class="keyword">class</span>
										<span> StandardAnalyzerTest    </span>
								</li>
								<li class="">
										<span>{   </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="comment">//构造函数， </span>
										<span>  </span>
								</li>
								<li class="">
										<span>    </span>
										<span class="keyword">public</span>
										<span> StandardAnalyzerTest()   </span>
								</li>
								<li class="alt">
										<span>    {   </span>
								</li>
								<li class="">
										<span>    }   </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="keyword">public</span>
										<span> </span>
										<span class="keyword">static</span>
										<span> </span>
										<span class="keyword">void</span>
										<span> main(String[] args)    </span>
								</li>
								<li class="">
										<span>    {   </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="comment">//生成一个StandardAnalyzer对象 </span>
										<span>  </span>
								</li>
								<li class="">
										<span>        Analyzer aAnalyzer = </span>
										<span class="keyword">new</span>
										<span> StandardAnalyzer();   </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="comment">//测试字符串 </span>
										<span>  </span>
								</li>
								<li class="">
										<span>        StringReader sr = </span>
										<span class="keyword">new</span>
										<span> StringReader(</span>
										<span class="string">"lighter javaeye com is the are on"</span>
										<span>);   </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="comment">//生成TokenStream对象 </span>
										<span>  </span>
								</li>
								<li class="">
										<span>        TokenStream ts = aAnalyzer.tokenStream(</span>
										<span class="string">"name"</span>
										<span>, sr);    </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="keyword">try</span>
										<span> {   </span>
								</li>
								<li class="">
										<span>            </span>
										<span class="keyword">int</span>
										<span> i=</span>
										<span class="number">0</span>
										<span>;   </span>
								</li>
								<li class="alt">
										<span>            Token t = ts.next();   </span>
								</li>
								<li class="">
										<span>            </span>
										<span class="keyword">while</span>
										<span>(t!=</span>
										<span class="keyword">null</span>
										<span>)   </span>
								</li>
								<li class="alt">
										<span>            {   </span>
								</li>
								<li class="">
										<span>                </span>
										<span class="comment">//辅助输出时显示行号 </span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>                i++;   </span>
								</li>
								<li class="">
										<span>                </span>
										<span class="comment">//输出处理后的字符 </span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>                System.out.println(</span>
										<span class="string">"第"</span>
										<span>+i+</span>
										<span class="string">"行:"</span>
										<span>+t.termText());   </span>
								</li>
								<li class="">
										<span>                </span>
										<span class="comment">//取得下一个字符 </span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>                t=ts.next();   </span>
								</li>
								<li class="">
										<span>            }   </span>
								</li>
								<li class="alt">
										<span>        } </span>
										<span class="keyword">catch</span>
										<span> (IOException e) {   </span>
								</li>
								<li class="">
										<span>            e.printStackTrace();   </span>
								</li>
								<li class="alt">
										<span>        }   </span>
								</li>
								<li class="">
										<span>    }   </span>
								</li>
								<li class="alt">
										<span>}   </span>
								</li>
						</ol>
				</div>
		</div>
		<script><![CDATA[ender_code();]]&gt;</script>
		<br />显示结果： <br /><div class="quote_title">引用</div><div class="quote_div">第1行:lighter <br />第2行:javaeye <br />第3行:com</div><br />提示一下： <br />StandardAnalyzer是lucene中内置的"标准分析器",可以做如下功能: <br />1、对原有句子按照空格进行了分词 <br />2、所有的大写字母都可以能转换为小写的字母 <br />3、可以去掉一些没有用处的单词，例如"is","the","are"等单词，也删除了所有的标点 <br />查看一下结果与"new StringReader("lighter javaeye com is the are on")"作一个比较就清楚明了。 <br />这里不对其API进行解释了，具体见lucene的官方文档。需要注意一点，这里的代码使用的是lucene2的API，与1.43版有一些明显的差别。 
<p></p><p>2、看另一个实例,简单地建立索引，进行搜索 <br /></p><div class="code_title">代码</div><div class="code_div"><div class="dp-highlighter"><div class="bar"></div><ol class="dp-j"><li class="alt"><span><span class="keyword">package</span><span> lighter.javaeye.com;   </span></span></li><li class=""><span></span><span class="keyword">import</span><span> org.apache.lucene.analysis.standard.StandardAnalyzer;   </span></li><li class="alt"><span></span><span class="keyword">import</span><span> org.apache.lucene.document.Document;   </span></li><li class=""><span></span><span class="keyword">import</span><span> org.apache.lucene.document.Field;   </span></li><li class="alt"><span></span><span class="keyword">import</span><span> org.apache.lucene.index.IndexWriter;   </span></li><li class=""><span></span><span class="keyword">import</span><span> org.apache.lucene.queryParser.QueryParser;   </span></li><li class="alt"><span></span><span class="keyword">import</span><span> org.apache.lucene.search.Hits;   </span></li><li class=""><span></span><span class="keyword">import</span><span> org.apache.lucene.search.IndexSearcher;   </span></li><li class="alt"><span></span><span class="keyword">import</span><span> org.apache.lucene.search.Query;   </span></li><li class=""><span></span><span class="keyword">import</span><span> org.apache.lucene.store.FSDirectory;   </span></li><li class="alt"><span>  </span></li><li class=""><span></span><span class="keyword">public</span><span> </span><span class="keyword">class</span><span> FSDirectoryTest {   </span></li><li class="alt"><span>  </span></li><li class=""><span>    </span><span class="comment">//建立索引的路径 </span><span>  </span></li><li class="alt"><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">final</span><span> String path = </span><span class="string">"c:\\index2"</span><span>;   </span></li><li class=""><span>  </span></li><li class="alt"><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">void</span><span> main(String[] args) </span><span class="keyword">throws</span><span> Exception {   </span></li><li class=""><span>        Document doc1 = </span><span class="keyword">new</span><span> Document();   </span></li><li class="alt"><span>        doc1.add( </span><span class="keyword">new</span><span> Field(</span><span class="string">"name"</span><span>, </span><span class="string">"lighter javaeye com"</span><span>,Field.Store.YES,Field.Index.TOKENIZED));   </span></li><li class=""><span>  </span></li><li class="alt"><span>        Document doc2 = </span><span class="keyword">new</span><span> Document();   </span></li><li class=""><span>        doc2.add(</span><span class="keyword">new</span><span> Field(</span><span class="string">"name"</span><span>, </span><span class="string">"lighter blog"</span><span>,Field.Store.YES,Field.Index.TOKENIZED));   </span></li><li class="alt"><span>  </span></li><li class=""><span>        IndexWriter writer = </span><span class="keyword">new</span><span> IndexWriter(FSDirectory.getDirectory(path, </span><span class="keyword">true</span><span>), </span><span class="keyword">new</span><span> StandardAnalyzer(), </span><span class="keyword">true</span><span>);   </span></li><li class="alt"><span>        writer.setMaxFieldLength(</span><span class="number">3</span><span>);   </span></li><li class=""><span>        writer.addDocument(doc1);   </span></li><li class="alt"><span>        writer.setMaxFieldLength(</span><span class="number">3</span><span>);   </span></li><li class=""><span>        writer.addDocument(doc2);   </span></li><li class="alt"><span>        writer.close();   </span></li><li class=""><span>  </span></li><li class="alt"><span>        IndexSearcher searcher = </span><span class="keyword">new</span><span> IndexSearcher(path);   </span></li><li class=""><span>        Hits hits = </span><span class="keyword">null</span><span>;   </span></li><li class="alt"><span>        Query query = </span><span class="keyword">null</span><span>;   </span></li><li class=""><span>        QueryParser qp = </span><span class="keyword">new</span><span> QueryParser(</span><span class="string">"name"</span><span>,</span><span class="keyword">new</span><span> StandardAnalyzer());   </span></li><li class="alt"><span>           </span></li><li class=""><span>        query = qp.parse(</span><span class="string">"lighter"</span><span>);   </span></li><li class="alt"><span>        hits = searcher.search(query);   </span></li><li class=""><span>        System.out.println(</span><span class="string">"查找\"lighter\" 共"</span><span> + hits.length() + </span><span class="string">"个结果"</span><span>);   </span></li><li class="alt"><span>  </span></li><li class=""><span>        query = qp.parse(</span><span class="string">"javaeye"</span><span>);   </span></li><li class="alt"><span>        hits = searcher.search(query);   </span></li><li class=""><span>        System.out.println(</span><span class="string">"查找\"javaeye\" 共"</span><span> + hits.length() + </span><span class="string">"个结果"</span><span>);   </span></li><li class="alt"><span>  </span></li><li class=""><span>    }   </span></li><li class="alt"><span>  </span></li><li class=""><span>}  </span></li></ol></div></div><script><![CDATA[ender_code();]]&gt;</script><br />运行结果： <br /><div class="code_title">代码</div><div class="code_div"><div class="bar"></div><div class="dp-highlighter"><ol class="dp-j"><li class="alt"><span><span>查找</span><span class="string">"lighter"</span><span> 共</span><span class="number">2</span><span>个结果   </span></span></li><li class=""><span>查找</span><span class="string">"javaeye"</span><span> 共</span><span class="number">1</span><span>个结果 </span></li></ol></div><p class=""><span></span> </p><span><div class="quote_div">//测试字符串 <br />StringReader sr = new StringReader("lighter javaeye com"); <br />//生成TokenStream对象 <br />TokenStream ts = aAnalyzer.tokenStream("name", sr); <br />请问:以上的解析是按什么来解析,为什么他会自动的按空格或者","进行字符分割,再一个当SR里输入是中文字符时,他将会对每个字进行分割,请问这是为什么,同时这功能的实现又意为着什么呢.....????</div><p class=""><br />StandardAnalyzer是lucene中内置的"标准分析器",可以做如下功能: <br />1、对原有句子按照空格进行了分词 <br />2、所有的大写字母都可以能转换为小写的字母 <br />3、可以去掉一些没有用处的单词，例如"is","the","are"等单词，也删除了所有的标点 <br />同时也可以对中文进行分词(效果不好),现在有很多的中文分词包可以采用 <br /><br /><br /></p><p>说明一下,这一篇文章的用到的lucene,是用2.0版本的,主要在查询的时候2.0版本的lucene与以前的版本有了一些区别. <br />其实这一些代码都是早几个月写的,自己很懒,所以到今天才写到自己的博客上,高深的文章自己写不了，只能记录下一些简单的记录与点滴，其中的代码算是自娱自乐的，希望高手不要把重构之类的砸下来...</p><p>1、在windows系统下的的C盘，建一个名叫s的文件夹,在该文件夹里面随便建三个txt文件，随便起名啦，就叫"1.txt","2.txt"和"3.txt"啦 <br />其中1.txt的内容如下： <br /></p><div class="code_title">代码</div><div class="code_div"><div class="dp-highlighter"><div class="bar"></div><ol class="dp-j"><li class="alt"><span><span>中华人民共和国   </span></span></li><li class=""><span>全国人民   </span></li><li class="alt"><span></span><span class="number">2006</span><span>年  </span></li></ol></div></div></span></div><p class=""><script><![CDATA[ender_code();]]&gt;</script><br />而"2.txt"和"3.txt"的内容也可以随便写几写，这里懒写，就复制一个和1.txt文件的内容一样吧 </p><p></p><p>2、下载lucene包，放在classpath路径中 <br />建立索引: <br /></p><div class="code_title">代码</div><div class="code_div"><div class="dp-highlighter"><div class="bar"></div><ol class="dp-j"><li class="alt"><span><span class="keyword">package</span><span> lighter.javaeye.com;   </span></span></li><li class=""><span>  </span></li><li class="alt"><span></span><span class="keyword">import</span><span> java.io.BufferedReader;   </span></li><li class=""><span></span><span class="keyword">import</span><span> java.io.File;   </span></li><li class="alt"><span></span><span class="keyword">import</span><span> java.io.FileInputStream;   </span></li><li class=""><span></span><span class="keyword">import</span><span> java.io.IOException;   </span></li><li class="alt"><span></span><span class="keyword">import</span><span> java.io.InputStreamReader;   </span></li><li class=""><span></span><span class="keyword">import</span><span> java.util.Date;   </span></li><li class="alt"><span>  </span></li><li class=""><span></span><span class="keyword">import</span><span> org.apache.lucene.analysis.Analyzer;   </span></li><li class="alt"><span></span><span class="keyword">import</span><span> org.apache.lucene.analysis.standard.StandardAnalyzer;   </span></li><li class=""><span></span><span class="keyword">import</span><span> org.apache.lucene.document.Document;   </span></li><li class="alt"><span></span><span class="keyword">import</span><span> org.apache.lucene.document.Field;   </span></li><li class=""><span></span><span class="keyword">import</span><span> org.apache.lucene.index.IndexWriter;   </span></li><li class="alt"><span>  </span></li><li class=""><span></span><span class="comment">/** </span> </li><li class="alt"><span><span class="comment"> * author lighter date 2006-8-7 </span> </span></li><li class=""><span><span class="comment"> */</span><span>  </span></span></li><li class="alt"><span></span><span class="keyword">public</span><span> </span><span class="keyword">class</span><span> TextFileIndexer {   </span></li><li class=""><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">void</span><span> main(String[] args) </span><span class="keyword">throws</span><span> Exception {   </span></li><li class="alt"><span>        </span><span class="comment">/* 指明要索引文件夹的位置,这里是C盘的S文件夹下 */</span><span>  </span></li><li class=""><span>        File fileDir = </span><span class="keyword">new</span><span> File(</span><span class="string">"c:\\s"</span><span>);   </span></li><li class="alt"><span>  </span></li><li class=""><span>        </span><span class="comment">/* 这里放索引文件的位置 */</span><span>  </span></li><li class="alt"><span>        File indexDir = </span><span class="keyword">new</span><span> File(</span><span class="string">"c:\\index"</span><span>);   </span></li><li class=""><span>        Analyzer luceneAnalyzer = </span><span class="keyword">new</span><span> StandardAnalyzer();   </span></li><li class="alt"><span>        IndexWriter indexWriter = </span><span class="keyword">new</span><span> IndexWriter(indexDir, luceneAnalyzer,   </span></li><li class=""><span>                </span><span class="keyword">true</span><span>);   </span></li><li class="alt"><span>        File[] textFiles = fileDir.listFiles();   </span></li><li class=""><span>        </span><span class="keyword">long</span><span> startTime = </span><span class="keyword">new</span><span> Date().getTime();   </span></li><li class="alt"><span>           </span></li><li class=""><span>        </span><span class="comment">//增加document到索引去 </span><span>  </span></li><li class="alt"><span>        </span><span class="keyword">for</span><span> (</span><span class="keyword">int</span><span> i = </span><span class="number">0</span><span>; i &lt; textFiles.length; i++) {   </span></li><li class=""><span>            </span><span class="keyword">if</span><span> (textFiles[i].isFile()   </span></li><li class="alt"><span>                    &amp;&amp; textFiles[i].getName().endsWith(</span><span class="string">".txt"</span><span>)) {   </span></li><li class=""><span>                System.out.println(</span><span class="string">"File "</span><span> + textFiles[i].getCanonicalPath()   </span></li><li class="alt"><span>                        + </span><span class="string">"正在被索引...."</span><span>);   </span></li><li class=""><span>                String temp = FileReaderAll(textFiles[i].getCanonicalPath(),   </span></li><li class="alt"><span>                        </span><span class="string">"GBK"</span><span>);   </span></li><li class=""><span>                System.out.println(temp);   </span></li><li class="alt"><span>                Document document = </span><span class="keyword">new</span><span> Document();   </span></li><li class=""><span>                Field FieldPath = </span><span class="keyword">new</span><span> Field(</span><span class="string">"path"</span><span>, textFiles[i].getPath(),   </span></li><li class="alt"><span>                        Field.Store.YES, Field.Index.NO);   </span></li><li class=""><span>                Field FieldBody = </span><span class="keyword">new</span><span> Field(</span><span class="string">"body"</span><span>, temp, Field.Store.YES,   </span></li><li class="alt"><span>                        Field.Index.TOKENIZED,   </span></li><li class=""><span>                        Field.TermVector.WITH_POSITIONS_OFFSETS);   </span></li><li class="alt"><span>                document.add(FieldPath);   </span></li><li class=""><span>                document.add(FieldBody);   </span></li><li class="alt"><span>                indexWriter.addDocument(document);   </span></li><li class=""><span>            }   </span></li><li class="alt"><span>        }   </span></li><li class=""><span>        </span><span class="comment">//optimize()方法是对索引进行优化 </span><span>  </span></li><li class="alt"><span>        indexWriter.optimize();   </span></li><li class=""><span>        indexWriter.close();   </span></li><li class="alt"><span>           </span></li><li class=""><span>        </span><span class="comment">//测试一下索引的时间 </span><span>  </span></li><li class="alt"><span>        </span><span class="keyword">long</span><span> endTime = </span><span class="keyword">new</span><span> Date().getTime();   </span></li><li class=""><span>        System.out   </span></li><li class="alt"><span>                .println(</span><span class="string">"这花费了"</span><span>  </span></li><li class=""><span>                        + (endTime - startTime)   </span></li><li class="alt"><span>                        + </span><span class="string">" 毫秒来把文档增加到索引里面去!"</span><span>  </span></li><li class=""><span>                        + fileDir.getPath());   </span></li><li class="alt"><span>    }   </span></li><li class=""><span>  </span></li><li class="alt"><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">static</span><span> String FileReaderAll(String FileName, String charset)   </span></li><li class=""><span>            </span><span class="keyword">throws</span><span> IOException {   </span></li><li class="alt"><span>        BufferedReader reader = </span><span class="keyword">new</span><span> BufferedReader(</span><span class="keyword">new</span><span> InputStreamReader(   </span></li><li class=""><span>                </span><span class="keyword">new</span><span> FileInputStream(FileName), charset));   </span></li><li class="alt"><span>        String line = </span><span class="keyword">new</span><span> String();   </span></li><li class=""><span>        String temp = </span><span class="keyword">new</span><span> String();   </span></li><li class="alt"><span>           </span></li><li class=""><span>        </span><span class="keyword">while</span><span> ((line = reader.readLine()) != </span><span class="keyword">null</span><span>) {   </span></li><li class="alt"><span>            temp += line;   </span></li><li class=""><span>        }   </span></li><li class="alt"><span>        reader.close();   </span></li><li class=""><span>        </span><span class="keyword">return</span><span> temp;   </span></li><li class="alt"><span>    }   </span></li><li class=""><span>}  </span></li></ol></div></div><script><![CDATA[ender_code();]]&gt;</script><p></p><p>索引的结果： <br /></p><div class="code_title">代码</div><div class="code_div"><div class="dp-highlighter"><div class="bar"></div><ol class="dp-j"><li class="alt"><span><span>File C:\s\</span><span class="number">1</span><span>.txt正在被索引....   </span></span></li><li class=""><span>中华人民共和国全国人民</span><span class="number">2006</span><span>年   </span></li><li class="alt"><span>File C:\s\</span><span class="number">2</span><span>.txt正在被索引....   </span></li><li class=""><span>中华人民共和国全国人民</span><span class="number">2006</span><span>年   </span></li><li class="alt"><span>File C:\s\</span><span class="number">3</span><span>.txt正在被索引....   </span></li><li class=""><span>中华人民共和国全国人民</span><span class="number">2006</span><span>年   </span></li><li class="alt"><span>这花费了</span><span class="number">297</span><span> 毫秒来把文档增加到索引里面去!c:\s  </span></li></ol></div></div><script><![CDATA[ender_code();]]&gt;</script><p></p><p>3、建立了索引之后，查询啦.... <br /></p><div class="code_title">代码</div><div class="code_div"><div class="dp-highlighter"><div class="bar"></div><ol class="dp-j"><li class="alt"><span><span class="keyword">package</span><span> lighter.javaeye.com;   </span></span></li><li class=""><span>  </span></li><li class="alt"><span></span><span class="keyword">import</span><span> java.io.IOException;   </span></li><li class=""><span>  </span></li><li class="alt"><span></span><span class="keyword">import</span><span> org.apache.lucene.analysis.Analyzer;   </span></li><li class=""><span></span><span class="keyword">import</span><span> org.apache.lucene.analysis.standard.StandardAnalyzer;   </span></li><li class="alt"><span></span><span class="keyword">import</span><span> org.apache.lucene.queryParser.ParseException;   </span></li><li class=""><span></span><span class="keyword">import</span><span> org.apache.lucene.queryParser.QueryParser;   </span></li><li class="alt"><span></span><span class="keyword">import</span><span> org.apache.lucene.search.Hits;   </span></li><li class=""><span></span><span class="keyword">import</span><span> org.apache.lucene.search.IndexSearcher;   </span></li><li class="alt"><span></span><span class="keyword">import</span><span> org.apache.lucene.search.Query;   </span></li><li class=""><span>  </span></li><li class="alt"><span></span><span class="keyword">public</span><span> </span><span class="keyword">class</span><span> TestQuery {   </span></li><li class=""><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">void</span><span> main(String[] args) </span><span class="keyword">throws</span><span> IOException, ParseException {   </span></li><li class="alt"><span>        Hits hits = </span><span class="keyword">null</span><span>;   </span></li><li class=""><span>        String queryString = </span><span class="string">"中华"</span><span>;   </span></li><li class="alt"><span>        Query query = </span><span class="keyword">null</span><span>;   </span></li><li class=""><span>        IndexSearcher searcher = </span><span class="keyword">new</span><span> IndexSearcher(</span><span class="string">"c:\\index"</span><span>);   </span></li><li class="alt"><span>  </span></li><li class=""><span>        Analyzer analyzer = </span><span class="keyword">new</span><span> StandardAnalyzer();   </span></li><li class="alt"><span>        </span><span class="keyword">try</span><span> {   </span></li><li class=""><span>            QueryParser qp = </span><span class="keyword">new</span><span> QueryParser(</span><span class="string">"body"</span><span>, analyzer);   </span></li><li class="alt"><span>            query = qp.parse(queryString);   </span></li><li class=""><span>        } </span><span class="keyword">catch</span><span> (ParseException e) {   </span></li><li class="alt"><span>        }   </span></li><li class=""><span>        </span><span class="keyword">if</span><span> (searcher != </span><span class="keyword">null</span><span>) {   </span></li><li class="alt"><span>            hits = searcher.search(query);   </span></li><li class=""><span>            </span><span class="keyword">if</span><span> (hits.length() &gt; </span><span class="number">0</span><span>) {   </span></li><li class="alt"><span>                System.out.println(</span><span class="string">"找到:"</span><span> + hits.length() + </span><span class="string">" 个结果!"</span><span>);   </span></li><li class=""><span>            }   </span></li><li class="alt"><span>        }   </span></li><li class=""><span>    }   </span></li><li class="alt"><span>  </span></li><li class=""><span>}  </span></li></ol></div></div><script><![CDATA[ender_code();]]&gt;</script><p></p><p>其运行结果： <br /></p><div class="quote_title">引用</div><div class="quote_div">找到:3 个结果!</div><div class="quote_title">balaschen 写道</div><div class="quote_div"><div class="quote_title">引用</div><div class="quote_div"><br />说明一下,这一篇文章的用到的lucene,是用2.0版本的,主要在查询的时候2.0版本的lucene与以前的版本有了一些区别. </div><br />主要区别在什么地方啊，从你的代码看，方法好像是一样？<img src="http://www.javaeye.com/images/forum/smiles/icon_confused.gif" /></div><p class=""><br />打一个例子吧, <br />这是lucene2.0的API <br /></p><div class="code_title">代码</div><div class="code_div"><div class="dp-highlighter"><div class="bar"></div><ol class="dp-j"><li class="alt"><span><span>QueryParser qp = </span><span class="keyword">new</span><span> QueryParser(</span><span class="string">"body"</span><span>, analyzer);      </span></span></li><li class=""><span>query = qp.parse(queryString);      </span></li></ol></div></div><script><![CDATA[ender_code();]]&gt;</script><p></p><p>这是lucene1.4.3版的API <br /></p><div class="code_title">代码</div><div class="code_div"><div class="dp-highlighter"><div class="bar"></div><ol class="dp-j"><li class="alt"><span><span>query = QueryParser.parse(key,queryString,</span><span class="keyword">new</span><span> </span><span class="keyword">new</span><span> StandardAnalyzer());  </span></span></li></ol></div></div><p class=""><script><![CDATA[ender_code();]]&gt;</script><br />详细的改动看一些官方的文档就清楚啦<br /><br /><br /><br /><br /></p><p class=""><span></span> </p><img src ="http://www.blogjava.net/zhangzhong1018/aggbug/96128.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2007-01-26 13:41 <a href="http://www.blogjava.net/zhangzhong1018/articles/96128.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java扮演嵌入式应用开发主角 http://mobile.csdn.net/subject/J2ME_Nokia/</title><link>http://www.blogjava.net/zhangzhong1018/articles/89072.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Wed, 20 Dec 2006 08:26:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/89072.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/89072.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/89072.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/89072.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/89072.html</trackback:ping><description><![CDATA[
		<p>嵌入式Java会在下一代移动电话、智能卡、无线设备、游戏装置及其他许多嵌入式应用中扮演重要角色，关键在于选择哪一种实现方法。 </p>
		<p>Java自从推出以来一直备受关注，不过在嵌入式系统设计师看来，其性能并不能令人满意。运行Java虚拟机（JVM）解释Java字节码这种方式对大多数嵌入式应用来说占用空间过多，运行速度过慢。不过Sun的Java 2 Micro Edition（J2ME）改变了这种状况。 </p>
		<p>对嵌入式系统设计师来说，Java有许多优点。作为一门编程语言，Java允许面向对象编程，又没有C++中存在的严重问题。例如，Java允许类继承，但不允许来自多个父类，这就排除了产生混淆的可能；同样，Java防止了C++定义运算符时允许出现的不确定性。Java运行时环境还提供了有用属性，它通过先检查JVM中的代码然后再执行来确保应用程序不会相互干扰，以及整个系统不会崩溃，如果代码试图改变系统的核心行为，它就无法运行。Java提供的内存管理功能使得编程人员不必分配及释放内存，避免了内存泄露的可能，它还能通过垃圾收集方法，自动释放闲置内存。运行时环境甚至可以通过整合核心类库来简化程序分配。 </p>
		<p>此外，Java在业界得到了广泛支持，这意味着有众多资源可以利用，包括小应用程序和经验丰富的编程人员，从而每次编写新应用程序无需重复性工作。 </p>
		<p>但在上述这些优点之外，Java用于嵌入式开发的问题在于，大多数嵌入式应用面临Java没有处理好的两大约束：没有足够的空间和时间。 </p>
		<p>Java开发的时间和空间约束 </p>
		<p>之所以会有时间上的约束，是嵌入式系统通常必须在短时间内对外部事件做出响应，如果系统在下一个事件出现前没有处理好前一个事件，就无法完成任务。 </p>
		<p>时间上的约束还意味着需要确定性。设计师依靠软件元素，在已知或者有限的时间内完成各自的任务，本身没有时间限制的任务（如等待循环）在执行时间攸关的任务时，能够暂停挂起。 </p>
		<p>嵌入式开发的空间约束来自对成本和便携性的需求。设计师需要尽量少用内存，往往使得设计受微控制器的片上内存资源的制约。但这也有助于降低功耗，这是电池供电的便携系统所考虑的一个重要因素。 </p>
		<p>在这些时间和空间的约束下Java很难正常工作。Java软件环境要与操作系统协同工作，并使用Java虚拟机把Java字节码转换成系统处理器的本机语言。它还需要相当大的类库，作为核心系统的一部分。这两种因素大大增加了对系统内存的需求。 </p>
		<p>Java的解释码运行起来本身就不如编译码快，这样一来，系统更难满足实时约束条件了。速度更快的处理器或许能帮上忙，但功耗因素往往使得嵌入式系统无法使用更快的处理器。就算系统足够快，Java的垃圾收集算法也没有时间限制、不可中断，就不可能获得确定性。 </p>
		<p>J2ME定义两类Java </p>
		<p>对于Java在嵌入式开发中遇到的问题，J2ME可以解决其中的一部分。办法是缩减类库大小，并且改变垃圾收集算法。J2ME定义了两类Java：连接设备配置（CDC）和连接有限设备配置（CLDC），让Java得以适用于诸多嵌入式系统，如下表所示。这些Java取代了较旧的嵌入式Java，而旧版本实际上是用于定制应用的非标准版本的Java。 </p>
		<p>
				<img alt="" hspace="0" src="http://images.csdn.net/20050701/b01_1t1.jpg" align="baseline" border="0" />
		</p>
		<p class="a14">CDC是一种功能齐全的Java，面向配有网络连接、32位处理器和供Java平台使用的2MB内存的设备。这个版本的Java允许设备以类似桌面机的方式，下载及运行通用的小应用程序。PDA、家用电器和汽车导航系统就是适合的目标应用。 
</p>
		<p class="a14">CLDC是一种精简版的Java，面向运行时环境更加定制的应用。CLDC并不允许运行通用小应用程序，而是要求Java程序符合设备的约束条件。这样一来，Java“编写一次、到处运行”的优势也就无从谈起，不过它仍保留了Java编程的其他优点。CLDC及其K虚拟机需要160KB的内存和16MHz的16位处理器。 
</p>
		<p class="a14">Sun利用这两种配置，开发出了符合许多嵌入式系统设计空间约束的标准Java配置，Java社区制订的实时Java规范使得实时和确定性问题迎刃而解。实时Java规范（RTSJ）V1.0提供了Java平台的标准扩展部分，并且改动了垃圾收集算法，确保了Java提供许多嵌入式应用所需的确定性。 
</p>
		<p class="a14">这就只剩下原始性能问题还没有加以解决。解决办法来自行业提高Java执行速度的一系列方法，包括使用优化的JVM、执行前先把Java代码编译成本机码，使用及时（JIT）编程器以及使用硬件加速，每种方法各有优缺点。 
</p>
		<p class="a14">与普通JVM相比，优化的JVM通常可以把执行速度提高2～2.5倍。不过，这种优化要针对特定处理器。提供优化的JVM的厂商可能还会提供优化的类库和实时操作系统，能够与JVM密切合作，进一步提高软件性能。 
</p>
		<p class="a14">不管有没有经过优化，使用JVM仍需要解释工作，这就限制了程序的执行速度。把Java代码编译成本机码、然后再执行可以避免这种限制。这种情况下，Java成了类似C++的另一种高级语言，限制执行速度的因素完全取决于编译器的代码效率。问题在于，与其他高级语言一样，必须在把代码植入程序内存之前，先进行这种编译，结果导致系统缺乏灵活性，无法下载升级的Java代码或者是新的应用程序。 
</p>
		<p class="a14">及时编译器力求通过“高速”编译Java代码以便可以立即执行，重新获得这种灵活性。这带来了高性能和灵活性，但也增加了特定应用程序的启动时间，因为需要先开始编译。由于至少占用100KB的内存（加上JVM和应用程序所需内存），使用及时编译器还加大了对系统内存的需求。 
</p>
		<p class="a14">
				<b>硬件加速Java</b>
		</p>
		<p class="a14">为了加快Java执行，又避开编译或者软件JVM的缺点，嵌入式开发人员可以求助于硬件加速器。这种设备把JVM的部分或者全部任务转交给专用硬件去处理，因而性能比解释的Java提高了5～10倍。不过，硬件加速器并不接管所有任务，主机CPU仍处理特别复杂或者很少使用的字节码。 
</p>
		<p class="a14">半导体厂商采用了几种方法，通过硬件来加快Java的执行速度，致力于不同任务。 
</p>
		<p class="a14">一种是使用硬件解释器。该解释器把进来的Java代码的大部分转化成本机码，从而给JVM省去了麻烦。例如Nazomi的Jstar、InSilicon的JVX和ARM的Jazelle。大多数情况下，解释器拥有硅知识产权，这实际上扩大了处理器的指令集。 
</p>
		<p class="a14">另一种方法就是使用协处理器。协处理器不仅解释字节码，还执行由此生成的机器码，让CPU完全得到解放。协处理器实际上是一种处理器，使用Java字节码作为本机机器语言。有些协处理器如InSilicon公司的JVXtreme是纯粹的协处理器，而有些协处理器如Aurora VLSI公司的Espresso和DeCaf可以充当协处理器或者独立处理器，这样在另一个CPU处理用户界面等事务时，可以处理Java代码。Ajile公司的aJ-100、DCT公司的Lightfoot和Zucotto公司的Xpresso都是协处理器。与解释器一样，这些协处理器往往作为用于ASIC或者FPGA实现的核心。 
</p>
		<p class="a14">第三种方式是利用硬件及时编译器高速编译Java字节码。这种设备有别于硬件解释器，它不仅仅把软件从一种形式转换成另一种形式，实际上还能够编译，包括进行优化、重新安排代码执行次序等。Parthus公司的MachStream就属于这一类。 
</p>
		<p class="a14">有了这一系列加快Java代码执行速度的软硬件方案，嵌入式系统的Java性能问题似乎可以得到解决了。遗憾的是，很难预测它们会给性能带来多大幅度的提升。加速器与其他系统单元的相互关系更是加大了预测难度。CPU架构、可用系统内存的数量、实时操作系统（RTOS）、JVM、类库和硬件加速都可能影响系统的最终性能，甚至应用软件也会对性能产生影响。例如适用于Internet设备的系统软硬件配置在机顶盒里面运行起来可能会比较慢，在移动电话上就完全不适合。 
</p>
		<p class="a14">遗憾的是，嵌入式设计师没有多少工具可以帮助自己测试非传统配置的性能。最有用的工具就是系统性能测试公司开发的SPEC JVM98基准测试。但SPEC JVM98不是为了满足嵌入式系统的测试需求，而是为联网和独立的客户机开发的，并且前提是假设完全实现了Java，并拥有完整的桌面系统环境，而很少有嵌入式系统拥有这么丰富的资源。 
</p>
		<p class="a14">Pendragon软件公司的CaffeineMark这个基准测试在嵌入式领域颇为流行。与Dhrystone MIPS基准测试一样,CaffeineMark也是一种人工基准测试，仅仅测试几项Java特性，不包括浮点运算、垃圾收集和多线程这些项目，而对这些嵌入式开发人员来说可能很重要。另外，没有标准配置可供基准测试来运行。因而，不同厂商的基准测试结果很难解读。 
</p>
		<p class="a14">对嵌入式Java而言，缺少测试工具问题也许不会长期存在。EDN嵌入式微处理器基准测试协会(EEMBC）已开始开发Java基准测试套件。EEMBC基准测试准备采用诸多系统测试指标，包括垃圾收集时间和确定性、I/O性能、中断时延、内存使用以及测试过程中的系统功耗。还会包括详细的软件执行基准测试，测试项目包括类加载时间、类方法执行、所用线程数量、每个线程所用时间、以及调用线程的时间。该协会计划在众多应用环境下进行基准测试，包括智能卡、移动电话、掌上设备、Internet设备和机顶盒。 
</p>
		<p class="a14">一旦这些工具准备到位，就可以根据预期应用来进行比较，从而大大方便了开发人员选择嵌入式Java的诸多方案、确保系统的最终性能能够达到预期。那样，Java可以在将来的嵌入式系统开发当中扮演主角。 </p>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/89072.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2006-12-20 16:26 <a href="http://www.blogjava.net/zhangzhong1018/articles/89072.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>J2ME开发入门专题系列之一：J2ME概述 （转）</title><link>http://www.blogjava.net/zhangzhong1018/articles/89071.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Wed, 20 Dec 2006 08:24:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/89071.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/89071.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/89071.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/89071.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/89071.html</trackback:ping><description><![CDATA[ 我们将从定义 J2ME 开始，从最简单的J2ME 是什么开始讲起。然后讨论它的总体架构并学习 J2ME 目标设备。作为架构讨论的一部分，我们将提供有关简表和配置的概述。同时我们会简要介绍打包和配置 J2ME 应用程序过程中的一些注意事项。
<p><strong>J2ME 是什么？</strong></p><p>    Sun Microsystems 将 J2ME 定义为“一种以广泛的消费性产品为目标的的高度优化的 Java 运行时环境，包括寻呼机、移动电话、可视电话、数字机顶盒和汽车导航系统。”</p><p>    自从 1999 年 6loper Conference 上声明之后，J2ME 为小型设备带来了 Java 语言的跨平台功能，允许移动无线设备共享应用程序。有了 J2ME，Sun 已经使 Java 平台能够适应集成了或基于小型计算设备月在 JavaOne Deve的用户产品。</p><p><strong>J2ME 总体架构</strong></p><p>    J2ME 使用配置和简表定制 Java 运行时环境 (JRE)。作为一个完整的 JRE，J2ME 由配置和简表组成，配置决定了使用的 JVM，而简表通过添加特定于域的类来定义应用程序。</p><p>    配置将基本运行时环境定义为一组核心类和一个运行在特定类型设备上的特定 JVM。我们将在 J2ME 配置一章中详细讨论配置。</p><p>    简表定义应用程序；特别地，它向 J2ME 配置中添加特定于域的类，定义设备的某种作用。我们将在 J2ME 简表一章中深入介绍简表。</p><p>    下面的图表描述了不同的虚拟机、配置和简表之间的关系。它同时把 J2SE API 和它的 Java 虚拟机进行了比较。虽然 J2SE 虚拟机通常被称为一种 JVM，但是 J2ME 虚拟机、KVM 和 CVM 都是 JVM 的子集。KVM 和 CVM 均可被看作是一种 Java 虚拟机 -- 它们是 J2SE JVM 的压缩版，并特定于 J2ME。<br /><img alt="" hspace="0" src="http://images.csdn.net/20050701/1.jpg" align="baseline" border="0" /></p><p><br /><strong>配置概述</strong><br /><br />     配置将基本运行时环境定义为一组核心类和一个运行在特定类型设备上的特定 JVM。虽然还可能在将来定义其他的配置，但当前 J2ME 存在两种配置：<br /><br />    1、连接限制设备配置 (CLDC) 特别与 KVM 一起用于内存有限的 16 位或 32 位设备。这是用于开发小型 J2ME 应用程序的配置（虚拟机）。（从开发者的角度来看）它的大小限制让它比 CDC 更有趣、更具挑战性。CLDC 同时还是用于开发绘图工具应用程序的配置。 Palm 电脑便是一个运行小应用程序的小型无线设备的示例。我们将在本转体的后续文章中深入介绍 CLDC。<br /><br />    2、连接设备配置 (CDC) 与 C 虚拟机 (CVM) 一起使用，用于要求内存超过 2 兆的 32 位体系结构。互联网电视机顶盒便是这类设备的一个示例。虽然稍后我们将在 CDC API 一章中简要介绍 CDC，但它并不在本教程的范围内。<br /><br /><strong>简表概述<br /></strong><br />    简表定义了您的应用程序所支持的设备类型。特别地，它向 J2ME 配置添加了特定于域的类来定义设备的某种作用。简表建立在配置的顶部。已经为 J2ME 定义了两种简表：KJava 和移动信息设备简表 (MIDP)，它们也被建立在 CDLC 上。这两种简表适用于小型设备。<br /><br />    有一种纲要简表，您可以在它的上面创建自己的简表，这种纲要简表也称为基础表，可供 CDC 使用。然而，在本教程中，我们只重点介绍建立在 CLDC 顶部，适用于小型设备的简表。我们将在后面的文章中讨论上述这些简表，还会使用 KJava 和 MIDP 建立一些示例应用程序。<br /><br /><strong>J2ME 目标设备<br /></strong><br />使用 CLDC 开发的 J2ME 应用程序的目标设备通常具有以下特征：<br /><br />可供 Java 平台使用的 160 到 512 千字节的总内存<br /><br />功率有限，常常是电池供电 <br /><br />网络连通性，常常是无线的、不一致的连接并且带宽有限<br /><br />用户接口混乱，程度参差不齐；有时根本就没有接口<br /><br />一些 CLDC 支持的设备，包括无线电话、寻呼机、主流个人数字助手 (PDA)，以及小型零售支付终端。<br /><br />依照 Sun Microsystems，CDC 的目标设备通常具有以下特征：<br /><br />使用 32 位处理器<br /><br />2 兆字节或更多可供 Java 平台使用的总内存 <br /><br />设备要求的 Java 2 “蓝皮书”虚拟机的全部功能 <br /><br />网络连通性，常常是无线的、不一致的连接并且带宽有限<br /><br />用户接口混乱，程度参差不齐；有时根本就没有接口<br /><br />一些 CDC 支持的设备，包括常驻网关、智能电话和通讯器、PDA、管理器、家用电器、销售网点终端以及汽车导航系统。<br /><br />J2ME、J2SE 与 J2EE 之间的比较<br /><br />下面的图表描述了支持 J2ME 应用程序的设备，同时说明了 J2ME 适合 Java 平台之处：<br /><img alt="" hspace="0" src="http://images.csdn.net/20050701/2.jpg" align="baseline" border="0" /></p><img src ="http://www.blogjava.net/zhangzhong1018/aggbug/89071.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2006-12-20 16:24 <a href="http://www.blogjava.net/zhangzhong1018/articles/89071.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何学好J2ME</title><link>http://www.blogjava.net/zhangzhong1018/articles/89070.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Wed, 20 Dec 2006 08:23:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/89070.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/89070.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/89070.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/89070.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/89070.html</trackback:ping><description><![CDATA[
		<ol>
				<li>具备良好的java语言基础，不要还没有学习java语言就拿起一本J2ME的书来看。这样效果并不好，相反如果你有良好的java语言基础的话，J2ME就显得比较容易掌握！ 
</li>
				<li>如果你决定开始学习J2ME了，那么首先你应该清楚J2ME的体系结构是什么样的。当你真正清楚了Configuration和Profile的关系、了解了CDC和CLDC的区别后，那么你可以开始编写自己的HelloWorldMIDlet了 
</li>
				<li>选择优秀的开发环境，J2ME的开发环境比较灵活。我推荐使用Eclipse和EclipseME插件。因为Eclipse的插件非常丰富且灵活，当你开发联网应用程序的时候安装Lomboz就可以了。当然你也可以选择Jbuilder等IDE，但是不推荐记事本！ 
</li>
				<li>在编写代码之前，应该多读一下好的代码。毕竟MIDlet的写法和一般的java Application不是很一样。推荐WTK中的Demo程序。 
</li>
				<li>MIDP的API doc比较少，每个类的方法也很少。如果有时间的话，每天看个4-5个。这会对你帮助很大。毕竟它的API和J2SE的并不一样，只是它的子集，不应该想当然的使用。 
</li>
				<li>清楚MIDP中高级UI和低级UI类的使用和区别，在你做用户界面的之前，思考好什么符合你的要求，推荐使用高级UI，这样更简单、可移植性更好。但是需要使用Canvas的时候不要犹豫，大胆使用！清楚高级事件和低级事件处理的机制。 
</li>
				<li>在开发应用程序的时候尽量使用MVC模式，这样扩展性出色。彻底掌握Record Management System，这是MIDP的一个重要子集。实现数据持久性存储不可缺少的系统。善于使用RecordFilter和RecordEnumeration来简化RMS的操作，在我的blog里面有一系列的关于RMS的文章，有时间就看看吧！ 
</li>
				<li>重视线程，如果你还不真正清楚线程的时候的话，那么赶快找资料看看吧。在J2ME的开发中，这非常的重要。具备了联网的能力则给你的应用程序插上了翅膀，而联网的时候为了避免堵塞一定要使用多线程技术。 
</li>
				<li>时刻关注最新的技术，比如PIM，BlueTooth等都在慢慢的得到支持。你可以使用WTK2.2开发相关的程序了。 
</li>
				<li>掌握Java中文问题，在J2ME中这个问题更加突出。你应该把你的应用程序放到手机上去测试这个问题而不是在模拟器上。 
</li>
				<li>IO不用我说你也必须清楚，在J2ME中提供的IO包中，类比较少你更应该注意。 
</li>
				<li>不要因为听说手机资源受限，在写程序的时候就顾虑重重，不要牺牲代码的可读性和可维护性，但是也不能乱用。这个时候你的java语言的基础起到了重要的作用！ 
</li>
				<li>如果想开发游戏，那么你应该多读相关的书籍。我这里一本J2ME游戏开发的书籍（电子版).想看的话可以email联系我,http://javap2p.nease.net/book/j2me_gamingbook_pdf.zip 
</li>
				<li>如果有些问题想了很久都没有明白的话，可以到论坛上去问问，但是不要一有问题就问，自己思考后得到正确答案效果更好。或者把问题放下几天，也许自然而然就明白了！不是胡说。 
</li>
				<li>多写代码!多多总结！简单的八个字，非常重要:)<br /></li>
		</ol>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/89070.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2006-12-20 16:23 <a href="http://www.blogjava.net/zhangzhong1018/articles/89070.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>精通J2ME中的Hello World（转载）</title><link>http://www.blogjava.net/zhangzhong1018/articles/89069.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Wed, 20 Dec 2006 08:22:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/89069.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/89069.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/89069.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/89069.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/89069.html</trackback:ping><description><![CDATA[
		<p>初学java的时候一般都写过如下的HelloWorld程序,今天我准备详细讲述一下J2ME中的HelloWorld。无论你是J2ME开发高手还是新手都应该读读这篇文章，我想它会对你有所帮助！</p>
		<p>      在javax.microedition.midlet包中定义了一个非常重要的类MIDlet，所有J2ME的应用程序都必须扩展这个类，只有这样才可以使得应用管理软件(Application Management Software)管理MIDlet,包括下载、安装和删除。在被AMS管理的同时，MIDlet可以和应用管理软件通信通知应用管理软件自己状态的变化，通常是通过方法notifyDestroyed()和notifyPaused()实现的。最后MIDlet还可以通过getAppProperty(String name)读取在jad文件中定义的属性值。</p>
		<p>      MIDlet有三个状态，分别是pause,active和destroyed。在启动一个MIDlet的时候，应用管理软件会首先创建一个MIDlet实例并使得他处于pause状态，当startApp()方法被调用的时候MIDlet进入active状态，也就是我们平时所说的运行状态。在active状态调用destroyApp(boolean unconditional)或者pauseApp()方法可以使得MIDlet进入destroyed或者pause状态。值得一提的是destroyApp(boolean unconditional)方法，很多开发者对unconditional参数不是很理解，事实上，当destroyApp()方法被调用的时候，AMS通知MIDlet进入destroyed状态。在destroyed状态的MIDlet必须释放了所有的资源，并且保存了数据。如果unconditional为false的时候，MIDlet可以在接到通知后抛出MIDletStateChangeException而保持在当前状态，如果设置为true的话，则必须立即进入destroyed状态。</p>
		<p>      下面是根据上述问题我编写的一个J2ME中的HelloWorld程序，他比j2se中的helloworld要复杂一点。新手可以仔细看看。<br />package com.j2medev.mingjava;</p>
		<p>import javax.microedition.midlet.MIDlet;<br />import javax.microedition.midlet.MIDletStateChangeException;<br />import javax.microedition.lcdui.*;</p>
		<p>public class HelloWorld extends MIDlet implements CommandListener<br />{<br />    private Display display;<br />    private Form mainForm;<br />    private StringItem stringItem;<br />    private Command exitCommand = new Command("Exit", Command.EXIT, 1);</p>
		<p>    public static final String WEB_SITE = "WEB_SITE";</p>
		<p>    protected void startApp() throws MIDletStateChangeException<br />    {</p>
		<p>        initMIDlet();<br />        display.setCurrent(mainForm);</p>
		<p>    }</p>
		<p>    private void initMIDlet()<br />    {<br />        display = Display.getDisplay(this);<br />        mainForm = new Form("Hello World");<br />        stringItem = new StringItem(null, null);<br />        String text = getAppProperty(WEB_SITE);<br />        stringItem.setText(text);<br />        mainForm.append(stringItem);<br />        mainForm.addCommand(exitCommand);<br />        mainForm.setCommandListener(this);<br />    }</p>
		<p>    protected void pauseApp()<br />    {</p>
		<p>    }</p>
		<p>    protected void destroyApp(boolean arg0) throws MIDletStateChangeException<br />    {<br />        System.out.println("exit the application");<br />    }</p>
		<p>    public void commandAction(Command cmd, Displayable display)<br />    {<br />        if (cmd == exitCommand)<br />        {<br />            try<br />            {<br />                destroyApp(false);<br />                notifyDestroyed();<br />            } catch (MIDletStateChangeException e)<br />            {<br />                e.printStackTrace();<br />            }<br />        }<br />    }</p>
		<p>}</p>
		<p>HelloWorldMIDlet.jad文件内容如下，如果你还不是很清楚jad文件请参考MIDP中的属性问题。尤其是当你在安装MIDlet到手机上的时候。</p>
		<p>MIDlet-Jar-Size: 2128<br />MIDlet-1: HelloWorld,/icon.png,com.j2medev.mingjava.HelloWorld<br />MIDlet-Jar-URL: HelloWorldMIDlet.jar<br />MicroEdition-Configuration: CLDC-1.0<br />MIDlet-Version: 1.0.0<br />MIDlet-Name: HelloWorldMIDlet<br />MIDlet-Vendor: <a href="http://www.j2medev.com/"><font color="#3f87d7">www.j2medev.com</font></a><br />MicroEdition-Profile: MIDP-1.0<br />WEB_SITE: <a href="http://www.j2medev.com/"><font color="#3f87d7">www.j2medev.com</font></a></p>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/89069.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2006-12-20 16:22 <a href="http://www.blogjava.net/zhangzhong1018/articles/89069.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转载 J2ME程序开发全方位基础讲解汇总 （http://blog.csdn.net/Mailbomb/）</title><link>http://www.blogjava.net/zhangzhong1018/articles/89068.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Wed, 20 Dec 2006 08:20:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/89068.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/89068.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/89068.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/89068.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/89068.html</trackback:ping><description><![CDATA[
		<p>一、J2ME中需要的Java基础知识<br />       现在有大部分人，都是从零开始学J2ME的，学习J2ME的时候，总是从Java基础开始学习，而且现在讲Java基础的书籍中都是以J2SE来讲基础，这就给学习造成了一些不必要的麻烦，下面将J2ME中用到的和不需要的Java基础知识做一个简单的说明。<br />       J2ME中使用到的Java基础知识：<br />　　  1、Java语法基础：包括基本数据类型、关键字、运算符等等<br />　　  2、面向对象的思想：类和对象的概念，继承和多态等等。<br />　　  3、异常处理<br />　　  4、多线程<br />　　J2ME中没有用到的Java基础知识：<br />　　  1、JDK中javac和java命令的使用<br />　　  2、Java基础中的很多类在J2ME中没有，或者类中的方法做了大量的精简。所以建议在J2ME中熟悉类库。<br />　　  3、Applet、AWT、Swing这些知识在J2ME中根本使用不到。<br />　　简单说这么多，希望学J2ME的朋友们能少走一些弯路，不足之处希望大家积极指正和补充。</p>
		<p>二、J2ME中暂时无法完成的功能<br />　　列一些J2ME中暂时无法完成的功能，希望大家能积极补充：<br />　　  1、在手机中不更改代码实现移植，主要指游戏。<br />　　  2、动态修改按钮文字。<br />　　  3、在Canvas上接受中文输入。<br />　　  4、操作本地资源、例如地址本、已收短信息等。<br />　　  5、制作破坏性的手机病毒。<br />　　  6、其他等待大家来补充。</p>
		<p>三、J2ME的跨平台性<br />　　J2ME技术源于Java，所以也具有JVM的优势，可以在支持Java的平台上进行移植，但是现在的J2ME技术在跨平台上却做的很糟糕，我们来简单看一下原因：<br />　　1、手机的屏幕尺寸不一：<br />　　这个主要在界面制作上。如果你使用的是高级用户界面，比如你做的是应用开发或者用户登陆、用户注册这样的通用功能时，一般没有什么问题。<br />　　如果你使用的是低级用户界面，比如你做的是游戏，那么你就需要考虑这个问题了。<br />　　2、厂商的扩展API不统一：<br />　　例如Nokia的扩展API类库UI系列，在别的手机上或者没有实现，或者包名不同等等。<br />　　3、手机平台上实现的bug：<br />　　例如Nokia的7650在实现双缓冲上有bug，那么在这种机型上运行的软件就不能使用双缓冲。其他NOKIA上的一些bug，可以参看：<a href="http://blog.csdn.net/Mailbomb/archive/2005/03/24/329123.aspx">http://blog.csdn.net/Mailbomb/archive/2005/03/24/329123.aspx</a><br />　　4、手机性能问题。<br />　　不同手机的可用内存、最大jar文件都有要求，例如Nokia S40的大部分手机支持的最大jar文件为64K，最大可用内容为210K。<br />　　所以现在的手机软件，特别是游戏都提供支持的机型列表，也才有了手机游戏移植人员的存在。</p>
		<p>四、学习J2ME可以从事的工作种类<br />　　现在J2ME技术可以说相当的火暴，这里介绍一些学好了J2ME之后可以从事的工作的种类：<br />　　1、J2ME游戏开发人员<br />　　根据游戏策划或者文档要求，在某种特定的机型(以Nokia S40或S60居多)开发游戏程序。<br />　　这是现在大部分J2ME程序员从事的工作。<br />　　需要熟练掌握：高级用户界面、低级用户界面、线程，如果是网络游戏，还需要熟练网络编程。<br />　　2、J2ME应用开发人员<br />　　现在的移动应用还不是很多，但是还是出现了一些，特别是移动定位以及移动商务相关的内容。<br />　　需要熟练掌握：高级用户界面、线程和网络编程。<br />　　3、J2ME游戏移植人员<br />　　参照源代码，将可以在一个平台上可以运行的游戏移植到其他平台上去。例如将Nokia S40的游戏移植到S60上，或者索爱的T618等等。<br />　　主要是控制屏幕坐标，有些可能需要替换一些API。<br />　　需要熟悉各平台之间的差异以及相关的技术参数，比如屏幕大小、最大jar文件尺寸等等。</p>
		<p>五、J2ME程序设计的几个原则<br />　　1、使用面向对象编程。<br />　　虽然使用面向过程编程可以减小文件的尺寸，但是为了以后维护的方便和利于扩展，还是要使用面向对象编程。<br />　　2、使用MVC模式<br />　　将模型、界面和控制分离。现在很多的程序将三者合一，但是如果你做的程序比较大的话，还是建议你进行分离。<br />　　3、自动存储用户设定<br />　　使用RMS来存储用户的信息，例如存储用户上次输入的用户名、密码、用户对于系统的设定等，这样不仅可以减少用户的输入，而且对用户友好。很多程序甚至做了自动登陆等。<br />　　4、一些系统设置允许用户关闭。如背景音乐、背景灯显示等。<br />　　5、将低级用户界面的绘制动作放在一个独立的线程里面去。<br />　　6、在需要大量时间才能完成的工作时，给用户一个等待界面。</p>
		<p>六、从模拟器到真机测试<br />　　对于J2ME开发者来说，模拟器给我们带来了很多方便，比如可以在模拟器中调试程序以及很方便的察看程序的效果，但是模拟器也给我们带来了一些问题，比如模拟器实现的bug等等，所以进行真机测试是必须的。<br />　　1、为什么要进行真机测试？<br />　　因为模拟器程序可能存在bug，以及真机的性能有限，所以必须进行真机测试。<br />　　2、如何将程序传输到机器中？<br />　　将程序传输到机器中有如下方式：<br />　　  a)　OTA下载<br />　　  b)　使用数据线传输<br />　　  c)　红外传输<br />　　  d)　蓝牙<br />　　你可以根据条件，选择合适的方式。<br />　　3、 真机测试主要测什么？<br />　　真机测试的内容很多，主要测试以下几个方面：<br />　　  a)　程序的功能<br />　　  b)　程序的操作性，是否易操作<br />　　  c)　程序的大小,比如Nokia S40系列的手机大部分接受的最大文件尺寸为64K<br />　　  d)　程序运行速度，速度是否可以忍受。</p>
		<p>七、从WTK到厂商SDK<br />　　对于J2ME爱好者来说，基本上大家都是从SUN的WTK(J2ME Wireless Toolkit)开始的，但是对于实际应用来说，仅仅使用WTK是远远不够的，所以在学习过程中，必须完成从WTK到SDK的跨越。<br />　　1、厂商SDK的下载地址？<br />　　<a href="http://blog.csdn.net/Mailbomb/archive/2005/01/01/236606.aspx">http://blog.csdn.net/Mailbomb/archive/2005/01/01/236606.aspx</a><br />　　2、厂商SDK和WTK有什么不同？<br />　　厂商SDK最简单的理解就是在WTK的基础上增加了自己的模拟器和自己的扩展API。<br />　　也就是说，你在使用厂商的SDK时，可以使用厂商的扩展类库，例如Nokia的UI类库，和厂商自己的模拟器而已。<br />　　每个厂商的扩展API都不多，而且不尽相同。<br />　　3、如何使用？<br />　　有些厂商SDK的使用都和WTK相同，例如SamSung。<br />　　Nokia提供了独立的界面来开发，但是这个界面在实际开发中使用不多。<br />　　4、厂商SDK的问题<br />　　厂商SDK实现过程中，有一些bug，而且和真机实现不一致。例如NOKIA的混音播放问题等等。</p>
		<p>八、在J2ME中获得手机IMEI的方法<br />　　IMEI是Internation mobile entity identification的简称，在手机中输入*#06#可以显示该数字，长度为15位，全球唯一，永远不会冲突，所以可以作为识别用户的一个标志。<br />　　下面是在J2ME中获得IMEI的方法：<br />　　1、MOTO系列的手机可以通过读取系统的IMEI属性获得，代码如下：<br />　　           String imei = System.getProperty("IMEI");<br />　　2、SIEMENS系列的手机可以通过读取系统的com.siemens.IMEI属性获得，代码如下：<br />　　           String imei = System.getProperty("com.siemens.IMEI");</p>
		<p>九、J2ME网络连接中显示问题的解决办法<br />　　在网络编程中，有些时候会出现一些在没有接收到网络数据就显示界面的，造成界面显示不符合要求（例如公告显示，会先显示公告的背景图片再显示公告信息），这里提一个简单的解决办法给大家：<br />　　解决这种情况的方法分成三个步骤：<br />　　1、在需要显示的界面中，调用发送网络数据的方法。每次显示时调用该构造方法，不调用Display的setCurrent方法显示。<br />　　2、显示等待界面(例如进度条等)，给用户提示，在进行网络连接。<br />　　3、在处理网络反馈的数据完以后，调用Display的setCurrent方法显示显示当前界面。</p>
		<p>十、增强J2ME的String能力——分割字符串<br />　　从JDK1.4以后，String类中新增了split方法来实现字符串的分割，但是在J2ME中却没有该方法(MIDP2.0中也没有实现)，但是在实际使用过程中，有些时候的确要用到这种操作，这里将我以前实现的一段代码和大家共享：<br />/**<br />* 分割字符串，原理：检测字符串中的分割字符串，然后取子串<br />* @param original 需要分割的字符串<br />* @paran regex 分割字符串<br />* @return 分割后生成的字符串数组<br />*/</p>
		<p>private static String[] split(String original,String regex)<br />{<br />     //取子串的起始位置<br />     int startIndex = 0;<br />     //将结果数据先放入Vector中<br />     Vector v = new Vector();<br />     //返回的结果字符串数组<br />     String[] str = null;<br />     //存储取子串时起始位置<br />     int index = 0;</p>
		<p>     //获得匹配子串的位置<br />     startIndex = original.indexOf(regex); <br />     //System.out.println("0" + startIndex); <br />     //如果起始字符串的位置小于字符串的长度，则证明没有取到字符串末尾。<br />     //-1代表取到了末尾<br />     while(startIndex &lt; original.length() &amp;&amp; startIndex != -1)<br />     {<br />           String temp = original.substring(index,startIndex);<br />           System.out.println(" " + startIndex);<br />           //取子串<br />           v.addElement(temp);</p>
		<p>           //设置取子串的起始位置<br />           index = startIndex + regex.length();</p>
		<p>           //获得匹配子串的位置<br />           startIndex = original.indexOf(regex,startIndex + regex.length());<br />     }</p>
		<p>     //取结束的子串<br />     v.addElement(original.substring(index + 1 - regex.length()));<br />     //将Vector对象转换成数组<br />     str = new String[v.size()];<br />     for(int i=0;i <br />     {<br />          str[i] = (String)v.elementAt(i);<br />     }<br />     <br />     //返回生成的数组<br />     return str;<br />}</p>
		<p>十一、J2ME在低级用户界面上分行显示文字<br />　　在J2ME的低级用户界面开发中，经常会遇到需要在Canvas上显示大量的文字，例如关于界面、游戏说明、游戏公告等信息。如果在设计时，将文字的内容和长度都固定，既不利于修改也不利于维护。下面介绍一个简单的方法，实现一个简单、可维护性强的方式。<br />　　实现方法：<br />　　  1、将需要显示的所有信息做成一个字符串。<br />　　  2、编写一个将该字符串按照要求转换为字符串数组的方法。<br />　　  3、将转换后的数组以循环的方式显示在Canvas上。<br />　　通过这样三个步骤，则修改显示的信息时，只需要修改包含显示信息的字符串即可，自己书写的方法可以按照以前的标准重新分割新的字符串。如果需要修改每行显示的字符个数，则只需要修改自己书写的方法即可。<br />　　通过这样一种实现方式，可以很方便的实现显示一些比较长的文本信息，即使是可变长度的字符串也没有问题。</p>
		<p>十二、J2ME中使用记录存储系统(RMS)存储信息<br />　　在MIDP中，没有文件的概念，所以永久存储一般只能依靠记录存储系统实现，关于记录存储系统的简介，可以参看教程：<a href="http://www-900.ibm.com/developerWorks/cn/java/j-wi-rms/index.shtml">http://www-900.ibm.com/developerWorks/cn/java/j-wi-rms/index.shtml</a><br />　　下面是一些记录存储系统的常用编码介绍：<br />　　  1、打开记录集：<br />　　打开记录集使用RecordStore里面的静态方法openRecordStore，示例代码如下：<br />          RecordStore rs = RecordStore.openRecordStore(“username”,true);<br />　　这样就打开了一个名称为rs的记录集，其中username为记录集的名称，该名称可以根据需要来取，第二个参数代表是否则没有时创建新的记录集，true代表在该记录集不存在时，创建新的记录集，false代表不创建。<br />　　如果在打开记录集时，该记录集不存在，则抛出RecordStoreNotFoundException异常，所以检测记录集是否已创建可以使用该异常。<br />　　注意：记录集打开以后记得关闭。<br />　　  2、向记录集中写入数据<br />　　      2.1增加数据<br />　　向已经打开的记录集中添加数据，需要使用addRecord方法，示例代码：<br />                 byte[] bytes = {1,2,3};<br />　　           int id = rs. addRecord(bytes,0,bytes.length);<br />　　该代码将字节数组bytes的全部内容写入到记录集中，该方法的返回值为该信息的id，注意：id从1开始，而不是从0开始。<br />　　你可以循环使用该方法向记录集中写入多条数据。<br />　　      2.2修改数据<br />　　修改已经存在的记录集中指定id的数据，需要使用setRecord方法，示例代码：<br />                 byte[] bytes = {1,2,3};<br />　　           rs. setRecord(1,bytes,0,bytes.length);<br />　　以上代码的作用是将字节数组bytes的全部内容写入到id为1的记录集rs中。<br />　　该操作会覆盖已有的数据。<br />　　说明：有些时候，你需要将信息写入到记录集中的第一条记录中，则可以结合以上两个方法，则第一次时向记录集增加数据，以后来进行修改。<br />　　  3、从记录集中读出数据<br />　　从记录集中读取已有数据，需要使用getRecord方法，示例代码：<br />            byte[] bytes = rs. getRecord(1);<br />　　该代码从记录集rs中读取第一条数据，将读取到的数据放在bytes数组中。<br />　　在读取数据时，可以获得记录集中id的个数，可以使用getNumRecords方法获得<br />　　综合代码为：<br />       int number = rs. getNumRecords();<br />       int id = 1;<br />       if(id &gt;0 &amp;&amp; id &lt; number)<br />       {<br />　　     byte[] bytes = rs. getRecord(1);<br />       }<br />　　  4、从记录集中删除记录<br />　　从记录集中删除记录的方法有两种：逻辑删除和物理删除。<br />　　逻辑删除是指给删除的记录打标记。<br />　　物理删除是指从物理上删除该记录，但是该记录的id不能被重用，也就是说该id不会被继续使用。例如一个记录集中有5个记录，假设你删除了id为3的数据，则剩余记录的id依然为1、2、4、5。这给便历带来了一定的麻烦。<br />　　  5、便历记录集<br />　　便历记录集，即访问记录集中的所有数据，有两个方法，详见：<br /><a href="http://gceclub.sun.com.cn/NASApp/sme/controller/teclist?tid=0103">http://gceclub.sun.com.cn/NASApp/sme/controller/teclist?tid=0103</a><br />　　  6、其他操作<br />　　删除记录集<br />　　删除记录集不同于删除记录，需要使用deleteRecordStore方法，示例代码：           <br />                RecordStore. deleteRecordStore(“username”);<br />　　该代码删除名称为username的记录集。</p>
		<p>十三、J2ME加密数据的一个第三方开源免费类库介绍<br />　　在J2ME编程中，经常遇到一些数据在存储或者传输时需要加密，下面介绍一个第三方的加密类库的一些资料：<br />　　加密类库的官方主页：<a href="http://www.bouncycastle.org/">http://www.bouncycastle.org/</a><br />　　介绍的文章：<br />　　中文：<a href="http://18900.motorola.com/ewa_portal/develope/jc_j2messl_5_1.jsp">http://18900.motorola.com/ewa_portal/develope/jc_j2messl_5_1.jsp</a><br />　　英文：<a href="http://www.javaworld.com/javaworld/jw-12-2002/jw-1220-wireless.html">http://www.javaworld.com/javaworld/jw-12-2002/jw-1220-wireless.html</a><br />　　该文章的源代码包含使用的一些方法。<br />　　备注：因为该类库提供的功能比较强大，所以类库的尺寸比较大，最后在发布时需要将类库中不需要的类删除</p>
		<p>十四、如何播放声音<br />　　在J2ME中，处理声音需要使用到Mobile Media API(MMAPI)，该包是MIDP1.0的可选包，在MIDP2.0中已经包含了这个包。所以如果你使用MIDP1.0的话，请确认你的运行环境是否支持。<br />　　一般手机支持的声音文件格式为wav、mid和mpg等。具体请查阅你的手机说明文档。<br />　　在声音处理中，有很多处理的方式，这里说一下最常用的情况，播放JAR文件中的wav文件。<br />　　播放声音文件的流程：<br />　　  1、按照一定的格式读取声音文件。<br />　　播放JAR文件中的声音文件一般是将声音文件处理成流的形式。示例代码：<br />             InputStream is = this.getClass().getResourceAsStream("/Autorun.wav");<br />       其中Autorun.wav文件位于JAR文件的根目录下，如果位于别的目录，需要加上目录名称，如/res /Autorun.wav。<br />　　  2、将读取到的内容传递给播放器。<br />　　将流信息传递给播放器，播放器按照一定的格式来进行解码操作，示例代码：<br />             Player player = Manager.createPlayer(is,"audio/x-wav");<br />　　其中第一个参数为流对象，第二个参数为声音文件的格式。<br />　　  3、播放声音。<br />　　使用Player对象的start方法，可以将声音播放出来，示例代码：<br />             player.start()；<br />　　在播放声音时也可以设定声音播放的次数，可以使用Player类中的setLoopCount方法来实现，具体可查阅API文档。<br />　　下面是在NOKIA S60模拟器中测试通过。代码如下：<br />package sound;<br />import javax.microedition.midlet.*;<br />import javax.microedition.lcdui.*;<br />import javax.microedition.media.*;<br />import java.io.*;</p>
		<p>public class SoundMIDlet extends MIDlet <br />{<br />　　private Player player = null;<br />　　/** Constructor */<br />　　public SoundMIDlet() <br />       {<br />             try<br />             {<br />                   InputStream is = this.getClass().getResourceAsStream("/Autorun.wav");<br />                   player = Manager.createPlayer(is,"audio/x-wav");<br />             }<br />             catch(IOException e)<br />             {<br />                   System.out.println("1:" + e);<br />             }<br />             catch(MediaException e)<br />             {<br />                   System.out.println("2:" + e);<br />             }<br />             catch(Exception e)<br />             {<br />                   System.out.println("3:" + e);<br />             }<br />      }</p>
		<p>      /** Main method */<br />      public void startApp() <br />      {<br />             if(player != null)<br />             {<br />                   try<br />                   {<br />　　　　          player.start();<br />                   }<br />                   catch(MediaException e)<br />                   {<br />　　　　          System.out.println("4:" + e);<br />                   }<br />             }<br />       }</p>
		<p>       /** Handle pausing the MIDlet */<br />       public void pauseApp() <br />       {<br />       }</p>
		<p>       /** Handle destroying the MIDlet */<br />       public void destroyApp(boolean unconditional) <br />       {<br />       }<br />}</p>
		<p>十五、J2ME 3D编程的一些资料<br />　　随着J2ME技术的发展，以及硬件速度的提升，3D游戏程序将慢慢的变成主流，最近想学习这一块的编程，所以收集了一些资料，和大家一起分享：<br />　　1、JSR184<br />　　JSR184是Nokia公司起草的一个关于3D API的规范，下载地址为：<br />　　<a href="http://www.forum.nokia.com/main/1,,1_0_10,00.html#jsr184">http://www.forum.nokia.com/main/1,,1_0_10,00.html#jsr184</a><br />　　2、Nokia的3D编程资料<br />　　<a href="http://www.forum.nokia.com/main/1,6566,21,00.html">http://www.forum.nokia.com/main/1,6566,21,00.html</a><br />　　3、3D引擎<br />　　一个简单的开放源代码的3D游戏引擎<br />　　<a href="http://www.j2me.com.cn/Soft_Show.asp?SoftID=19">http://www.j2me.com.cn/Soft_Show.asp?SoftID=19</a><br />　　国内一个合作开发3D引擎的项目：<br />　　<a href="http://gceclub.sun.com.cn/NASApp/sme/jive/thread.jsp?forum=11&amp;thread=8593">http://gceclub.sun.com.cn/NASApp/sme/jive/thread.jsp?forum=11&amp;thread=8593</a><br />　　4、一款3D游戏产品<br />　　<a href="http://games.sina.com.cn/newgames/2004/04/040217696.shtml">http://games.sina.com.cn/newgames/2004/04/040217696.shtml</a><br />　　5、支持3D的开发工具<br />　　当前一些高端的手机支持3D开发，支持3D开发的开发工具中，通用的有SUN的J2MEWTK2.2。专用的是厂商提高的支持JSR184的SDK。</p>
		<p>十六、3D编程——第一个3D程序<br />　　参考WTK2.2提供的demo，完成了第一个3D程序，虽然很简单，而且有些问题还不是很清楚，还是把代码共享出来和愿意学习J2ME 3D编程的朋友一起学习。<br />　　关于代码的编译和运行说明如下：<br />　　1、以下代码在J2ME WTK2.2下面编译通过。<br />　　2、代码分为两个文件：First3DCanvas.java和First3DMIDlet.java。<br />　　3、使用J2ME WTK2.2建立新的工程，主MIDlet类为：first3d. First3DMIDlet<br />　　4、将代码保存在你的工程目录下的first3d目录下。<br />　　5、将J2ME WTK安装目录下的apps\Demo3D\res\com\superscape\m3g\wtksamples\retainedmode\content目录中的swerve.m3g文件复制到你的工程目录下的res目录下。<br />　　6、你的工程建立后，设置工程，通过WTK界面中的“设置”按钮打开设置窗口，在“API选择”中，设置“目标平台”为：自定义；“简档”为“MIDP2.0”；“配置”为“CLDC1.1”；选中“Mobile 3D Graphics for J2ME(JSR184)”。<br />　　7、这样你就可以编译和运行以下代码了。<br />　　源代码如下： </p>
		<p>// First3DMIDlet.java<br />package first3d;<br />import javax.microedition.midlet.*;<br />import javax.microedition.lcdui.*;<br />public class First3DMIDlet extends MIDlet <br />{<br />      private First3DCanvas displayable = new First3DCanvas();<br />      public void startApp() <br />      {<br />            Display.getDisplay(this).setCurrent(displayable);<br />      }</p>
		<p>      public void pauseApp() {}</p>
		<p>      public void destroyApp(boolean unconditional) {}<br />}</p>
		<p>// First3Dcanvas.java<br />package first3d;<br />import javax.microedition.lcdui.*;<br />import javax.microedition.m3g.*;<br />import java.util.*;<br />/**<br />* 第一个3D程序<br />*/<br />public class First3DCanvas extends Canvas implements Runnable <br />{<br />      /**World对象*/<br />      private World myWorld = null;<br />      /**Graphics3D对象*/<br />      private Graphics3D g3d = Graphics3D.getInstance();<br />      /**Camera对象*/<br />      private Camera cam = null;<br />      private int viewport_x;<br />      private int viewport_y;<br />      private int viewport_width;<br />      private int viewport_height;<br />      private long worldStartTime = 0;<br />      //重绘时间<br />      private int validity = 0;<br />      <br />      public First3DCanvas() <br />      {<br />            //启动重绘界面的线程<br />            Thread thread = new Thread(this);<br />            thread.start();<br />            try <br />            {<br />                   //导入3D图片<br />                   myWorld = (World) Loader.load("/swerve.m3g")[0];<br />                   viewport_x = 0;<br />                   viewport_y = 0;<br />                   viewport_width = getWidth();<br />                   viewport_height = getHeight();<br />                   cam = myWorld.getActiveCamera();<br />                   //设置cam对象<br />                   float[] params = new float[4];<br />                   int type = cam.getProjection(params);<br />                   if (type != Camera.GENERIC) <br />                   {<br />                          //calculate window aspect ratio<br />                          float waspect = viewport_width / viewport_height;<br />                          if (waspect &lt; params[1]) <br />                          {<br />                                float height = viewport_width / params[1];<br />                                viewport_height = (int) height;<br />                                viewport_y = (getHeight() - viewport_height) / 2;<br />                          }<br />                          else <br />                          {<br />                                float width = viewport_height * params[1];<br />                                viewport_width = (int) width;<br />                                viewport_x = (getWidth() - viewport_width) / 2;<br />                          }<br />                   }<br />                   worldStartTime = System.currentTimeMillis();<br />            }<br />            catch (Exception e) {}<br />      }<br />      <br />      protected void paint(Graphics g) <br />      {<br />            //清除背景<br />            g.setColor(0x00);<br />            g.fillRect(0, 0, getWidth(), getHeight());<br />            //和3D对象绑定<br />            g3d.bindTarget(g);<br />            g3d.setViewport(viewport_x, viewport_y, viewport_width, viewport_height);<br />            long startTime = System.currentTimeMillis() - worldStartTime;<br />            validity = myWorld.animate((int)startTime);<br />            try <br />            {<br />                   g3d.render(myWorld);<br />            }<br />            finally <br />            {<br />                   g3d.releaseTarget();<br />            }<br />      }</p>
		<p>      public void run() <br />      {<br />            try<br />            {<br />                   while(true)<br />                   {<br />                         //重绘图形<br />                         repaint(viewport_x, viewport_y, viewport_width, viewport_height);<br />                   }<br />            }<br />            catch(Exception e){}<br />      }<br />}</p>
		<p>十七、在J2ME网络编程中使用CMWAP代理<br />　　在中国移动提供的网络连接中，分为CMNET和CMWAP两种，其中CMNET可以无限制的访问互联网络，资费比较贵。CMWAP类似一个HTTP的代码，只能访问支持HTTP的应用，但是资费便宜，稳定性比较差。<br />　　在实际的J2ME网络编程中，一般需要提供以CMWAP代理的方式连接网络，在J2ME中，连接的代码和直接连接有所不同，代码如下：<br />             HttpConnection http = (HttpConnection)Connector.open(("<a href="http://10.0.0.172/&quot;+url">http://10.0.0.172/"+url</a>);<br />             http.setRequestProperty("X-Online-Host",ServerName);<br />　　例如你需要访问的地址为：<a href="http://www.test.com/login/loginServlet">http://www.test.com/login/loginServlet</a>则上面的代码就为：<br />             HttpConnection http = (HttpConnection)Connector.open(("<a href="http://10.0.0.172/">http://10.0.0.172/</a>" + "login/loginServlet");<br />             http.setRequestProperty("X-Online-Host","<a href="http://www.test.com/">www.test.com</a>");<br />　　在实际使用过程中，只需要使用实际需要访问的地址的域名或者IP来代替ServerName，例如示例中的“www.test.com”，使用后续的地址类代替代码中的url，例如示例中的“login/loginServlet”，就可以实际的使用CMWAP代理来进行连接了。</p>
		<p>十八、J2ME中的时间处理全攻略<br />　　时间处理在程序开发中相当常见，下面对于时间处理做一个简单的说明。<br />　　一、时间的表达方式<br />　　时间在J2ME中有两种表达方式：<br />　　1、以和GMT1970年1月1号午夜12点和现在相差的毫秒数来代表<br />　　这种方式适合比较两个时间之间的差值。<br />　　2、以对象的形式来表达<br />　　二、时间处理的相关类<br />　　时间处理在J2ME中涉及三个类：<br />　　1、System类<br />　　 long time = System. currentTimeMillis();<br />　　使用该方法可以获得当前时间，时间的表达方式为上面提到的第一种。<br />　　2、Date类<br />　　 Date date = new Date();<br />　　获得当前时间，使用对象的形式来进行表达。<br />　　3、Calendar类<br />　　 Calendar calendar = Calendar. getInstance();</p>
		<p>三、时间处理的具体操作<br />　　1、以上三种表达方式的转换：<br />　　a)将System类获得的时间转换为Date对象<br />　　 Date date = new Date(System. currentTimeMillis());<br />　　b)将Date类型的对象转换为Calendar类型的对象<br />　　 Calendar calendar = Calendar. getInstance();<br />　　 Date date = new Date();<br />　　 calendar.setTime(date);<br />　　2、使用Calendar完成一些日期操作：<br />　　Calendar是时间处理中最常用也是功能最强大的类，可以用它来获得某个时间的日期、星期几等信息。<br />　　获得日期：<br />　　 Calendar calendar = Calendar. getInstance();<br />　　 ……<br />　　 int day = calendar.get(Calendar. DATE);<br />　　获得日期、年份、星期的操作和这个类似。<br />　　需要注意的是：Calendar中表示月份的数字和实际相差1，即1月用数字0表示，2月用数字1表示，……12月用数字11表示。</p>
		<p>十九、J2ME中随机数字处理全攻略<br />　　在程序中生成随机数字，用处比较，如人工智能领域等等，这里对于在J2ME中生成随机数的操作进行一个简单的整理，希望对大家能有帮助。<br />　　J2ME和J2SE不同，不能使用Math类的random来生成随机数字，只能使用java.util包的Random类来生成随机数字。<br />　　1、创建Random类型的对象：<br />         Random random = new Random();<br />　　 Random random = new Random(10010010);<br />　　以上两种是创建Random对象的方式，第一种使用默认构造方法，和以下的代码作用完全等价：<br />　　 Random random = new Random(System. currentTimeMillis());<br />　　相当与使用当前时间作为种子数字来进行创建。<br />　　第二种方式通过自己来指定种子数字来进行创建。<br />　　大家可以根据需要使用以上两种方式的任一种。<br />　　2、生成随机数字：<br />　　创建好了随机对象以后，我们就可以来生成随机数字了：<br />　　生成随机整数：<br />         int k = random.nextInt();<br />       生成随机长整数：<br />         long l = random.nextLong();<br />　　3、生成指定范围的数字：<br />　　例如生成0-10之间的随机数字：<br />         int k = random.nextInt();<br />　　 int j = Math.abs(k % 10);<br />　　首先生成一个随机整数k，然后用k和10取余，最后使用Math类的abs方法取绝对值，获得0-10之间的随机数字。<br />　　获得0-15之间的随机数，类似：<br />         int k = random.nextInt();<br />　　 int j = Math.abs(k % 15);<br />　　获得10-20之间的随机数字：<br />         int k = random.nextInt();<br />　　 int j = Math.abs(k % 10) + 10;</p>
		<p>二十、在J2ME手机编程中使用字体<br />　　在J2ME手机编程中，可以通过使用字体类——Font在低级用户界面中，获得更好的表现效果，那么如何使用Font类呢？<br />　　首先，由于手机设备的限制，手机中支持的字体类型很有限，所以在J2ME中只能使用手机支持的默认字体来构造Font类对象。下面是创建Font类的对象时使用的方法：<br />          getFont(int face,int style,int size);<br />例如：<br />          Font font = Font.getFont(Font.FACE_SYSTEM,Font.STYLE_BOLD,Font. SIZE_MEDIUM);<br />　　无论哪一个参数，都只能使用系统设置的数值，这些数值具体的大小在不同的手机上可能不同。下面对于其中的三个参数的取值做详细的介绍：<br />　　face参数指字体的外观，其的取值：<br />　　FACE_MONOSPACE——等宽字体<br />　　FACE_PROPORTIONAL——均衡字体<br />　　FACE_SYSTEM——系统字体<br />　　style参数指字体的样式，其的取值：<br />　　STYLE_BOLD——粗体<br />　　STYLE_ITALIC——斜体<br />　　STYLE_PLAIN——普通<br />　　STYLE_UNDERLINED——下划线<br />　　STYLE_BOLD | STYLE_ITALIC——粗斜体<br />　　STYLE_UNDERLINED | STYLE_BOLD——带下划线粗体<br />　　STYLE_UNDERLINED | STYLE_ITALIC——带下划线斜体<br />　　STYLE_UNDERLINED | STYLE_ITALIC | STYLE_BOLD——带下划线的粗斜体<br />　　size参数指字体的大小，其的取值：<br />　　SIZE_SMALL——小<br />　　SIZE_MEDIUM——中<br />　　SIZE_LARGE——大<br />　　通过上面的参数的值，可以组合出你需要的字体对象。<br />　　下面是一些常用的字体操作：<br />　　1. 获得系统的默认字体：<br />          Font font = Font.getDefaultFont();<br />　　2. 在panit方法内部，假设Graphics参数的名称为g，则获得当前字体的方法是：<br />          Font font = g.getFont();<br />　　3. 在panit方法内部，假设Graphics参数的名称为g，则设置当前字体的方法是：<br />          g.setFont(font);<br />　　其中font为你构造好的字体对象。<br />　　4. 在MIDP2.0中，List可以设置每行的字体格式，方法是：<br />          list.setFont(0,font);<br />　　则上面的代码是将list中的第一行设置为font类型的字体。</p>
		<p>二十一、在J2ME手机程序开发中使用颜色<br />　　在J2ME手机开发过程中，需要经常用到颜色来进行绘制，增强程序的表现效果，下面就介绍一下如何使用颜色。<br />　　由于J2ME技术比较简单，所以没有实现专门的颜色类，而只是使用RGB的概念来代表颜色。这里简单介绍一下RGB的概念，颜色是由红(Red)、绿(Green)、蓝(Blue)三原色组成的，所以可以使用这三个颜色的组合来代表一种具体的颜色，其中R、G、B的每个数值都位于0-255之间。在表达颜色的时候，即可以使用三个数字来表达，也可以使用一个格式如0X00RRGGBB这样格式的十六进制来表达，下面是常见颜色的表达形式：<br />　　红色：(255,0,0)或0x00FF0000<br />　　绿色：(0,255,0)或0x0000FF00<br />　　蓝色：(255,255,255)或0x00FFFFFF<br />　　其他颜色也可以通过上面的方式组合出来。<br />　　知道了颜色的表达方式以后，下面来介绍一下如何在J2ME程序中使用颜色，涉及的方法均在Graphics类中，有以下几个：<br />　　1.getColor()：<br />　　获得当前使用的颜色，返回值是0x00RRGGBB格式的数字。例如：<br />          int color = g.getColor();<br />　　其中g为Graphics类型的对象。<br />　　2.setColor(int RGB)：<br />　　设置使用的颜色。例如：<br />          g.setColor(0x00ff0000);<br />　　3.setColor(int red, int green, int blue)<br />　　和上面的方法作用一样，例如：<br />          g.setColor(255,0,0);<br />　　在设置了Graphics使用的颜色以后，再进行绘制的时候，就可以绘制指定的颜色了。</p>
		<p>二十二、在J2ME联网应用中获得客户端的手机号码<br />　　在J2ME程序开发过程中，为了一定的需要，经常需要来获得用户的手机号码，但是这个功能却在标准的J2ME类库中没有提供。<br />　　在使用中国移动的CMWAP方式连接网络时，中国移动会将用户的手机号码放在一个名称为x-up-calling-line-id的头信息中，可以通过读取该头信息，获得用户的手机号码，具体代码如下：<br />          String usermphone = http.getHeader("x-up-calling-line-id");<br />　　其中http是HttpConnction类型的对象。</p>
		<p>二十三、使用J2ME发送手机短信息<br />　　在程序中，发送短信息的方式一般有三种：<br />　　1、 使用程序在网络上发送短信息，例如各大网站的短信业务。这种方式是通过程序将信息发送给运营商的网关服务器，然后通过运营商的网络发送给手机。<br />　　2、 在计算机中，通过数据线连接到手机，然后通过手机来发送短信息。这种方式是通过使用AT指令来实现。爱立信手机的AT指令你可以在以下地址找到：<a href="http://mobilityworld.ericsson.com.cn/development/download_hit.asp">http://mobilityworld.ericsson.com.cn/development/download_hit.asp</a><br />　　3、 通过在手机中运行的程序来发送短信息。这个正是本文实现的方式。<br />　　在J2ME中，如果想发送短信息，需要使用WMA包，MIDP2.0中已经包含，MIDP1.0中可以通过厂商提供的扩展API实现，和WMA的类库基本一样。<br />       下面是使用WMA向指定手机号码发送短信息的一个方法，很简单。当然WMA也提供了其他的方式来发送更多的内容。</p>
		<p>// SMSUtil.java<br />package my.util;<br />import javax.wireless.messaging.*;<br />import javax.microedition.io.*;<br />/**<br />* 发送文本短信息的方法<br />*/<br />public class SMSUtil<br />{<br />      /**<br />      * 给指定号码发送短信息<br />      * @param content 短信息内容<br />      * @param phoneNumber 手机号码<br />      * @return 发送成功返回true，否则返回false<br />      */<br />      public static boolean send(String content,String phoneNumber)<br />      {<br />            //返回值<br />            boolean result = true;<br />            try<br />            {<br />                   //地址<br />                   String address = "sms://+" + phoneNumber;<br />                   //建立连接<br />                   MessageConnection conn = (MessageConnection)Connector.open(address);<br />                   //设置短信息类型为文本，短信息有文本和二进制两种类型<br />                   TextMessage msg = (TextMessage)conn.newMessage(MessageConnection.TEXT_MESSAGE);<br />                   //设置信息内容<br />                   msg.setPayloadText(content);<br />                   //发送<br />                   conn.send(msg);<br />            }<br />            catch(Exception e)<br />            {<br />                   result = false;<br />                   //未处理<br />            }<br />            return result;<br />      } <br />}</p>
		<p>二十四、使用简单的J2ME程序测试MIDlet的生命周期<br />　　在MIDlet程序学习中，生命周期是一个比较抽象的概念。其实生命周期就是一个简单的规定，规定了MIDlet中的每个方法，什么时候被系统调用。下面是一个示例代码，在每个方法的内部都输出一条语句，可以根据程序的输出结果来验证各方法被调用的顺序，具体代码如下：</p>
		<p>
				<br />//文件名：LifeCircleMIDlet.java<br />import javax.microedition.midlet.*;<br />/**<br />* 测试MIDlet的生命周期<br />*/<br />public class LifeCircleMIDlet extends MIDlet<br />{<br />      /**<br />      * 默认构造方法<br />      */<br />      public LifeCircleMIDlet()<br />      {<br />            System.out.println("默认构造方法");<br />      }<br />      /**<br />      * 启动方法<br />      */<br />      public void startApp()<br />      {<br />            System.out.println("startApp方法");<br />      }<br />      /**<br />      * 暂停方法<br />      */<br />      public void pauseApp()<br />      {<br />            System.out.println("pauseApp方法"); <br />      }<br />      /**<br />      * 销毁方法<br />      * @param b <br />      */<br />      public void destroyApp(boolean b)<br />      {<br />            System.out.println("destroyApp方法"); <br />      } <br />}<br />　　在J2WTK中运行该程序时，可以使用浏览器中的“MIDlet”菜单中的暂停和恢复菜单，模拟暂停事件。</p>
		<p>二十五、使用OTA来发布你的程序<br />　　众所周知，J2ME程序发布的形式主要有：OTA、数据线传输、红外和蓝牙传输等。这里简单说说如何通过OTA来发布你的程序。<br />　　OTA是Over The Air的简写，也就是通过网络下载，这是主要的发布形式之一。现在的百宝箱都是采用这种形式。<br />　　使用OTA来发布程序，需要如下几个步骤：<br />　　1、在你的WEB服务器上添加对于jad和jar文件的MIME支持。<br />　　后缀名:jad<br />　　MIME类型:text/vnd.sun.j2me.app-descriptor<br />　　后缀名:jar<br />　　MIME类型:application/java-archive<br />　　2、发布WML页面：<br />　　例如你的jar文件名test.jad，则最简单的下载页面是：<br />　　&lt;?xml version="1.0"?&gt; <br />　　&lt;!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.3//EN" <br />　　"<a href="http://www.wapforum.org/DTD/wml13.dtd">http://www.wapforum.org/DTD/wml13.dtd</a>"&gt; <br />　　&lt;wml&gt; <br />　　&lt;card id="card1" title="Download Midlet"&gt; <br />　　&lt;a href="test.jad"&gt;test&lt;/a&gt; <br />　　&lt;/card&gt; <br />　　&lt;/wml&gt; <br />　　你可以将以上代码保存在WEB服务器上，例如保存为text.wml<br />　　3、修改jad文件：<br />　　在jad文件中增加　MIDlet-Jar-URL: <a href="http://domain/directory/test.jar">http://domain/directory/test.jar</a><br />　　其中的<a href="http://domain/directory/test.jar">http://domain/directory/test.jar</a>为你的jar文件的路径。<br />　　经过上面的设置，你就可以将你的wml页面路径作为你的WAP下载页面发布了。用户只需要在手机上输入这个路径就可以访问和下载你的程序了。<br /></p>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/89068.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2006-12-20 16:20 <a href="http://www.blogjava.net/zhangzhong1018/articles/89068.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jxl.jar  下载</title><link>http://www.blogjava.net/zhangzhong1018/articles/83057.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Thu, 23 Nov 2006 07:42:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/83057.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/83057.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/83057.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/83057.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/83057.html</trackback:ping><description><![CDATA[
		<a href="http://sourceforge.net/project/showfiles.php?group_id=79926">http://sourceforge.net/project/showfiles.php?group_id=79926</a>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/83057.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2006-11-23 15:42 <a href="http://www.blogjava.net/zhangzhong1018/articles/83057.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java 中易混淆问题（ms）</title><link>http://www.blogjava.net/zhangzhong1018/articles/77198.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Wed, 25 Oct 2006 07:11:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/77198.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/77198.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/77198.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/77198.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/77198.html</trackback:ping><description><![CDATA[
		<h5 class="diaryTitle"> </h5>
		<div class="diaryContent" id="diary4630106" style="DISPLAY: block">第一，final, finally, finalize的区别.<br /><br />final 修饰符（关键字）如果一个类被声明为final，意味着它不能再派生出新的子类，不能作为父类被继承。因此一个类不能既被声明为 abstract的，又被声明为final的。将变量或方法声明为final，可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值，而在以后的引用中只能读取，不可修改。被声明为final的方法也同样只能使用，不能重载 <br /><br />finally 再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常，那么相匹配的 catch 子句就会执行，然后控制就会进入 finally 块（如果有的话）。 <br />finalize 方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的，因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。 <br /><br />第二，Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类，是否可以implements(实现)interface(接口)? <br /><br />匿名的内部类是没有名字的内部类。不能extends(继承) 其它类，但一个内部类可以作为一个接口，由另一个内部类实现。 <br /><br />第三，Static Nested Class 和 Inner Class的不同，说得越多越好<br />Nested Class （一般是C++的说法），Inner Class (一般是JAVA的说法)。Java内部类与C++嵌套类最大的不同就在于是否有指向外部的引用上。具体可见http: //www.frontfree.net/articles/services/view.asp?id=704&amp;page=1 <br />注： 静态内部类（Inner Class）意味着1创建一个static内部类的对象，不需要一个外部类对象，2不能从一个static内部类的一个对象访问一个外部类对象 <br /><br />第四，&amp;和&amp;&amp;的区别。<br /><br />&amp;是位运算符。&amp;&amp;是布尔逻辑运算符。 <br /><br />第五，HashMap和Hashtable的区别。<br /><br />都属于Map接口的类，实现了将惟一键映射到特定的值上。 <br />HashMap 类没有分类或者排序。它允许一个 null 键和多个 null 值。 <br />Hashtable 类似于 HashMap，但是不允许 null 键和 null 值。它也比 HashMap 慢，因为它是同步的。 <br /><br />第六，Collection 和 Collections的区别。 <br />Collections是个java.util下的类，它包含有各种有关集合操作的静态方法。 <br />Collection是个java.util下的接口，它是各种集合结构的父接口。 <br /><br />第七，什么时候用assert。 <br />断言是一个包含布尔表达式的语句，在执行这个语句时假定该表达式为 true。如果表达式计算为 false，那么系统会报告一个 Assertionerror。它用于调试目的： <br />assert(a &gt; 0); // throws an Assertionerror if a &lt;= 0 <br />断言可以有两种形式： <br />assert Expression1 ; <br />assert Expression1 : Expression2 ; <br />Expression1 应该总是产生一个布尔值。 <br />Expression2 可以是得出一个值的任意表达式。这个值用于生成显示更多调试信息的 String 消息。 <br />断言在默认情况下是禁用的。要在编译时启用断言，需要使用 source 1.4 标记： <br />javac -source 1.4 Test.java <br />要在运行时启用断言，可使用 -enableassertions 或者 -ea 标记。 <br />要在运行时选择禁用断言，可使用 -da 或者 -disableassertions 标记。 <br />要系统类中启用断言，可使用 -esa 或者 -dsa 标记。还可以在包的基础上启用或者禁用断言。 <br />可以在预计正常情况下不会到达的任何位置上放置断言。断言可以用于验证传递给私有方法的参数。不过，断言不应该用于验证传递给公有方法的参数，因为不管是否启用了断言，公有方法都必须检查其参数。不过，既可以在公有方法中，也可以在非公有方法中利用断言测试后置条件。另外，断言不应该以任何方式改变程序的状态。 <br /><br />第八，GC是什么? 为什么要有GC? (基础)。<br /><br />GC是垃圾收集器。Java 程序员不用担心内存管理，因为垃圾收集器会自动进行管理。要请求垃圾收集，可以调用下面的方法之一： <br />System.gc() <br />Runtime.getRuntime().gc() <br /><br />第九，String s = new String("xyz");创建了几个String Object? <br /><br />两个对象，一个是“xyx”,一个是指向“xyx”的引用对象s。 <br /><br />第十，Math.round(11.5)等於多少? Math.round(-11.5)等於多少? <br /><br />Math.round(11.5)返回（long）12，Math.round(-11.5)返回（long）-11; <br /><br />第十一，short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错? <br /><br />short s1 = 1; s1 = s1 + 1;有错，s1是short型，s1+1是int型,不能显式转化为short型。可修改为s1 =(short)(s1 + 1) 。short s1 = 1; s1 += 1正确。 <br /><br />第十二，sleep() 和 wait() 有什么区别? 搞线程的最爱 <br />sleep()方法是使线程停止一段时间的方法。在sleep 时间间隔期满后，线程不一定立即恢复执行。这是因为在那个时刻，其它线程可能正在运行而且没有被调度为放弃执行，除非(a)“醒来”的线程具有更高的优先级 <br />(b)正在运行的线程因为其它原因而阻塞。 <br />wait()是线程交互时，如果线程对一个同步对象x 发出一个wait()调用，该线程会暂停执行，被调对象进入等待状态，直到被唤醒或等待时间到。 <br /><br />第十三，Java有没有goto? <br />Goto java中的保留字，现在没有在java中使用。 <br /><br />第十四，数组有没有length()这个方法? String有没有length()这个方法？ <br /><br />数组没有length()这个方法，有length的属性。 <br />String有有length()这个方法。 <br /><br />第十五，Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型? <br /><br />方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现，重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数，我们说该方法被重写 (Overriding)。子类的对象使用这个方法时，将调用子类中的定义，对它而言，父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法，它们或有不同的参数个数或有不同的参数类型，则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。 <br /><br />第十六，Set里的元素是不能重复的，那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别? <br /><br />Set里的元素是不能重复的，那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等。 <br />equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖，为的是当两个分离的对象的内容和类型相配的话，返回真值。 <br /><br />第十七，给我一个你最常见到的runtime exception。 <br />ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException, <br />ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFORMatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException <br /><br />第十八，error和exception有什么区别? <br />error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。 <br />exception 表示一种设计或实现问题。也就是说，它表示如果程序运行正常，从不会发生的情况。 <br /><br />第十九，List, Set, Map是否继承自Collection接口? <br />List，Set是 <br /><br />Map不是 <br /><br />第二十，abstract class和interface有什么区别? <br /><br />声明方法的存在而不去实现它的类被叫做抽象类（abstract class），它用于要创建一个体现某些基本行为的类，并为该类声明方法，但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量，其类型是一个抽象类，并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现，否则它们也是抽象类为。取而代之，在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。 <br />接口（interface）是抽象类的变体。在接口中，所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的，没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似，除了该实现类不能从接口定义中继承行为。当类实现特殊接口时，它定义（即将程序体给予）所有这种接口的方法。然后，它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类，它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换，instanceof 运算符可以用来决定某对象的类是否实现了接口。 <br /><br />第二十一，abstract的method是否可同时是static,是否可同时是native，是否可同时是synchronized? <br /><br />都不能 <br /><br />第二十二，接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)? <br />接口可以继承接口。抽象类可以实现(implements)接口，抽象类是否可继承实体类，但前提是实体类必须有明确的构造函数。 <br /><br />第二十三，启动一个线程是用run()还是start()? <br />启动一个线程是调用start()方法，使线程所代表的虚拟处理机处于可运行状态，这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。 <br /><br />第二十四，构造器Constructor是否可被override? 构造器Constructor不能被继承，因此不能重写Overriding，但可以被重载Overloading。 <br /><br />第二十五，是否可以继承String类? <br />String类是final类故不可以继承。 <br /><br />第二十六，当一个线程进入一个对象的一个synchronized方法后，其它线程是否可进入此对象的其它方法? <br />不能，一个对象的一个synchronized方法只能由一个线程访问。 <br /><br />第二十七，try {}里有一个return语句，那么紧跟在这个try后的finally {}里的code会不会被执行，什么时候被执行，在return前还是后? <br /><br />会执行，在return前执行。 <br /><br />第二十八，编程题: 用最有效率的方法算出2乘以8等於几? <br /><br />有C背景的程序员特别喜欢问这种问题。 <br /><br />2 &lt;&lt; 3 <br /><br />第二十九，两个对象值相同(x.equals(y) == true)，但却可有不同的hash code，这句话对不对? <br />不对，有相同的hash code。 <br /><br />第三十，当一个对象被当作参数传递到一个方法后，此方法可改变这个对象的属性，并可返回变化后的结果，那么这里到底是值传递还是引用传递? <br /><br />是值传递。Java 编程语言只由值传递参数。当一个对象实例作为一个参数被传递到方法中时，参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变，但对象的引用是永远不会改变的。 <br /><br />第三十一，swtich是否能作用在byte上，是否能作用在long上，是否能作用在String上? <br /><br />switch（expr1）中，expr1是一个整数表达式。因此传递给 switch 和 case 语句的参数应该是 int、 short、 char 或者 byte。long,string 都不能作用于swtich。 <br /><br />第三十二，编程题: 写一个Singleton出来。<br /><br />Singleton模式主要作用是保证在Java应用程序中，一个类Class只有一个实例存在。 <br />一般Singleton模式通常有几种种形式: <br />第一种形式: 定义一个类，它的构造函数为private的，它有一个static的private的该类变量，在类初始化时实例话，通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。 <br />public class Singleton { <br />　　private Singleton(){} <br />　　//在自己内部定义自己一个实例，是不是很奇怪？ <br />　　//注意这是private 只供内部调用 <br />　　private static Singleton instance = new Singleton(); <br />　　//这里提供了一个供外部访问本class的静态方法，可以直接访问　　 <br />　　public static Singleton getInstance() { <br />　　　　return instance; 　　 <br />　　 } <br />} <br />第二种形式: <br />public class Singleton { <br />　　private static Singleton instance = null; <br />　　public static synchronized Singleton getInstance() { <br />　　//这个方法比上面有所改进，不用每次都进行生成对象，只是第一次　　　 　 <br />　　//使用时生成实例，提高了效率！ <br />　　if (instance==null) <br />　　　　instance＝new Singleton(); <br />return instance; 　　} <br />} <br />其他形式: <br />定义一个类，它的构造函数为private的，所有方法为static的。 <br />一般认为第一种形式要更加安全些 <br /><br />第三十三 Hashtable和HashMap <br />Hashtable继承自Dictionary类，而HashMap是Java1.2引进的Map interface的一个实现 <br /><br />HashMap允许将null作为一个entry的key或者value，而Hashtable不允许 <br /><br />还有就是，HashMap把Hashtable的contains方法去掉了，改成containsvalue和containsKey。因为contains方法容易让人引起误解。 <br /><br />最大的不同是，Hashtable的方法是Synchronize的，而HashMap不是，在 <br />多个线程访问Hashtable时，不需要自己为它的方法实现同步，而HashMap <br />就必须为之提供外同步。 <br /><br />Hashtable和HashMap采用的hash/rehash算法都大概一样，所以性能不会有很大的差异</div>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/77198.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2006-10-25 15:11 <a href="http://www.blogjava.net/zhangzhong1018/articles/77198.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java格式化小数</title><link>http://www.blogjava.net/zhangzhong1018/articles/75832.html</link><dc:creator>leoli</dc:creator><author>leoli</author><pubDate>Wed, 18 Oct 2006 02:19:00 GMT</pubDate><guid>http://www.blogjava.net/zhangzhong1018/articles/75832.html</guid><wfw:comment>http://www.blogjava.net/zhangzhong1018/comments/75832.html</wfw:comment><comments>http://www.blogjava.net/zhangzhong1018/articles/75832.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangzhong1018/comments/commentRss/75832.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangzhong1018/services/trackbacks/75832.html</trackback:ping><description><![CDATA[
		<p>package com.gpe.ukweb.invoice;</p>
		<p>import java.math.BigDecimal;</p>
		<p>public class FormatNumber {<br /> public FormatNumber(){}<br /> public static double Double(String d,int i){<br />  BigDecimal b = new BigDecimal(d);<br />  BigDecimal one = new BigDecimal("1");<br />  return b.divide(one,i,BigDecimal.ROUND_HALF_UP).doubleValue();<br /> }<br /> public static double Double(double d){<br />  return Double(Double.toString(d),2);<br /> }<br /> <br /> public static String strDouble(String d,int i){<br />  BigDecimal b = new BigDecimal(d);<br />  BigDecimal one = new BigDecimal("1");<br />  return b.divide(one,i,BigDecimal.ROUND_HALF_UP).toString();  <br /> }<br /> public static String strDouble(double d){<br />  return strDouble(Double.toString(d),2);<br /> }<br /> public static void main(String[] args){<br />  String ss="523.9999";<br />  System.out.println(FormatNumber.strDouble(ss,6));<br /> } </p>
		<p>}<br /></p>
<img src ="http://www.blogjava.net/zhangzhong1018/aggbug/75832.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangzhong1018/" target="_blank">leoli</a> 2006-10-18 10:19 <a href="http://www.blogjava.net/zhangzhong1018/articles/75832.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>