<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>卒子99</title>
    <description></description>
    <link>http://bbobchen.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>一个半例模式</title>
        <author>卒子99</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://bbobchen.javaeye.com">卒子99</a>&nbsp;
          链接：<a href="http://bbobchen.javaeye.com/blog/183039" style="color:red;">http://bbobchen.javaeye.com/blog/183039</a>&nbsp;
          发表时间: 2008年04月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>最近做的项目中，有一个特殊需求： 设计一个多机环境中的cache,如果其它服务器更新了数据，需要重新reload数据，更新缓存。但是在没有得到新的cache前，老的cache依然能使用。 这就介于有一个存在的cache实例的同时，可以存在一个正在construct的新cache，自己觉得不像单例模式，姑且就叫一个半例模式 </p>
<p>&nbsp;</p>
<pre name="code" class="java">public class CategoryCache
<br /> { 
<br />    private static final Logger logger = Logger .getLogger(CatagoryCache.class); 
<br />   private static volatile CategoryCache cache; 
<br />    // after all variants initialized 
<br />    static 
<br />   { 
<br />        cache = new CategoryCache(); 
<br />    }
<br />
<br />     private CategoryCache() 
<br />    {
<br />     load(); 
<br />    } 
<br />
<br />    static CategoryCache getInstance() 
<br />    { 
<br />        return cache; 
<br />    }
<br />  
<br />    Category getCategory(String name) { ...... } 
<br />
<br />    void addCategory(Category category) { ..... } 
<br />
<br />     public static void process(Object obj) 
<br />    { 
<br />      ........
<br />      reload(); 
<br />    }
<br /> 
<br />    private void load() { ........ } 
<br />    
<br />    private static synchronized void reload() 
<br />    { 
<br />         CategoryCache temp = new CategoryCache(); 
<br />         cache = temp; 
<br />    } 
<br />}</pre>
<p>&nbsp;cache在当前jvm只有一个实例，所以都通过getInstance方法获取，需要注意的是，创建cache实例的时候是放在static块中的，原因是不能保证jvm初始化变量的顺序，如果load方法需要使用成员变量，则有可能抛出NullPointException </p>
<p>process是接受到消息时，用于通知当前cache需要重新构建 </p>
<p>reload方法实现了重新构建cache.需要注意，不能直写成CategoryCache cache = new CategoryCache(); 因为cache变量被标识为volatile，所以如果在构建的过程，一个线程调用getInstance，会得到一个构建不完全的对象。并且在当前的情况下，其它线程仍然可以使用老得cache，这就出现了一个老的cahce+一个构建中的cache</p>
          <br/>
          <span style="color:red;">
            <a href="http://bbobchen.javaeye.com/blog/183039#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 15 Apr 2008 21:40:10 +0800</pubDate>
        <link>http://bbobchen.javaeye.com/blog/183039</link>
        <guid>http://bbobchen.javaeye.com/blog/183039</guid>
      </item>
      <item>
        <title>接口，抽象类的使用</title>
        <author>卒子99</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://bbobchen.javaeye.com">卒子99</a>&nbsp;
          链接：<a href="http://bbobchen.javaeye.com/blog/164638" style="color:red;">http://bbobchen.javaeye.com/blog/164638</a>&nbsp;
          发表时间: 2008年02月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          以前在使用接口的时候，就知道它可以抽象系统模型，便于扩展。但到底什么时候使用接口，什么时候使用抽象类，我一直也不是很清楚。但最新做了一个项目，其中遇到抽象一个系统模型的时候，让我明白了他们的用途。废话少说，直接上Case了<br />  需求：从文件中系统中读取数据，可支持从TXT文件，XML，XLS.....<br /><br />  这个是最初的需求，很简单，系统支持从多文件格式读取数据，首先抽象出一个AbstractFileDataParser类，类图如下：<br />AbstractFileDataParser类代码如下：<br /><pre name="code" class="java">
public abstract class AbstractFileDataParser
{
    private FileInputStream fileInputStream = null;

    public AbstractFileDataParser(FileInputStream fileInputStream)
    {
        if (fileInputStream == null)
        {
            throw new NullPointerException("file input stream is null!");
        }
        this.fileInputStream = fileInputStream;
    }

    protected FileInputStream getFileInputStream()
    {
        return this.fileInputStream;
    }

    public void release()
    {
        CloseUtil.close(fileInputStream);
    }

}
</pre><br />   最主要的方法就是readData，类似于BufferedReader，每次调用读取一组数据，如果还回Null，表示数据读取完成了。<br />   如果从项目的需要上来看，这个抽象应该是满足需求了。但现在有考虑问题，会老想着抽象，所以又想了到了一个新的抽象层：只是读取数据。这就意味着不知道什么地方获取数据，文件系统，网络等,于是需要进一步抽象，这个时候就需要定义一个IDataParser接口，类图抽象层次如下所示<br />IDataParser接口代码如下：<br /><pre name="code" class="java">

public interface IDataParser
{
    /**
     * 
     * 如果还回null，则代表没有可读取的数据了 
     * 
     * @return
     */
    Object[] readData();

    void release();

}
</pre><br />AbstractFileDataParser类实现IDatParser接口，代码如下：<br /><pre name="code" class="java">
public abstract class AbstractFileDataParser implements IDataParser
{
    private FileInputStream fileInputStream = null;

    public AbstractFileDataParser(FileInputStream fileInputStream)
    {
        if (fileInputStream == null)
        {
            throw new NullPointerException("file input stream is null!");
        }
        this.fileInputStream = fileInputStream;
    }

    protected FileInputStream getFileInputStream()
    {
        return this.fileInputStream;
    }

    public void release()
    {
        CloseUtil.close(fileInputStream);
    }
}
</pre><br /><br />   这个抽象层次就比较清楚了，虽然暂时项目中只是从文件中读取数据，但并不保证以后可能会改变啊，抽象出一个接口，就很好满足了OCP。而AbstractFileDataParser类作为项目实际需求，可以实现文件读入流的获取和关闭，实现了一些共同行为。<br />   我想这就是接口和抽象类的最大区别了吧
          <br/>
          <span style="color:red;">
            <a href="http://bbobchen.javaeye.com/blog/164638#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 24 Feb 2008 22:02:21 +0800</pubDate>
        <link>http://bbobchen.javaeye.com/blog/164638</link>
        <guid>http://bbobchen.javaeye.com/blog/164638</guid>
      </item>
      <item>
        <title>请教如何在dos下实现显示滚动进度</title>
        <author>卒子99</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://bbobchen.javaeye.com">卒子99</a>&nbsp;
          链接：<a href="http://bbobchen.javaeye.com/blog/115628" style="color:red;">http://bbobchen.javaeye.com/blog/115628</a>&nbsp;
          发表时间: 2007年08月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          我想在dos下用System.out.print打连续循环的打印出\ | - /这四个字符，但要求打印到同一个位置以达到动画的效果。请问如何实现？<br />我已经试过了打印后退符(\b)没有效果的？
          <br/>
          <span style="color:red;">
            <a href="http://bbobchen.javaeye.com/blog/115628#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 23 Aug 2007 12:51:07 +0800</pubDate>
        <link>http://bbobchen.javaeye.com/blog/115628</link>
        <guid>http://bbobchen.javaeye.com/blog/115628</guid>
      </item>
      <item>
        <title>[转]DB2中的数据移动</title>
        <author>卒子99</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://bbobchen.javaeye.com">卒子99</a>&nbsp;
          链接：<a href="http://bbobchen.javaeye.com/blog/107050" style="color:red;">http://bbobchen.javaeye.com/blog/107050</a>&nbsp;
          发表时间: 2007年07月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <br />
DB2中所谓的数据移动，包括：&nbsp;<br />
<br />
1.&nbsp;数据的导入（Import）&nbsp;<br />
<br />
2.&nbsp;数据的导出（Export）&nbsp;<br />
<br />
3.&nbsp;数据的装入（Load）&nbsp;<br />
<br />
<br />
<br />
导入和装入都是利用DB2的相关命令把某种格式的文件中的数据保存到数据库中的表中&nbsp;<br />
<br />
导出是指把DB2数据库的表中的数据保存到某种格式的文件当中去&nbsp;<br />
<br />
<br />
<br />
数据移动的作用：&nbsp;<br />
<br />
<br />
<br />
如果要在不同的数据库管理系统之间转移数据，数据移动通常是最实用的一种方法，因为任何一种数据库管理系统都支持常用的几种文件格式，通过这个通用的接口，就很容易实现不同系统间数据的转移。&nbsp;<br />
<br />
<br />
<br />
这三个命令中，Export最简单，因为从表中向文件转移数据，通常不会出现错误，也不会有非法的数据。&nbsp;<br />
<br />
<br />
<br />
在讲解命令之前，首先介绍一下文件的格式，用于DB2数据移动的文件格式有四种：&nbsp;<br />
<br />
1.&nbsp;ASC&mdash;&mdash;非定界ASCII文件，是一个ASCII字符流。数据流中的行由行定界符分隔，而行中的每一列则通过起始和结束位置来定义。例如：&nbsp;<br />
<br />
<br />
<br />
10&nbsp;&nbsp;&nbsp;Head&nbsp;Office&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;160&nbsp;&nbsp;&nbsp;Corporate&nbsp;&nbsp;&nbsp;New&nbsp;York&nbsp;<br />
<br />
15&nbsp;&nbsp;&nbsp;New&nbsp;England&nbsp;&nbsp;50&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Eastern&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Boston&nbsp;<br />
<br />
20&nbsp;&nbsp;&nbsp;Mid&nbsp;Atlantic&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Eastern&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Washington&nbsp;<br />
<br />
38&nbsp;&nbsp;&nbsp;South&nbsp;Atlantic&nbsp;30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Eastern&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Atlanta&nbsp;<br />
<br />
42&nbsp;&nbsp;&nbsp;Great&nbsp;Lakes&nbsp;&nbsp;&nbsp;&nbsp;100&nbsp;&nbsp;&nbsp;Midwest&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Chicago&nbsp;<br />
<br />
51&nbsp;&nbsp;&nbsp;Plains&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;140&nbsp;&nbsp;&nbsp;Midwest&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dallas&nbsp;<br />
<br />
66&nbsp;&nbsp;&nbsp;Pacific&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;270&nbsp;&nbsp;&nbsp;Western&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;San&nbsp;Francisco&nbsp;<br />
<br />
84&nbsp;&nbsp;&nbsp;Mountain&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;290&nbsp;&nbsp;&nbsp;Western&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Denver&nbsp;<br />
<br />
<br />
<br />
2.&nbsp;DEL&mdash;&mdash;定界ASCII文件，也是一个ASCII字符流。数据流中的行由行定界符分隔，行中的列值由列定界符分隔。文件类型修饰符可用于修改这些定界符的默认值。例如：&nbsp;<br />
<br />
<br />
<br />
10,&quot;Head&nbsp;Office&quot;,160,&quot;Corporate&quot;,&quot;New&nbsp;York&quot;&nbsp;<br />
<br />
15,&quot;New&nbsp;England&quot;,50,&quot;Eastern&quot;,&quot;Boston&quot;&nbsp;<br />
<br />
20,&quot;Mid&nbsp;Atlantic&quot;,10,&quot;Eastern&quot;,&quot;Washington&quot;&nbsp;<br />
<br />
38,&quot;South&nbsp;Atlantic&quot;,30,&quot;Eastern&quot;,&quot;Atlanta&quot;&nbsp;<br />
<br />
42,&quot;Great&nbsp;Lakes&quot;,100,&quot;Midwest&quot;,&quot;Chicago&quot;&nbsp;<br />
<br />
51,&quot;Plains&quot;,140,&quot;Midwest&quot;,&quot;Dallas&quot;&nbsp;<br />
<br />
66,&quot;Pacific&quot;,270,&quot;Western&quot;,&quot;San&nbsp;Francisco&quot;&nbsp;<br />
<br />
84,&quot;Mountain&quot;,290,&quot;Western&quot;,&quot;Denver&quot;&nbsp;<br />
<br />
<br />
<br />
3.&nbsp;WSF&mdash;&mdash;（work&nbsp;sheet&nbsp;format）为工作表格式，用于与Lotus系列的软件进行数据交换。&nbsp;<br />
<br />
<br />
<br />
4.&nbsp;PC/IXF&mdash;&mdash;是集成交换格式（Integration&nbsp;Exchange&nbsp;Format，IXF）数据交换体系结构的改编版本，由一些列可变长度的记录构成，包括头记录、表记录、表中每列的列描述符记录以及表中每行的一条或多条数据记录。PC/IXF&nbsp;文件记录由包含了字符数据的字段组成。&nbsp;<br />
<br />
<br />
<br />
第一部分：数据的导出（Export）&nbsp;<br />
<br />
例一：把Org表中的所有数据导出到文件C:\ORG.TXT中。&nbsp;<br />
<br />
Export&nbsp;to&nbsp;c:\org.txt&nbsp;of&nbsp;del&nbsp;select&nbsp;*&nbsp;from&nbsp;org&nbsp;<br />
<br />
<br />
<br />
其中，of&nbsp;del表示导出到的文件的类型，在本例中导出到一个非定界文本文件中；后面的select&nbsp;*&nbsp;from&nbsp;org是一个SQL语句，该语句查询出来的结果就是要导出的数据。&nbsp;<br />
<br />
<br />
<br />
例二：改变del格式文件的格式控制符&nbsp;<br />
<br />
export&nbsp;to&nbsp;c:\staff.txt&nbsp;of&nbsp;del&nbsp;modified&nbsp;by&nbsp;coldel$&nbsp;chardel''&nbsp;decplusblank&nbsp;select&nbsp;*&nbsp;from&nbsp;staff&nbsp;<br />
<br />
在该例中，modified子句用于控制各种符号，coldel表示字段之间的间隔符，默认情况为逗号，现在改为$号；chardel表示字符串字段用什么符号引用，默认情况下为一对双引号括起来，现在改为用一对单引号括起来；decplusblank表示对于十进制数据类型，用空格代替最前面的加号，因为默认情况下会在十进制数据前面加上正负号的。&nbsp;<br />
<br />
<br />
<br />
例三：以ASC格式将数据导出到文件&nbsp;<br />
<br />
Export命令是不支持ASC格式文件的，所以如果想导出ASC这样规整的格式，需要程序员自己进行转换操作，思路是将各种数据类型都转换成定长字符串，然后把各个要导出的字段合并成为一个字段。&nbsp;<br />
<br />
例如创建如下结构的表n：&nbsp;<br />
<br />
create&nbsp;table&nbsp;n(a&nbsp;int,b&nbsp;date,c&nbsp;time,d&nbsp;varchar(5),e&nbsp;char(4),f&nbsp;double)&nbsp;<br />
<br />
然后插入两条数据：&nbsp;<br />
<br />
insert&nbsp;into&nbsp;n&nbsp;values(15,'2004-10-21','23:12:23','abc','hh',35.2)&nbsp;<br />
<br />
insert&nbsp;into&nbsp;n&nbsp;values(5,'2004-1-21','3:12:23','bc','hhh',35.672)&nbsp;<br />
<br />
要想把这两条数据以规整的格式导出到文件中，进行如下操作：&nbsp;<br />
<br />
export&nbsp;to&nbsp;c:\test.txt&nbsp;of&nbsp;del&nbsp;select&nbsp;char(a)&nbsp;||&nbsp;char(b)&nbsp;||&nbsp;char(c)&nbsp;||&nbsp;char(d,5)&nbsp;||&nbsp;e&nbsp;||&nbsp;char(f)&nbsp;as&nbsp;tmp&nbsp;from&nbsp;n&nbsp;<br />
<br />
这样导出的结果与ASC格式的文件非常类似，只是每一行的前后多出了一对双引号，对此我们可以使用文本工具（如写字板、记事本等）把双引号删除掉，也可以置之不理，在以后导入的时候直接控制格式（忽略双引号）&nbsp;<br />
<br />
在文件中的格式为：&nbsp;<br />
<br />
<br />
<br />
&quot;15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2004-10-2123.12.23abc&nbsp;&nbsp;hh&nbsp;&nbsp;3.52E1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;<br />
<br />
&quot;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2004-01-2103.12.23bc&nbsp;&nbsp;&nbsp;hhh&nbsp;3.5672E1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;<br />
<br />
<br />
<br />
例四：大数据的导出&nbsp;<br />
<br />
export&nbsp;to&nbsp;d:\myfile.del&nbsp;of&nbsp;del&nbsp;lobs&nbsp;to&nbsp;d:\lob\&nbsp;lobfile&nbsp;lobs&nbsp;modified&nbsp;by&nbsp;lobsinfile&nbsp;select&nbsp;*&nbsp;from&nbsp;emp_photo&nbsp;<br />
<br />
该命令把emp_photo表的数据导出到d:\myfile.del文件中，其结果为：&nbsp;<br />
<br />
<pre>;&nbsp;<br />
<br />
&quot;000130&quot;,&quot;bitmap&quot;,&quot;lobs.001.0.43690/&quot;&nbsp;<br />
<br />
&quot;000130&quot;,&quot;gif&quot;,&quot;lobs.001.43690.29540/&quot;&nbsp;<br />
<br />
&quot;000130&quot;,&quot;xwd&quot;,&quot;lobs.001.73230.45800/&quot;&nbsp;<br />
<br />
&quot;000140&quot;,&quot;bitmap&quot;,&quot;lobs.001.119030.71798/&quot;&nbsp;<br />
<br />
&quot;000140&quot;,&quot;gif&quot;,&quot;lobs.001.190828.29143/&quot;&nbsp;<br />
<br />
&quot;000140&quot;,&quot;xwd&quot;,&quot;lobs.001.219971.73908/&quot;&nbsp;<br />
<br />
&quot;000150&quot;,&quot;bitmap&quot;,&quot;lobs.001.293879.73438/&quot;&nbsp;<br />
<br />
&quot;000150&quot;,&quot;gif&quot;,&quot;lobs.001.367317.39795/&quot;&nbsp;<br />
<br />
&quot;000150&quot;,&quot;xwd&quot;,&quot;lobs.001.407112.75547/&quot;&nbsp;<br />
<br />
&quot;000190&quot;,&quot;bitmap&quot;,&quot;lobs.001.482659.63542/&quot;&nbsp;<br />
<br />
&quot;000190&quot;,&quot;gif&quot;,&quot;lobs.001.546201.36088/&quot;&nbsp;<br />
<br />
&quot;000190&quot;,&quot;xwd&quot;,&quot;lobs.001.582289.65650/&quot;&nbsp;<br />
<br />
</pre>
;&nbsp;<br />
<br />
其中第三个字段是BLOB类型，在该文件中只保存了一个标志，相当于一个指针，真正的LOB数据保存在d:\lob目录下的lobs.001、lobs.002、......等一系列文件中。命令中lobs&nbsp;to&nbsp;后面指定大对象数据保存在什么路径下（注意，该路径必须事先已经存在，否则会报错），lobfile&nbsp;后面指定大对象数据保存在什么文件中，不要指定扩展名，DB2会根据数据量自动追加.001、.002等扩展名，同时不要忘记加上modified&nbsp;by&nbsp;lobsinfile子句。&nbsp;<br />
<br />
<br />
<br />
例五：把导出信息保存在消息文件中。&nbsp;<br />
<br />
export&nbsp;to&nbsp;d:\awards.ixf&nbsp;of&nbsp;ixf&nbsp;messages&nbsp;d:\msgs.txt&nbsp;select&nbsp;*&nbsp;from&nbsp;staff&nbsp;where&nbsp;dept&nbsp;=&nbsp;20&nbsp;<br />
<br />
这个例子把staff表中dept=20的数据导出到d:\awards.ixf文件中，所有的导出信息都保存在d:\msgs.txt文件中（无论是成功、警告还是失败信息），这样，管理员可以通过观察信息文件找到问题所在。&nbsp;<br />
<br />
<br />
<br />
例六：给导出数据列重命名。&nbsp;<br />
<br />
export&nbsp;to&nbsp;d:\awards.ixf&nbsp;of&nbsp;ixf&nbsp;method&nbsp;n(c1,c2,c3,c4,c5,c6,c7)&nbsp;messages&nbsp;d:\msgs.txt&nbsp;select&nbsp;*&nbsp;from&nbsp;staff&nbsp;where&nbsp;dept=20&nbsp;<br />
<br />
在默认情况下，导出的每一列数据以表中对应的字段名自动命名，我们可以通过method&nbsp;n子句给每一列重新命名，需要注意的是，这个子句只在ixf和wsf格式文件中有效，在文本文件中不能使用。<br />
          <br/>
          <span style="color:red;">
            <a href="http://bbobchen.javaeye.com/blog/107050#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 30 Jul 2007 18:42:56 +0800</pubDate>
        <link>http://bbobchen.javaeye.com/blog/107050</link>
        <guid>http://bbobchen.javaeye.com/blog/107050</guid>
      </item>
      <item>
        <title>[转]Oracle、DB2、PostgreSQL之Sequence总结</title>
        <author>卒子99</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://bbobchen.javaeye.com">卒子99</a>&nbsp;
          链接：<a href="http://bbobchen.javaeye.com/blog/104354" style="color:red;">http://bbobchen.javaeye.com/blog/104354</a>&nbsp;
          发表时间: 2007年07月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="tpc_content">Sequence是数据库系统按照一定规则自动增加的数字序列。这个序列一般作为代理主键（因为不会重复），没有其他任何意义。<br />
<br />
Sequence是数据库系统的特性，有的数据库有Sequence，有的没有。比如Oracle、DB2、PostgreSQL数据库有Sequence，MySQL、SQL Server、Sybase等数据库没有Sequence。<br />
<br />
根据我个人理解，Sequence是数据中一个特殊存放等差数列的表，该表受数据库系统控制，任何时候数据库系统都可以根据当前记录数大小加上步长来获取到该表下一条记录应该是多少，这个表没有实际意义，常常用来做主键用，非常不错，呵呵，不过很郁闷的各个数据库厂商尿不到一个壶里--各有各的一套对Sequence的定义和操作。在此我对常见三种数据库的Sequence的定义和操作做一个对比和总结，以便日后查看。<br />
<br />
一、定义Sequence<br />
<br />
定义一个seq_test，最小值为10000，最大值为99999999999999999，从20000开始，增量的步长为1，缓存为20的循环排序Sequence。<br />
<br />
Oracle的定义方法：<br />
create sequence seq_test<br />
minvalue 10000<br />
maxvalue 99999999999999999<br />
start with 20000<br />
increment by 1<br />
cache 20<br />
cycle<br />
order;<br />
<br />
DB2的写法：<br />
create sequence seq_test<br />
as bigint<br />
start with 20000<br />
increment by 1<br />
minvalue 10000<br />
maxvalue 99999999999999999<br />
cycle<br />
cache 20<br />
order;<br />
<br />
PostgreSQL的写法：<br />
create sequence seq_test<br />
increment by 1<br />
minvalue 10000<br />
maxvalue 99999999999999999<br />
start 20000<br />
cache 20<br />
cycle;<br />
<br />
二、Oracle、DB2、PostgreSQL数据库Sequence值的引用参数为：currval、nextval，分别表示当前值和下一个值。下面分别从三个数据库的Sequence中获取nextval的值。<br />
<br />
Oracle中：seq_test.nextval <br />
例如：select seq_test.nextval from dual;<br />
<br />
DB2中：nextval for SEQ_TOPICMS<br />
例如：values nextval for seq_test;<br />
<br />
PostgreSQL中：nextval(seq_test)<br />
例如：select nextval(seq_test);<br />
<br />
三、Sequence与indentity的区别与联系<br />
<br />
Sequence与indentity的基本作用都差不多。都可以生成自增数字序列。<br />
Sequence是数据库系统中的一个对象，可以在整个数据库中使用，和表没有任何关系；indentity仅仅是指定在表中某一列上，作用范围就是这个表。<br />
<br />
转自：红联Linux</div>
          <br/>
          <span style="color:red;">
            <a href="http://bbobchen.javaeye.com/blog/104354#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 23 Jul 2007 09:32:40 +0800</pubDate>
        <link>http://bbobchen.javaeye.com/blog/104354</link>
        <guid>http://bbobchen.javaeye.com/blog/104354</guid>
      </item>
      <item>
        <title>使用Dwr渲染table</title>
        <author>卒子99</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://bbobchen.javaeye.com">卒子99</a>&nbsp;
          链接：<a href="http://bbobchen.javaeye.com/blog/89911" style="color:red;">http://bbobchen.javaeye.com/blog/89911</a>&nbsp;
          发表时间: 2007年06月13日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>第一次尝试使用Dwr来开发ajax，js也没有想像那么难写。有一个感觉，Dwr的设计很像axis1，连显示服务的风格都很像，呵呵，是不是作者使借签了axis的设计思想啊</p>
<p>1、设计目标</p>
<p>避免查询的时候刷新页面的全部区域，只用改变查询结果显示的部分</p>
<p>2、web.xml中部署Dwr</p>
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">servlet</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>dwr</span><span class="tag">&lt;/</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">servlet-class</span><span class="tag">&gt;</span><span>uk.ltd.getahead.dwr.DWRServlet</span><span class="tag">&lt;/</span><span class="tag-name">servlet-class</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">init-param</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">param-name</span><span class="tag">&gt;</span><span>debug</span><span class="tag">&lt;/</span><span class="tag-name">param-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">param-value</span><span class="tag">&gt;</span><span>true</span><span class="tag">&lt;/</span><span class="tag-name">param-value</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">init-param</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">servlet</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">servlet-mapping</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>dwr</span><span class="tag">&lt;/</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>/dwr/*</span><span class="tag">&lt;/</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">servlet-mapping</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>3、Dwr.xml部置</p>
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">dwr</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">allow</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">create</span><span>&nbsp;</span><span class="attribute">creator</span><span>=</span><span class="attribute-value">&quot;spring&quot;</span><span>&nbsp;</span><span class="attribute">javascript</span><span>=</span><span class="attribute-value">&quot;FileManager&quot;</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">param</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;beanName&quot;</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">&quot;fileItemManager&quot;</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">include</span><span>&nbsp;</span><span class="attribute">method</span><span>=</span><span class="attribute-value">&quot;getFileItemsByParent&quot;</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">create</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">convert</span><span>&nbsp;</span><span class="attribute">match</span><span>=</span><span class="attribute-value">&quot;com.csroad.fileproject.model.FileItem&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="attribute">converter</span><span>=</span><span class="attribute-value">&quot;bean&quot;</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">param</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;include&quot;</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">&quot;id,name,fileType,parentId&quot;</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">convert</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">allow</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="tag">&lt;/</span><span class="tag-name">dwr</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>客户端调用的是Spring代理的javabean，所有creator要使用spring，如果是普通javabean，则使用new就可以了。javascript属性指定了客户端的js名字</p>
<p>参数，spring中是使用beanName来获取spring中的bean。如果是普通的javabean，则使用class，值为java类</p>
<p>需要注意的是convert，如果传递的对象不是基本类型，则需要配置javabean，并指定相关的属性。如配置文件中的id,name</p>
<p>需要说明的是，fileItemManager的方法是一返回一个java.util.List对象</p>
<p>4、页面中插入js</p>
<div class="code_title">js 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-c">
    <li class="alt"><span><span>&lt;script&nbsp;type='text/javascript'&nbsp;src='${ctx}/dwr/</span><span class="keyword">interface</span><span>/FileManager.js'&gt;&lt;/script&gt; &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&lt;script&nbsp;type='text/javascript' &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;src='&lt;%=request.getContextPath()%&gt;/dwr/engine.js'&gt; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&lt;/script&gt; &nbsp;&nbsp;</span></li>
    <li class=""><span>&lt;script&nbsp;type='text/javascript' &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;src='&lt;%=request.getContextPath()%&gt;/dwr/util.js'&gt;&lt;/script&gt;&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>&nbsp;</p>
<p>其中${ctx}/dwr/inteface/FileManger.js的名字要和前面dwr.xml中javscript属性的值一致。</p>
<p>5、编写JS代码</p>
<div class="code_title">js 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-c">
    <li class="alt"><span><span>&lt;script&nbsp;type=</span><span class="string">&quot;text/javascript&quot;</span><span>&gt; &nbsp;&nbsp;</span></span></li>
    <li class=""><span></span><span class="comment">//查询函数 </span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="keyword">function</span><span>&nbsp;query(parentId,label,dep){ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;FileManager.getFileItemsByParent(parentId,getFileList); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;DWRUtil.useLoadingMessage(</span><span class="string">&quot;文件正在载入中，请稍等...........&quot;</span><span>);&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="comment">//回调函数 </span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">function</span><span>&nbsp;getFileList(data){ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">var</span><span>&nbsp;cellfuncs=[ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">function</span><span>(data){ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(data.fileType==1){ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;data.name; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">var</span><span>&nbsp;aDom=document.createElement(</span><span class="string">&quot;a&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;aDom.setAttribute(</span><span class="string">&quot;href&quot;</span><span>,</span><span class="string">&quot;javascript:query('&quot;</span><span>+data.id+</span><span class="string">&quot;','&quot;</span><span>+data.name+</span><span class="string">&quot;','&quot;</span><span>+fileDep+</span><span class="string">&quot;')&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">var</span><span>&nbsp;aText=document.createTextNode(data.name); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;aDom.appendChild(aText); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;aDom; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}, &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">function</span><span>(data){ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(data.fileType==0){ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="string">&quot;目录&quot;</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="string">&quot;可下载文件&quot;</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;}, &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">function</span><span>(data){ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(data.fileType==0){ &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="string">&quot;无相关操作&quot;</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">var</span><span>&nbsp;aDom=document.createElement(</span><span class="string">&quot;a&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;aDom.setAttribute(</span><span class="string">&quot;href&quot;</span><span>,</span><span class="string">&quot;javascript:openWindow('/scrood/yg/downloadRecordAction.html?method=applyDownload&amp;dep=&quot;</span><span>+fileDep+</span><span class="string">&quot;&amp;fileId=&quot;</span><span>+data.id+</span><span class="string">&quot;')&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">var</span><span>&nbsp;aText=document.createTextNode(</span><span class="string">&quot;申请下载&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;aDom.appendChild(aText); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;aDom; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;]; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;DWRUtil.removeAllRows(</span><span class="string">&quot;fileResultBody&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;DWRUtil.addRows('fileResultBody',&nbsp;data,cellfuncs,{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;rowCreator:</span><span class="keyword">function</span><span>(options)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">var</span><span>&nbsp;row&nbsp;=&nbsp;document.createElement(</span><span class="string">&quot;tr&quot;</span><span>);&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;row;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;cellCreator:</span><span class="keyword">function</span><span>(options)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">var</span><span>&nbsp;td&nbsp;=&nbsp;document.createElement(</span><span class="string">&quot;td&quot;</span><span>);&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;td.setAttribute(</span><span class="string">&quot;align&quot;</span><span>,</span><span class="string">&quot;center&quot;</span><span>);&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;td;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;});&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&lt;/script&gt;&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>&nbsp;</p>
<p>在query查询函数中，调用FileManager得到查询结果，和普通的java方法调用一样。但要注意，第二个参数传入的是回调函数，用于处理响应值，注要是指如何渲染。</p>
<p>在回调函数中第一个要定义的就是cellfuns，它代表每一列值的表现形势，有多少function，就有多少列。每一个单元格的内容可以是简单的值，也可以是一个包含了其它HTML标签的Document.</p>
<p>接下来就是具体的处理参数值的过程。DwrUtil是DWR框架提供的一个非常有用的功具函数，包含通常的是JS处理功能，如动态添加select的option等，可以单独使用。</p>
<p>DwrUtil.addRows('fileResultBody',data,cellfuncs,...)是用来实际插入数据的，第一个插入是要插入数据所在的表格的ID，最好是tbody的ID，data为值，cellfuncs前面已经介绍了，最后两个参数是用于创建&lt;tr&gt;和&lt;td&gt;属性的</p>
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://bbobchen.javaeye.com/blog/89911#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 13 Jun 2007 22:24:46 +0800</pubDate>
        <link>http://bbobchen.javaeye.com/blog/89911</link>
        <guid>http://bbobchen.javaeye.com/blog/89911</guid>
      </item>
      <item>
        <title>[转]Java中Set的深入研究</title>
        <author>卒子99</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://bbobchen.javaeye.com">卒子99</a>&nbsp;
          链接：<a href="http://bbobchen.javaeye.com/blog/85870" style="color:red;">http://bbobchen.javaeye.com/blog/85870</a>&nbsp;
          发表时间: 2007年06月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div width="100%">
<div style="FLOAT: right"></div>
<div>Java中Set的深入研究
<p>&nbsp;</p>
<p>作者：jjp</p>
<p>Set和数学中的集合是同一个概念，就是没有重复元素的集合。</p>
<p>这篇文章主要论述了Set是如何实现&quot;没有重复元素&quot;（no&nbsp;duplicate&nbsp;elements）的，以及阐述了什么是&ldquo;重复&rdquo;（duplicate），是相同的地址空间？是equals的返回值为true？是compareTo的返回值为0&nbsp;？还是有相同的hashCode？本文还给出了在什么情况下使用什么样的Set的建议。</p>
<p>注：本文不涉及范型。</p>
<p>1、树形结构：<br />
&nbsp;public&nbsp;interface&nbsp;Set&lt;E&gt;&nbsp;extends&nbsp;Collection&lt;E&gt;{}<br />
&nbsp;public&nbsp;abstract&nbsp;class&nbsp;AbstractSet&lt;E&gt;&nbsp;extends&nbsp;AbstractCollection&lt;E&gt;&nbsp;implements&nbsp;Set&lt;E&gt;{}<br />
&nbsp;public&nbsp;class&nbsp;CopyOnWriteArraySet&lt;E&gt;extends&nbsp;AbstractSet&lt;E&gt;implements&nbsp;Serializable{}<br />
&nbsp;public&nbsp;abstract&nbsp;class&nbsp;EnumSet&lt;E&nbsp;extends&nbsp;Enum&lt;E&gt;&gt;extends&nbsp;AbstractSet&lt;E&gt;implements&nbsp;Cloneable,&nbsp;Serializable{}<br />
&nbsp;public&nbsp;class&nbsp;HashSet&lt;E&gt;extends&nbsp;AbstractSet&lt;E&gt;implements&nbsp;Set&lt;E&gt;,&nbsp;Cloneable,&nbsp;Serializable{}<br />
&nbsp;public&nbsp;final&nbsp;class&nbsp;JobStateReasonsextends&nbsp;HashSet&lt;JobStateReason&gt;implements&nbsp;PrintJobAttribute{}<br />
&nbsp;public&nbsp;class&nbsp;LinkedHashSet&lt;E&gt;extends&nbsp;HashSet&lt;E&gt;implements&nbsp;Set&lt;E&gt;,&nbsp;Cloneable,&nbsp;Serializable{}<br />
&nbsp;public&nbsp;class&nbsp;TreeSet&lt;E&gt;extends&nbsp;AbstractSet&lt;E&gt;implements&nbsp;SortedSet&lt;E&gt;,&nbsp;Cloneable,&nbsp;Serializable{}<br />
&nbsp;&nbsp;&nbsp;可以看出，可以实例化的类为：CopyOnWriteArraySet，HashSet，LinkedHashSet，TreeSet。<br />
2、Set是如何实现元素唯一性的<br />
&nbsp;&nbsp;&nbsp;javadoc中对Set的描述第一段如下：&ldquo;A&nbsp;collection&nbsp;that&nbsp;contains&nbsp;no&nbsp;duplicate&nbsp;elements.&nbsp;More&nbsp;formally,&nbsp;sets&nbsp;contain&nbsp;no&nbsp;pair&nbsp;of&nbsp;elements&nbsp;e1&nbsp;<br />
&nbsp;&nbsp;&nbsp;and&nbsp;e2&nbsp;such&nbsp;that&nbsp;e1.equals(e2),&nbsp;and&nbsp;at&nbsp;most&nbsp;one&nbsp;null&nbsp;element.&nbsp;As&nbsp;implied&nbsp;by&nbsp;its&nbsp;name,&nbsp;this&nbsp;interface&nbsp;models&nbsp;the&nbsp;mathematical&nbsp;set&nbsp;abstraction.&rdquo;<br />
&nbsp;&nbsp;&nbsp;这段话是对是错，请看下面分析。<br />
&nbsp;&nbsp;&nbsp;要进行下面的论述，我们先了解一下Map。Map中的元素是&ldquo;键－值&rdquo;对，其中&ldquo;键&rdquo;必须是唯一的。TreeSet和HashSet就是利用这个特性实现&ldquo;no&nbsp;duplicate&nbsp;&nbsp;&nbsp;&nbsp;elements&rdquo;。它把set中的元素作为Map中的&ldquo;键&rdquo;，从而保持元素的唯一性。这些键在Map中又是如何区分的呢？不同的Map有不同的做法，而且区别很大。<br />
&nbsp;&nbsp;&nbsp;下面我们分别就TreeSet、HashSet和CopyOnWriteArraySet进行论述：<br />
2.1、TreeSet部分：<br />
&nbsp;&nbsp;&nbsp;以下以TreeSet为例进行分析。<br />
&nbsp;&nbsp;&nbsp;请看TreeSet的部分实体：<br />
&nbsp;public&nbsp;class&nbsp;TreeSet&lt;E&gt;&nbsp;extends&nbsp;AbstractSet&lt;E&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;implements&nbsp;SortedSet&lt;E&gt;,&nbsp;Cloneable,&nbsp;java.io.Serializable<br />
&nbsp;{<br />
&nbsp;&nbsp;//&nbsp;The&nbsp;backing&nbsp;Map<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;transient&nbsp;SortedMap&lt;E,Object&gt;&nbsp;m;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;The&nbsp;keySet&nbsp;view&nbsp;of&nbsp;the&nbsp;backing&nbsp;Map<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;transient&nbsp;Set&lt;E&gt;&nbsp;keySet;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Dummy&nbsp;value&nbsp;to&nbsp;associate&nbsp;with&nbsp;an&nbsp;Object&nbsp;in&nbsp;the&nbsp;backing&nbsp;Map<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//这是每个键所指的对像<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;static&nbsp;final&nbsp;Object&nbsp;PRESENT&nbsp;=&nbsp;new&nbsp;Object();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//constructor<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;TreeSet(SortedMap&lt;E,Object&gt;&nbsp;m)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m&nbsp;=&nbsp;m;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;keySet&nbsp;=&nbsp;m.keySet();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;TreeSet()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;this(new&nbsp;TreeMap&lt;E,Object&gt;());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//以下省略..........<br />
&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;可以看到TreeSet使用了SortedMap作为其Map保存&ldquo;键－值&rdquo;对，而这个SortedMap的真正实体是TreeMap。<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;请看示例程序1：<br />
&nbsp;import&nbsp;java.util.*;<br />
&nbsp;public&nbsp;class&nbsp;SetTest1&nbsp;{<br />
&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args){<br />
&nbsp;&nbsp;&nbsp;Set&nbsp;set&nbsp;=&nbsp;new&nbsp;TreeSet();<br />
&nbsp;&nbsp;&nbsp;set.add(new&nbsp;SetElement1(&quot;aa&quot;));<br />
&nbsp;&nbsp;&nbsp;set.add(new&nbsp;SetElement1(&quot;bb&quot;));<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;static&nbsp;class&nbsp;SetElement1{<br />
&nbsp;&nbsp;&nbsp;String&nbsp;s;<br />
&nbsp;&nbsp;&nbsp;public&nbsp;SetElement1(String&nbsp;s){<br />
&nbsp;&nbsp;&nbsp;&nbsp;this.s&nbsp;=&nbsp;&nbsp;s;<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;public&nbsp;String&nbsp;toString(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;s;<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;public&nbsp;boolean&nbsp;equals(Object&nbsp;obj)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;s.equals(((SetElement1)obj).s);<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}<br />
&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;该程序能够正常编译，但是运行时会抛出异常java.lang.ClassCastException。为什么？<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;请看示例程序2：<br />
&nbsp;import&nbsp;java.util.*;<br />
&nbsp;public&nbsp;class&nbsp;SetTest2&nbsp;{<br />
&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args){<br />
&nbsp;&nbsp;&nbsp;Set&nbsp;set&nbsp;=&nbsp;new&nbsp;TreeSet();<br />
&nbsp;&nbsp;&nbsp;set.add(new&nbsp;SetElement2(&quot;aa&quot;));<br />
&nbsp;&nbsp;&nbsp;set.add(new&nbsp;SetElement2(&quot;aa&quot;));<br />
&nbsp;&nbsp;&nbsp;set.add(new&nbsp;SetElement2(&quot;bb&quot;));<br />
&nbsp;&nbsp;&nbsp;System.out.println(set);<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;static&nbsp;class&nbsp;SetElement2&nbsp;implements&nbsp;Comparable{<br />
&nbsp;&nbsp;&nbsp;String&nbsp;s;<br />
&nbsp;&nbsp;&nbsp;public&nbsp;SetElement2(String&nbsp;s){<br />
&nbsp;&nbsp;&nbsp;&nbsp;this.s&nbsp;=&nbsp;&nbsp;s;<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;public&nbsp;String&nbsp;toString(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;s;<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;public&nbsp;int&nbsp;compareTo(Object&nbsp;o){<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;s.compareTo(((SetElement2)o).s);<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;public&nbsp;boolean&nbsp;equals(Object&nbsp;obj)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;s.equals(((SetElement2)obj).s);<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}<br />
&nbsp;}<br />
&nbsp;&nbsp;&nbsp;运行结果：<br />
&nbsp;&nbsp;&nbsp;[aa,&nbsp;bb]<br />
&nbsp;&nbsp;&nbsp;这正是我们所期望的结果。那&ldquo;示例程序1&rdquo;和&ldquo;示例程序2&rdquo;有什么区别？<br />
&nbsp;&nbsp;&nbsp;是因为SetElement2实现了Comparable接口，而SetElement1没有。SetElement2实现Comparable接口有什么用呢？因为在TreeSet的add方法中需要比较两个&nbsp;&nbsp;&nbsp;&nbsp;元素的&ldquo;值&rdquo;。请看TreeMap中的compare方法：<br />
&nbsp;&nbsp;&nbsp;private&nbsp;int&nbsp;compare(K&nbsp;k1,&nbsp;K&nbsp;k2)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(comparator==null&nbsp;?&nbsp;((Comparable&lt;/*-*/K&gt;)k1).compareTo(k2)<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;comparator.compare((K)k1,&nbsp;(K)k2));<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;可见这个方法先把要比较的元素down&nbsp;cast成Comparable类型。这里就可以解释&ldquo;示例程序1&rdquo;中为什么会抛出异常java.lang.ClassCastException，因SetElement1没有实现Comparable接口，当然就不能down&nbsp;cast成Comparable。可见，要用TreeSet来做为你的Set，那么Set中所装的元素都必须实现了Comparable接口。<br />
&nbsp;&nbsp;&nbsp;说到这里，你是不是想到了TreeSet中是采用Comparable接口中的compareTo方法来判断元素是否相同（duplicate），而不是采用其他类似equals之类的东东来判断。<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;请看示例程序3：<br />
&nbsp;&nbsp;&nbsp;&nbsp;import&nbsp;java.util.Set;<br />
&nbsp;import&nbsp;java.util.*;<br />
&nbsp;public&nbsp;class&nbsp;SetTest3&nbsp;{<br />
&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args){<br />
&nbsp;&nbsp;&nbsp;Set&nbsp;set&nbsp;=&nbsp;new&nbsp;HashSet();<br />
&nbsp;&nbsp;&nbsp;set.add(new&nbsp;SetElement3(&quot;aa&quot;));<br />
&nbsp;&nbsp;&nbsp;set.add(new&nbsp;SetElement3(&quot;aa&quot;));<br />
&nbsp;&nbsp;&nbsp;set.add(new&nbsp;SetElement3(&quot;bb&quot;));<br />
&nbsp;&nbsp;&nbsp;System.out.println(set);<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;static&nbsp;class&nbsp;SetElement3&nbsp;implements&nbsp;Comparable{<br />
&nbsp;&nbsp;&nbsp;String&nbsp;s;<br />
&nbsp;&nbsp;&nbsp;public&nbsp;SetElement3(String&nbsp;s){<br />
&nbsp;&nbsp;&nbsp;&nbsp;this.s&nbsp;=&nbsp;&nbsp;s;<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;public&nbsp;String&nbsp;toString(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;s;<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;public&nbsp;int&nbsp;compareTo(Object&nbsp;o){<br />
&nbsp;&nbsp;&nbsp;&nbsp;//return&nbsp;s.compareTo(((SetElement3)o).s);<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;-1;<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;public&nbsp;boolean&nbsp;equals(Object&nbsp;obj)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;s.equals(((SetElement3)obj).s);<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}<br />
&nbsp;}<br />
&nbsp;&nbsp;&nbsp;运行结果：<br />
&nbsp;&nbsp;&nbsp;[bb,&nbsp;aa,&nbsp;aa]<br />
&nbsp;&nbsp;&nbsp;看到没有，有两个&ldquo;aa&rdquo;！！这是因为compareTo返回值始终是&quot;-1&quot;，也就是说&ldquo;把任何元素都看成不同&rdquo;。<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;综上所述，你是否对javadoc中对Set功能的描述有了怀疑？！</p>
<div>2.2、HashSet部分：<br />
&nbsp;&nbsp;&nbsp;以下以HashSet为例进行分析。<br />
&nbsp;&nbsp;&nbsp;从Hashset类的主体部分：<br />
&nbsp;public&nbsp;class&nbsp;HashSet&lt;E&gt;&nbsp;extends&nbsp;AbstractSet&lt;E&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;implements&nbsp;Set&lt;E&gt;,&nbsp;Cloneable,&nbsp;java.io.Serializable<br />
&nbsp;{<br />
&nbsp;&nbsp;static&nbsp;final&nbsp;long&nbsp;serialVersionUID&nbsp;=&nbsp;-5024744406713321676L;<br />
&nbsp;&nbsp;private&nbsp;transient&nbsp;HashMap&lt;E,Object&gt;&nbsp;map;<br />
&nbsp;&nbsp;//&nbsp;Dummy&nbsp;value&nbsp;to&nbsp;associate&nbsp;with&nbsp;an&nbsp;Object&nbsp;in&nbsp;the&nbsp;backing&nbsp;Map<br />
&nbsp;&nbsp;//这是每个键所指的对像<br />
&nbsp;&nbsp;private&nbsp;static&nbsp;final&nbsp;Object&nbsp;PRESENT&nbsp;=&nbsp;new&nbsp;Object();
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;HashSet()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;map&nbsp;=&nbsp;new&nbsp;HashMap&lt;E,Object&gt;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;boolean&nbsp;add(E&nbsp;o)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;return&nbsp;map.put(o,&nbsp;PRESENT)==null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;//以下省略..........<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;HashSet()&nbsp;{<br />
&nbsp;<br />
&nbsp;&nbsp;map&nbsp;=&nbsp;new&nbsp;HashMap&lt;E,Object&gt;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;}<br />
&nbsp;&nbsp;&nbsp;可以看到HashSet使用了HashMap作为其Map保存&ldquo;键－值&rdquo;对。<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;请看示例程序4：<br />
&nbsp;import&nbsp;java.util.*;</p>
<p>&nbsp;public&nbsp;class&nbsp;SetTest4&nbsp;{<br />
&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args){<br />
&nbsp;&nbsp;Set&nbsp;set&nbsp;=&nbsp;new&nbsp;HashSet();<br />
&nbsp;&nbsp;set.add(new&nbsp;SetElement4(&quot;aa&quot;));<br />
&nbsp;&nbsp;set.add(new&nbsp;SetElement4(&quot;aa&quot;));<br />
&nbsp;&nbsp;set.add(new&nbsp;SetElement4(&quot;bb&quot;));<br />
&nbsp;&nbsp;System.out.println(set);<br />
&nbsp;}<br />
&nbsp;static&nbsp;class&nbsp;SetElement4{<br />
&nbsp;&nbsp;String&nbsp;s;<br />
&nbsp;&nbsp;public&nbsp;SetElement4(String&nbsp;s){<br />
&nbsp;&nbsp;&nbsp;this.s&nbsp;=&nbsp;&nbsp;s;<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;public&nbsp;String&nbsp;toString(){<br />
&nbsp;&nbsp;&nbsp;return&nbsp;s;<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;public&nbsp;boolean&nbsp;equals(Object&nbsp;obj)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;return&nbsp;s.equals(((SetElement4)obj).s);<br />
&nbsp;&nbsp;}<br />
&nbsp;}<br />
}</p>
<p>&nbsp;&nbsp;&nbsp;运行结果：<br />
&nbsp;&nbsp;&nbsp;[bb,&nbsp;aa,&nbsp;aa]<br />
&nbsp;&nbsp;&nbsp;没有&ldquo;示例程序1&rdquo;中的java.lang.ClassCastException，但是运行结果似乎不对，因为有两个&ldquo;aa&rdquo;。<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;请看示例程序5：<br />
&nbsp;import&nbsp;java.util.*;<br />
&nbsp;public&nbsp;class&nbsp;SetTest5&nbsp;{<br />
&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args){<br />
&nbsp;&nbsp;&nbsp;Set&nbsp;set&nbsp;=&nbsp;new&nbsp;HashSet();<br />
&nbsp;&nbsp;&nbsp;set.add(new&nbsp;SetElement5(&quot;aa&quot;));<br />
&nbsp;&nbsp;&nbsp;set.add(new&nbsp;SetElement5(&quot;aa&quot;));<br />
&nbsp;&nbsp;&nbsp;set.add(new&nbsp;SetElement5(&quot;bb&quot;));<br />
&nbsp;&nbsp;&nbsp;System.out.println(set);<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;static&nbsp;class&nbsp;SetElement5{<br />
&nbsp;&nbsp;&nbsp;String&nbsp;s;<br />
&nbsp;&nbsp;&nbsp;public&nbsp;SetElement5(String&nbsp;s){<br />
&nbsp;&nbsp;&nbsp;&nbsp;this.s&nbsp;=&nbsp;&nbsp;s;<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;public&nbsp;String&nbsp;toString(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;s;<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;public&nbsp;boolean&nbsp;equals(Object&nbsp;obj)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;s.equals(((SetElement5)obj).s);<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;public&nbsp;int&nbsp;hashCode()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;//return&nbsp;super.hashCode();<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;s.hashCode();<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}<br />
&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;运行结果：<br />
&nbsp;&nbsp;&nbsp;&nbsp;[bb,&nbsp;aa]<br />
&nbsp;&nbsp;&nbsp;&nbsp;这就对了。&ldquo;示例程序4&rdquo;和&ldquo;示例程序5&rdquo;有什么区别？是SetElement5重写了hashCode方法。<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;可见HashSet中是采用了比较元素hashCode的方法来判断元素是否相同（duplicate），而不是采用其他类似equals之类的东东来判断。<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;说了这么多，那java类库中到底有没有根据equals来判断元素是否相同（duplicate）的Set呢？请看下文。<br />
2.2、CopyOnWriteArraySet部分：<br />
&nbsp;&nbsp;&nbsp;类CopyOnWriteArraySet是java.util.concurrent包中的一个类，所以它是线程安全的。<br />
&nbsp;&nbsp;&nbsp;CopyOnWriteArraySet是使用CopyOnWriteArrayList作为其盛放元素的容器。当往CopyOnWriteArrayList添加新元素，它都要遍历整个List，并且用equals来&nbsp;&nbsp;&nbsp;&nbsp;比较两个元素是否相同。</p>
<p>&nbsp;&nbsp;&nbsp;请看示例程序6：<br />
&nbsp;import&nbsp;java.util.*;<br />
&nbsp;import&nbsp;java.util.concurrent.*;<br />
&nbsp;public&nbsp;class&nbsp;SetTest6&nbsp;{<br />
&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args){<br />
&nbsp;&nbsp;&nbsp;Set&nbsp;set&nbsp;=&nbsp;new&nbsp;CopyOnWriteArraySet();<br />
&nbsp;&nbsp;&nbsp;set.add(new&nbsp;SetElement6(&quot;aa&quot;));<br />
&nbsp;&nbsp;&nbsp;set.add(new&nbsp;SetElement6(&quot;aa&quot;));<br />
&nbsp;&nbsp;&nbsp;set.add(new&nbsp;SetElement6(&quot;bb&quot;));<br />
&nbsp;&nbsp;&nbsp;System.out.println(set);<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;static&nbsp;class&nbsp;SetElement6{<br />
&nbsp;&nbsp;&nbsp;String&nbsp;s;<br />
&nbsp;&nbsp;&nbsp;public&nbsp;SetElement6(String&nbsp;s){<br />
&nbsp;&nbsp;&nbsp;&nbsp;this.s&nbsp;=&nbsp;&nbsp;s;<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;public&nbsp;String&nbsp;toString(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;s;<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;public&nbsp;boolean&nbsp;equals(Object&nbsp;obj)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;s.equals(((SetElement6)obj).s);<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}<br />
&nbsp;}<br />
&nbsp;&nbsp;&nbsp;运行结果：<br />
&nbsp;&nbsp;&nbsp;[aa,&nbsp;bb]<br />
&nbsp;&nbsp;&nbsp;好了，一切搞定！！</p>
<p>3、总结：<br />
&nbsp;&nbsp;&nbsp;Javadoc中的一些描述可能是不准确的，大家要当心了！<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;Set中实现元素互异的各种方法差异很大，大致可以分为三种：使用equals，使用hashCode，使用compareTo。但是我还没有发现采用&ldquo;判断地址空间是否相同&rdquo;来判断元素是否相同的类，当然我们可以用现有的三种方法来实现&ldquo;判断地址空间是否相同&rdquo;。<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;综上所述，我们可以总结出使用Set的三种不同的情形：（以下假设元素类为Element）<br />
&nbsp;&nbsp;&nbsp;A、如果想使用Element的equals方法来判断元素是否相同，那么可以使用CopyOnWriteArraySet来构造类的实体。<br />
&nbsp;&nbsp;&nbsp;B、如果Element实现了Comparable接口，而且想使用compareTo方法来判断元素是否相同，那么可以使用TreeSet来构造类的实体。<br />
&nbsp;&nbsp;&nbsp;C、如果想使用判断hashCode是否相同的方法来判断元素是否相同，那么可以使用HashSet来构造类的实体。</p>
</div>
</div>
</div>
          <br/>
          <span style="color:red;">
            <a href="http://bbobchen.javaeye.com/blog/85870#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 02 Jun 2007 10:00:28 +0800</pubDate>
        <link>http://bbobchen.javaeye.com/blog/85870</link>
        <guid>http://bbobchen.javaeye.com/blog/85870</guid>
      </item>
      <item>
        <title>[转]JavaBean</title>
        <author>卒子99</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://bbobchen.javaeye.com">卒子99</a>&nbsp;
          链接：<a href="http://bbobchen.javaeye.com/blog/77337" style="color:red;">http://bbobchen.javaeye.com/blog/77337</a>&nbsp;
          发表时间: 2007年05月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>from:<font face="Arial">http://www.itisedu.com/phrase/200604251741535.html</font></p>
<center>
<h1>JavaBean</h1>
</center>
<div>
<p align="right"><font face="Verdana"><font face="Verdana"><font face="Verdana"><font color="#f70938"><font face="黑体"><a href="http://www.itisedu.com/phrase/200604112229525.html" target="_new">中科永联</a>高级技术培训中心（</font><font face="黑体">www.itisedu.com</font><font face="黑体">）<img src="http://www.itisedu.com/manage/Upload/image/2006425174142165.jpg" border="0" alt="" /></font></font></font></font></font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.itisedu.com/phrase/200604251741535.html" target="_new">JavaBean</a> 是一种JAVA语言写成的可重用<a href="http://www.itisedu.com/phrase/200603302222545.html" target="_new">组件</a>。为写成JavaBean，<a href="http://www.itisedu.com/phrase/200603090857555.html" target="_new">类</a>必须是具体的和公共的，并且具有无参数的构造器。JavaBeans 通过提供符合一致性<a href="http://www.itisedu.com/phrase/200603061631585.html" target="_new">设计模式</a>的公共方法将内部域暴露称为属性。众所周知，属性名称符合这种<a href="http://www.itisedu.com/phrase/200603061709535.html" target="_new">模式</a>，其他Java 类可以通过自省机制发现和操作这些JavaBean 属性。<br />
</font><font face="Verdana"></font>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用户可以使用JavaBean将功能、处理、值、<a href="http://www.itisedu.com/phrase/200602271218062.html" target="_new">数据库</a>访问和其他任何可以用java代码创造的<a href="http://www.itisedu.com/phrase/200603090845215.html" target="_new">对象</a>进行打包，并且其他的开发者可以通过内部的JSP页面、<a href="http://www.itisedu.com/phrase/200603091005185.html" target="_new">Servlet</a>、其他JavaBean、<a href="http://www.itisedu.com/phrase/200604201518585.html" target="_new">applet</a><a href="http://www.itisedu.com/phrase/200604232224305.html" target="_new">程序</a>或者应用来使用这些对象。用户可以认为JavaBean提供了一种随时随地的复制和粘贴的功能，而不用关心任何改变。</font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JavaBean是Sun微系统的一个<a href="http://www.itisedu.com/phrase/200603101726185.html" target="_new">面向对象</a>的编程接口，它可以让你建可重用应用程序或能在网络中任何主流<a href="http://www.itisedu.com/phrase/200602281634075.html" target="_new">操作系统</a>平台上配置的程序块，称作组件。像Java applet一样，JavaBeans组件(或&ldquo;Beans&rdquo;)能够给予万维网页面交互的能力，例如：计算感兴趣的比率或是根据用户或浏览器的特性改变页面内容。</font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 从用户的观点来看，一个组件可以是一个与你交互的按钮或是一个当你按下按钮它便开始的小计算程序。从一个开发者的观点来看，那个按钮组件和计算器组件是分别被创建的，并且他们可以一起使用或是在不同的应用程序或情况下和不同的组件产生不同的组合来使用。</font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当组件或Beans在使用过程中，Bean的性质(比如，一个窗口的背景色)对于其他Bean来说是可见的，并且，之前没&ldquo;碰到&rdquo;过的Bean也可以动态地获悉彼此的特性并从而进行交互。　</font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bean是随Sun的Bean开发包(BDK)开发出来的，并且能在任何主流操作系统平台的许多应用程序环境(人们所说的&ldquo;容器&rdquo;，container)中运行，包括浏览器，文字处理<a href="http://www.itisedu.com/phrase/200604232134205.html" target="_new">软件</a>，以及一些其他应用。　</font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 要想用JavaBeans建一个组件，你必须用Sun的Java编程语言来写程序，并且在程序中包括描述组件特性的JavaBeans语句，这些组件特性例如：用户接口的特性，以及触发一个bean和在同一个容器中或网络其他地方的其他的bean交流的事件。　　</font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bean也有持续性，持续性就是一种把一个组件的状态存在一个安全处的机制。有了这种持续性，它能使，比如说，一个组件(bean)&ldquo;记住&rdquo;某个特定用户在早些时候的用户对话中所输入的数据。　</font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JavaBeans给Java应用程序提供了OpenDoc和ActiveX接口已提供的这种复合文档的能力。</font></p>
<font face="Verdana">
<p><font face="Verdana"><strong>一、JavaBean的历史</strong></font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 最初，JavaBean的目的是为了将可以重复使用的软件代码打包标准。特别是用与帮助厂家开发在综合开发环境（<a href="http://www.itisedu.com/phrase/200604261459505.html" target="_new">IDE</a>）下使用的java软件部件。这些包括如Grid控件，用户可以将该部件拖放到开发环境中。从此，JavaBean就可以扩展为一个java web 应用的标准部件，并且JavaBean部件<a href="http://www.itisedu.com/phrase/200603061723295.html" target="_new">框架</a>已经扩展为企业版的 Bean（<a href="http://www.itisedu.com/phrase/200604241156485.html" target="_new">EJB</a>）。 </font></p>
<p><font face="Verdana"><strong>二、JavaBean和企业Bean的区别</strong></font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JavaBean 和 Server Bean（通常称为 <a href="http://www.itisedu.com/phrase/200603091138035.html" target="_new">Enterprise JavaBean</a> (EJB)）有一些基本相同之处。它们都是用一组特性创建，以执行其特定任务的对象或组件。它们还有从当前所驻留服务器上的容器获得其它特性的能力。这使得 bean 的行为根据特定任务和所在环境的不同而有所不同。 </font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Enterprise Bean 与 JavaBean 不同。JavaBean 是使用 java.beans 包开发的，它是 Java 2 标准版的一部分。JavaBean 是一台机器上同一个地址空间中运行的组件。JavaBean 是进程内组件。Enterprise Bean 是使用 javax.ejb 包开发的，它是标准 <a href="http://www.itisedu.com/phrase/200604181646475.html" target="_new">JDK</a> 的扩展，是 Java 2 Enterprise Edition 的一部分。Enterprise Bean 是在多台机器上跨几个地址空间运行的组件。因此 Enterprise Bean 是进程间组件。JavaBean 通常用作 GUI 窗口小部件，而 Enterprise Bean 则用作分布式商业对象. </font></p>
<p><br />
<strong>三、JavaBean 的发展</strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 最初，JavaBean的目的是为了将可以重复使用的软件代码打包标准。特别是用与帮助厂家开发在综合开发环境（IDE）下使用的java软件部件。这些包括如Grid控件，用户可以将该部件拖放到开发环境中。从此，JavaBean就可以扩展为一个java web 应用的标准部件，并且JavaBean部件框架已经扩展为企业版的 Bean（EJB）。</p>
<p><strong>四、JavaBean<a href="http://www.itisedu.com/phrase/200603101518295.html" target="_new">需求</a></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; avaBean是java类，属于某些特定的译码知道方针，并且扩展了适应性和范围，允许用户访问内部的属性和方法。通过这些，JavaBean类可以用于下列方法：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1．在IDE中，JavaBean的功能允许应用开发者浏览其中的方法，即使JavaBean是被编译的，并且无法利用原始的源<a href="http://www.itisedu.com/phrase/200602282323195.html" target="_new">文件</a>。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2．在 <a href="http://www.itisedu.com/phrase/200604281036245.html" target="_new">Remote Method Invocation</a>(<a href="http://www.itisedu.com/phrase/200604281025035.html" target="_new">RMI</a>) 的分布式风格中，这项功能听起来并不让人兴奋，但是在未来的包含企业版的JavaBean后，将改变这种情况。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3．为了JavaBean的属性值和状态可以保存到磁盘上。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这里说的有些简单，如果想了解更多的东西，可以查阅一些资料。</p>
<p><br />
<strong>五、JavaBean设计注意事项</strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 实际应用中，在表现对象或者处理前扩展JavaBean的设计非常有用。通常认为如果提供信息，web开发者将在功能上满足拥护对JavaBean的需求。例如： HTML中显示敏感的数据时，用户可以屏蔽的条目，如密码、电话号码等。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 良好规划设计的JavaBean是值得信赖的。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Java 中的 null 不同于 <a href="http://www.itisedu.com/phrase/200604022014515.html" target="_new">SQL</a> 中的 null</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 看这样一道测试程序：</p>
<p>public <a href="http://www.itisedu.com/phrase/200604231359565.html" target="_new">class</a> NullTest<br />
{<br />
public static void main(String[] args)<br />
{<br />
int I = 0;<br />
// int I = null； // not a valid initialization <br />
String str = null;<br />
String strZeroOutValue = &ldquo;&rdquo;;<br />
StringBuffer sb = new StringBuffer(&ldquo;Null test: String initialized <a href="http://www.itisedu.com/phrase/200604232104015.html" target="_new">as</a> null = &ldquo;);<br />
sb.append(str);<br />
sb.append(&ldquo;\n String representing a Zero Out Value:&rdquo;);<br />
sb.append(strZeroOutValue);<br />
System.out.println(sb.toString());<br />
}<br />
}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个程序将产生下面的结果：</p>
<p>Null test: String initialized as null = null<br />
String representing a Zero Out Value:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在JavaBean中， 我们将 I 变量声明为一个 int， 我们必须处理与该变量相关的值，因为I 默认的没有值，int <a href="http://www.itisedu.com/phrase/200603051002565.html" target="_new">类型</a>无法初始化为 null， 如果int 值没有进行明确的初始化，编译器将提示错误。 <br />
执行 NullTest 程序，将验证在文本中空字符串是空值的替代，用于显示 SQL 的插入和更新。如果我们需要删除一些信息，通过删除表单区域的文本，需要将数据库发送长度为0的字符串。<br />
尽管大多数数据库将空字符串作为空值进行操作，如果我们使用的数据库不支持处理空字符串的话，我们必须写入附加的java代码，来创建自己的SQL插入声明。<br />
例如：<br />
if(test.length==0)<br />
{<br />
sb.append(&ldquo;null&rdquo;);<br />
}<br />
else<br />
{<br />
sb.append(test);<br />
}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JavaBean 的范围：</p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JavaBean 的范围。 Scope 是一个具有生命时间的变量。JavaBean的范围在<br />
标志中右边进行表示。将产生一个JavaBean的快捷参考。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 说明：jsp服务器引擎将剥离 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 存在下面四种范围： 页面、 请求、 对话、 应用。</p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对话范围：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对话范围的JavaBean 主要应用与跨多个页面和时间段： 例如填充 用户信息。 添加信息并且接受回馈，保存用户最近执行页面的轨迹。对话范围JavaBean保留一些和用户对话 ID 相关的信息。这些信息来自临时的对话cookie，并在当用户关闭浏览器时，这个cookie将从<a href="http://www.itisedu.com/phrase/200603082208195.html" target="_new">客户端</a>和服务器删除。</p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 页面/请求范围：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 页面和请求范围的JavaBean有时类似表单 的bean ， 这是因为 他们大豆用与处理表单。表单需要很长的时间来处理用户的输入，通常情况下用于页面接受HTTP/POST或者GET请求。另外页面和请求范围的bean可以用于减少大型站点服务器上的负载，如果使用对话bean，耽搁的处理就可能会消耗掉很多资源。</p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 应用： </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 应用范围通常应用于服务器的部件，例如 <a href="http://www.itisedu.com/phrase/200604151904545.html" target="_new">JDBC</a> 连接池、应用监视、拥护计数和其他参与用户行为的类。</p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在Bean中限制HTML的产生：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 理论上，JavaBean 将不会产生任何HTML，因为这是jsp层负责的工作；然而，为了动态<a href="http://www.itisedu.com/phrase/200603090938465.html" target="_new">消息</a>提供一些预先准备的格式是非常有用的。产生的HTML将被标注的 JavaBean方法返回。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这里有一些非常重要的事情：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.不要试图在JavaBean返回的HTML中放置任何字体尺寸。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 并不是所有的浏览器都相同。很多浏览器无法处理完整的字体尺寸。 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.不要试图在JavaBean返回的HTML中放置任何脚本或者DHTML。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 向页面直接输出脚本或者DHTML相当于自我毁灭，因为某些浏览器版本在处理不正确的脚本时会崩溃（非常少但是有）。如果用户的JavaBean在运行时是动态的推出复杂的HTML语言，用户将陷入调试的噩梦。另外，复杂的HTML将限制JavaBean的寿命和灵活性。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.不要提供任何的选择。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果用户使用不同的系统浏览页面，可以提供一种可以替换的方法。</p>
<p><font face="Verdana"><strong>六、JavaBean的任务</strong></font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JavaBean的任务就是: &ldquo;Write once, run anywhere, reuse everywhere&rdquo;，即&ldquo;一次性编写，任何地方执行，任何地方重用&rdquo;。这个任何实际上就是要解决困扰软件工业的日益增加的复杂性，提供一个简单的、紧凑的和优秀的问题解决方案。</font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1. 一个开发良好的软件组件应该是一次性地编写，而不需要再重新编写代码以增强或完善功能。因此，JavaBean应该提供一个实际的方法来增强现有代码的利用率，而不再需要在原有代码上重新进行编程。除了在节约开发资源方面的意义外，一次性地编写JavaBean组件也可以在<a href="http://www.itisedu.com/phrase/200603292355295.html" target="_new">版本控制</a>方面起到非常好的作用。开发者可以不断地对组件进行改进，而不必从头开始编写代码。这样就可以在原有基础上不断提高组件功能，而不会犯相同的错误。</font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2. JavaBean组件在任意地方运行是指组件可以在任何环境和平台上使用，这可以满足各种交互式平台的需求。由于JavaBean是基于Java的，所以它可以很容易地得到交互式平台的支持。JavaBean组件在任意地方执行不仅是指组件可以在不同的操作平台上运行，还包括在分布式网络环境中运行。</font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.JavaBean组件在任意地方的重用说的是它能够在包括应用程序、其他组件、文档、Web站点和应用程序构造器工具的多种方案中再利用。这也许是JavaBean组件的最为重要的任务了，因为它正是JavaBean组件区别于Java程序的特点之一。Java程序的任务就是JavaBean组件所具有的前两个任务，而这第3个任务却是JavaBean组件独有的。</font></p>
<font face="Verdana">
<p><br />
<strong>七、JavaBean的设计目标及其如何被实现</strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 现在我们来看一实现JavaBean的一些具体的主要设计目标: </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.紧凑而方便的创建和使用 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JavaBean紧凑性的需求是基于JavaBean组件常常用于分布式计算环境中，这使得JavaBean组件常常需要在有限的带宽连接环境下进行传输。显然，为了适应传送的效率和速度，JavaBean组件必须是越紧凑越好。另外，为了更好地创建和使用组件，就应该使其越简单越好。通常为了提高组件的简易性和紧凑性，设计过程需要投入相对较大的功夫。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 现在已有的组件软件技术通常是使用复杂的<a href="http://www.itisedu.com/phrase/200604241228185.html" target="_new">API</a>，这常常搞得开发者在创建组件时晕头转向。因此，JavaBean组件必须不仅容易使用，而且必须便于开发。这对于组件开发者而言是至关重要的，因为这可以使得开发者不必花大量功夫在使用API进行<a href="http://www.itisedu.com/phrase/200602281641255.html" target="_new">程序设计</a>上，从而更好地对组件进行润饰，提高组件的可观赏性。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JavaBean组件大部分是基于已有的传统Java编程的类结构上的，这对于那些已经可以熟练地使用Java语言的开发者非常有利。而且这可以使得JavaBean组件更加紧凑，因为Java语言在编程上吸收了以前的编程语言中的大量优点，已经使开发出来的程序变得相当有效率。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.完全的可移植性</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JavaBean API与操作基础的独立于平台的Java系统相结合，提供了独立于平台的组件解决方案。因此，组件开发者就可以不必再为带有Java applet平台特有的类库而担心了。最终的结果都将是<a href="http://www.itisedu.com/phrase/200603021438435.html" target="_new">计算机</a>界共享可重复使用的组件，并在任何支持Java的系统中无需修改地执行。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.继承Java的强大功能</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 现有的Java结构已经提供了多种易于应用于组件的功能。其中一个比较重要的是Java本身的内置类发现功能，它可以使得对象在运行时彼此动态地交互作用，这样对象就可以从开发系统或其开发历史中独立出来。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于JavaBean而言，由于它是基于Java语言的，所以它就自然地继承了这个对于组件技术而言非常重要的功能，而不再需要任何额外开销来支持它。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JavaBean继承在现有Java功能中还有一个重要的方面，就是持久性，它保存对象并获得对象的内部状态。通过Java提供的序列化(serialization)机制，持久性可以由JavaBean自动进行处理。当然，在需要的时候，开发者也可以自己建立定制的持久性方案。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.应用程序构造器支持</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JavaBean的另一个设计目标是设计环境的问题和开发者如何使用JavaBean创建应用程序。JavaBean<a href="http://www.itisedu.com/phrase/200603122156385.html" target="_new">体系结构</a>支持指定设计环境属性和编辑机制以便于JavaBean组件的可视化编辑。这样开发者可以使用可视化应用程序构造器无缝地组装和修改JavaBean组件。就像Windows平台上的可视化开发工具VBX或OCX控件处理组件一样。通过这种方法，组件开发者可以指定在开发环境中使用和操作组件的方法。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.分布式计算支持</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 支持分布式计算虽然不是JavaBean体系结构中的核心元素，但也是JavaBean中的一个主要问题。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JavaBean使得开发者可以在任何时候使用分布式计算机制，但不使用分布式计算的核心支持来给自己增加额外负担。这正是出于JavaBean组件的紧凑性考虑的，无疑分布式计算需要大量的额外开销。</p>
<p><br />
<strong>八、JavaBean和Java</strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 虽然JavaBean和Java之间已经有了明确的界限，但在某些方面JavaBean和Java之间仍然存在着非常明显的混淆。Java确实是能够为用户创建可重用的对象，但它却没有管理这些对象相互作用的规则或标准。JavaBean通过指定定义对象之间交互作用的机制，以及大部分对象需要支持的常用行为，如持久性和实际处理等，建立了自己需要的组件模型。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 虽然当前的Java组件模型也可以运行得很好，但在传送真正的可重用性和交互操作性上仍然非常有限，Java用户需要做的最多的一件事就是创建applet并使得它们在Web 页面上相互通讯，这并非易事。JavaBean提供了一个框架包，使用这个包进行通讯就容易得多了。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JavaBean组件能够通过定义好的标准属性改进性能。总体而言，JavaBean充分发展了Java applet的功能，并结合了Java <a href="http://www.itisedu.com/phrase/200604251406195.html" target="_new">AWT</a>组件的紧凑性和可重用性。</p>
<p><br />
<strong>九、JavaBean组件的基本概念</strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JavaBean是可复用的平台独立的软件组件，开发者可以在软件构造器工具中其直接进行可视化操作。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 软件构造器工具可以是Web页面构造器、可视化应用程序构造器、CUI设计构造器或服务器应用程序构造器。有时，构造器工具也可以是一个包含子一些bean的复合文档的文档编辑器。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JavaBean可以是简单的CUI要素，如按钮或滚动条；也可以是复杂的可视化软件组件，如数据库<a href="http://www.itisedu.com/phrase/200603141659315.html" target="_new">视图</a>，有些JavaBean是没有GUI表现形式的，但这些JavaBean仍然可以使用应用程序构造器可视化地进行组合。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一个JavaBean和一个Javaapplet相似，是一个非常简单的遵循某种严格协议的Java类。每个JavaBean的功能都可能不一样，但它们都必须支持以下特征。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一个bean没有必须继承的特定的基类或接口。可视化的bean必须继承的类是java.awt.<a href="http://www.itisedu.com/phrase/200604251501485.html" target="_new">Component</a>，这样它们才能添加到可视化容器中去，非可视化bean则不需要继承这个类。有许多bean，无论是在应用程序构造器工具中，还是在最后创建好的应用程序中，都具有很强的可视化特征，但这并非每个bean必须的特征。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在使用Java编程时，并不是所有软件模块都需要转换成bean。Bean比较适合于那些具有可视化操作和定制特性的软件组件。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 从基本上说，JavaBean可以看成是一个黑盒子，即只需要知道其功能而不必管其内部结构的软件设备。黑盒子只介绍和定义其外部特征和与其他部分的接口，如按钮、窗口、颜色、形状、句柄等。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通过将系统看成使用黑盒子关联起来的通讯网络，我们可以忽略黑盒子内部的系统细节，从而有效地控制系统的整体性能。作为一个黑盒子的模型，JavaBean有3个接口面，可以独立进行开发。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1. JavaBean可以调用的方法。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2. JavaBean提供的可读写的属性。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3. JavaBean向外部发送的或从外部接收的事件。 </p>
<p><br />
<strong>九、JavaBean组件的开发环境</strong></p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 普通JavaBean组件是要分布在各自环境中，所以它们应该能够适应各种环境。虽然我们无法事先预知JavaBean要运行的确切环境，但以下两点是可以确定的：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1. bean必须能够在一个应用程序构造器工具中运行。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2. bean必须可以在产生的应用程序的运行环境中使用。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 设计环境</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 第一点说明的是bean必须可以在设计环境(design environment)中运行。在设计环境中，bean应该提供设计信息给应用程序构造器工具并允许终端用户制定bean的外　　观和行为。<br />
在传统的软件构造活动中，必须通过编译、链接之后才能看到应用程序的最终运行结果；而利用JavaBean设计的软件中，则没有这种明确的界限。使用JavaBean，就可以非常直观地设计应用程序软件，在设计过程中赋予软件生机。而且，这个过程更加容易重复开发，设计思想更加容易变成原型。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 运行环境</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 第二点说明的是bean必须可以在运行环境(run-time environment)中使用。在这个环境中，对设计信息和定制的需求并不重要。一个组件的设计环境信息和设计环境中编写的代码通常可能是非常巨大的。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 因此，我们可能需要在bean的设计环境方面和运行环境方面作一个明确的区分，这样，就可能需要在运行环境中不使用bean的任何设计环境代码来配置这个bean。所以，JavaBean就必须分别支持运行环境接口的类库和设计环境接口的类库。<br />
</p>
<p>&nbsp;</p>
<p><font face="Verdana"><strong>十、JavaBean入门</strong></font></p>
<p><font face="Verdana"><br />
一般要求<br />
首先，您必须有一个不带有参数的公用构造器。此构造器也应该通过调用各个特性的设置方法来设置特性的缺省值，例如：</font></p>
<p><font face="Verdana">public Fireworks()<br />
{<br />
setAutoStart(true);<br />
setBackground(Color.black);<br />
setSpeed(10);<br />
setRadius(40);<br />
.<br />
.<br />
.<br />
}</font></p>
<p><font face="Verdana">如果 bean 是一个从 java.awt.Component 类继承而来的可视 bean，您就应该为 bean 定义一个缺省的首选大小，例如：</font></p>
<p><font face="Verdana">public Dimension getPreferredSize()<br />
{<br />
return (new Dimension(radius*3, radius*3));<br />
}</font></p>
<p><font face="Verdana">public Dimension getMinimumSize()<br />
{<br />
return getPreferredSize();<br />
}</font></p>
<font face="Verdana">
<p><br />
特性<br />
对于您需要的每个特性，您应该有一个带有匹配公用 getter 和 setter 方法的专用实例变量，例如：</p>
<p>private int speed;<br />
.<br />
.<br />
.<br />
public int getSpeed()<br />
{<br />
return speed;<br />
}</p>
<p>public void setSpeed(int s)<br />
{<br />
speed = s;<br />
}</p>
<p>此 get 和 set 方法必须有与实例变量相同的名称，但是第一个字母要大写并以 get 和 set 开头。</p>
<p>由于连接而在任何时候更改它们的特性时，确认 Bean 在运行时行为正确也是很重要的。如果特性的更改影响到 Bean 的可视外观，您应该以此特性设置的方法来调用</p>
<p>repaint();。</p>
<p><br />
同样，如果特性的更改影响到 bean 的大小和位置，您需要确认获得验证的事物。我们建议编写您自己的 validateAll 方法，如下所示：</p>
<p>private void validateAll()<br />
{<br />
if (isValid())<br />
{<br />
Component self = this;<br />
self.invalidate();<br />
Component myParent = self.getParent();<br />
if (myParent != null)<br />
{<br />
myParent.invalidate();<br />
self = myParent;<br />
}<br />
self.validate();<br />
}<br />
}</p>
<p>然后以此特性设置的方法调用</p>
<p>validateAll();。</p>
<p><br />
　</p>
<p>bean 类将无法进行关于调用特性设置方法命令的假设。您应该写 bean 以便可以初始构造它，然后在不引起错误的同时在任何命令中设置其特性。</p>
<p><br />
操作<br />
对于每个您需要的操作，您应该有一个公用方法，例如：</p>
<p>public void start()<br />
{<br />
if(<a href="http://www.itisedu.com/phrase/200604231348385.html" target="_new">thread</a>==null)<br />
{<br />
thread=new Thread(this);<br />
thread.start();<br />
}<br />
}</p>
<p>您为操作写的方法应该在无须期待用户创建连接或设置很多特性的情况下独立操作。 例如，如果您写了一个音频 Bean，您希望通过播放操作处理打开声音的所有步骤、完成您需要的所有设置并播放声音。同样，即使声音未播放，停止操作也应起作用。</p>
<p><br />
事件<br />
对于您需要的每个事件或事件设置，您应该定义事件和侦听器类。对于此例，查看 FireworksEvent.java 源文件以及 Fireworks.java 文件。此事件类的源应该如同这样：</p>
<p>import java.awt.*;<br />
import java.util.*;</p>
<p>public class FireworksEvent extends EventObject<br />
{<br />
public static final int EXPLODED = 1;</p>
<p>int id = 0;</p>
<p>public FireworksEvent(Component source, int id)<br />
{<br />
super(source);<br />
this.id = id;<br />
}</p>
<p>public int getID()<br />
{<br />
return id;<br />
}<br />
}</p>
<p>您应该为此事件设置中的每个事件定义一个公用静态结束事件标识符，例如在此例子中的 EXPLODED。</p>
<p>对于侦听器类的源，查看 FireworksListener.java 源文件：</p>
<p>import java.util.*;</p>
<p>public interface FireworksListener extends EventListener<br />
{<br />
public abstract void exploded(FireworksEvent e);<br />
}</p>
<p>您应该为此事件设置中的每个事件定义一个公用抽象方法，例如在此例子中的 exploded。 而且，侦听器类必须扩展 EventListener ，以使 JAR 向导能够找到它。</p>
<p>然后，如果由 bean 类播送事件，它必须跟踪侦听事件的对象。要这样做，您需要定义侦听器实例变量以及 addListener 和 removeListener 方法。返回 Fireworks.java 源，例如，您将查看到：</p>
<p>private Vector listeners = new Vector();<br />
.<br />
.<br />
.<br />
public void addFireworksListener(FireworksListener f)<br />
{<br />
listeners.addElement(f);<br />
}</p>
<p>public void removeFireworksListener(FireworksListener f)<br />
{<br />
listeners.removeElement(f);<br />
}</p>
<p>最后，bean 类需要以正确的次数将事件实际播送到所有的侦听器。要这样做，您需要定义 processEvent 方法并以适当的次数调用它，例如：</p>
<p>public void processFireworksEvent(FireworksEvent e)<br />
{<br />
for (Enumeration enum = listeners.elements(); enum.hasMoreElements(); )<br />
((FireworksListener)enum.nextElement()).exploded(e);<br />
}</p>
<p>public void run()<br />
{<br />
.<br />
.<br />
.<br />
processFireworksEvent(new FireworksEvent(this, FireworksEvent.EXPLODED));<br />
}<br />
</p>
<p>(来源：<font face="Verdana">www.seasky.biz；<font face="Verdana">www.daima.com.cn；<font color="#008000">www.cnpaf.net）</font></font></font></p>
<p><font face="Verdana"></font>&nbsp;</p>
<p><br />
</p>
</font></font></font>&nbsp;</p>
</div>
          <br/>
          <span style="color:red;">
            <a href="http://bbobchen.javaeye.com/blog/77337#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 06 May 2007 11:14:41 +0800</pubDate>
        <link>http://bbobchen.javaeye.com/blog/77337</link>
        <guid>http://bbobchen.javaeye.com/blog/77337</guid>
      </item>
      <item>
        <title>在写Hibernate配置文件中需要注意的问题</title>
        <author>卒子99</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://bbobchen.javaeye.com">卒子99</a>&nbsp;
          链接：<a href="http://bbobchen.javaeye.com/blog/62905" style="color:red;">http://bbobchen.javaeye.com/blog/62905</a>&nbsp;
          发表时间: 2007年03月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>1.在many-to-one的配置中，如果insert=false，则在插手一条新的记录时，无法插入关联实体的Key，update=false情况是一样的</p>
<p>2.延迟加载问题</p>
<p>在配置文件中设置了lazy=true那级联的对象不会被全部加载到内存中。但是如果需要得到所有的级联对象，这个时候只需要事务中调用一句相关操作，如</p>
<p>public Order getOrder(String orderSN) throws NoOrderException {<br />
&nbsp;&nbsp;// TODO Auto-generated method stub<br />
&nbsp;&nbsp;Order order = this.ordersDAO.getOdrers(orderSN);<br />
&nbsp;&nbsp;if(order==null){<br />
&nbsp;&nbsp;&nbsp;throw new NoOrderException();<br />
&nbsp;&nbsp;}<br />
&nbsp;<font color="#ff0000">&nbsp;order.getOrderItem().size();<br />
</font>&nbsp;&nbsp;return order;<br />
&nbsp;}</p>
<p>即可完成加载对象的操作</p>
          <br/>
          <span style="color:red;">
            <a href="http://bbobchen.javaeye.com/blog/62905#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 20 Mar 2007 10:28:28 +0800</pubDate>
        <link>http://bbobchen.javaeye.com/blog/62905</link>
        <guid>http://bbobchen.javaeye.com/blog/62905</guid>
      </item>
      <item>
        <title>关于inverse发表点看法</title>
        <author>卒子99</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://bbobchen.javaeye.com">卒子99</a>&nbsp;
          链接：<a href="http://bbobchen.javaeye.com/blog/62904" style="color:red;">http://bbobchen.javaeye.com/blog/62904</a>&nbsp;
          发表时间: 2007年03月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>看了很多关于inverse的文章，理解得也不是很透彻，这次做了这个项目，遇到这方面问题，就总结了一样关于inverse的配置，</p>
<p>1.关系parent和children的例子也已经说了怎么去配置一对多的关系，这个例子已经说明了在set端设置inverse=true，原因很简单，child长大了，不需要什么事情都要parent带到</p>
<p>其实在我看来，inverse=true实际上是去解放了one那一方，在这儿就是指parent对象，他不需要在每次更新的时候，都把children都加载出来。像在下面的代码中，不会有什么问题，应该都在一个session中完成的</p>
<p>&nbsp;ParentManager manager=(ParentManager) getBean(&quot;parentManager&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Parent parent=manager.getParent(&quot;pppp&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parent.setName(&quot;bob&quot;);manager.save(parent);</p>
<p>所以不会觉得有什么问题。但是在WEB应用的三层结构中，通常要把模型传递到表现层中，完成更新操作，那这个时候inverse=true的优势就明显了，他可以不用考虑Children就完成自身的更新</p>
<p>2.当inverse=false会发生什么？</p>
<p>那天也是无意注意到这个问题，突然把系统的所有inverse都设置成了false</p>
<p>当在插入一个新的对象的时候，不会出现什么问题。但是在更新父对象的时候，却发生了我不想看到的,Customer和Order是一对多的关系</p>
<p>Hibernate: update customer.name=?..........where customerName=? and version=?</p>
<p>Hibernate: update orders set customer=null where customer=?</p>
<p>在更新了customer信息后，同时把订单中该用户的用户置为null，换句话说就是断了两者之间的联系。再看看代码</p>
<p><br />
&nbsp;&nbsp;CustomerForm customerForm = (CustomerForm) form;<br />
&nbsp;&nbsp;Customer customer = new Customer();<br />
&nbsp;&nbsp;convertObject(customerForm, customer);<br />
&nbsp;&nbsp;CustomerManager manager = (CustomerManager) getBean(&quot;customerManager&quot;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p>&nbsp; manage.save(customer);</p>
<p>customerForm是通过struts的form理到来自表单的数据。最后通过业务层的代码调用Hibernate的saveOrUpdate()方法进行保存。这个时候我发现我并未去加载和customer关系的order，</p>
<p>然后我修改了代码，试着把所有的该customer的order都提出来，并在保存前调用了</p>
<p>customer .setOrder(order);</p>
<p>结果发生异常</p>
<p><br />
org.springframework.orm.hibernate3.HibernateSystemException: a different object with the same identifier value was already associated with the session: [com.us.ebuy.model.Customer#123]; nested exception is org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.us.ebuy.model.Customer#123]<br />
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.us.ebuy.model.Customer#123]<br />
&nbsp;at org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:629)<br />
&nbsp;at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:258)<br />
&nbsp;at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:216)<br />
&nbsp;at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)<br />
&nbsp;at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)<br />
&nbsp;at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:531)<br />
&nbsp;at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:523)<br />
&nbsp;at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:519)<br />
&nbsp;at org.springframework.orm.hibernate3.HibernateTemplate$18.doInHibernate(HibernateTemplate.java:690)<br />
&nbsp;at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:365)<br />
&nbsp;at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:687)<br />
&nbsp;at com.us.ebuy.dao.hibernate.BaseDAOHibernate.saveObject(BaseDAOHibernate.java:55)<br />
&nbsp;at com.us.ebuy.users.dao.hibernate.CustomerDAOHibernate.saveCustomer(CustomerDAOHibernate.java:64)<br />
&nbsp;at com.us.ebuy.users.service.impl.CustomerManagerImpl.saveCustomer(CustomerManagerImpl.java:52)<br />
&nbsp;at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)<br />
&nbsp;at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)<br />
&nbsp;at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)<br />
&nbsp;at java.lang.reflect.Method.invoke(Method.java:585)<br />
&nbsp;at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:335)<br />
&nbsp;at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:181)<br />
&nbsp;at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:148)<br />
&nbsp;at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)<br />
&nbsp;at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)<br />
&nbsp;at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)<br />
&nbsp;at $Proxy2.saveCustomer(Unknown Source)<br />
&nbsp;at com.us.ebuy.users.action.CustomerAction.save(CustomerAction.java:133)<br />
&nbsp;at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)<br />
&nbsp;at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)<br />
&nbsp;at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)<br />
&nbsp;at java.lang.reflect.Method.invoke(Method.java:585)<br />
&nbsp;at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:274)<br />
&nbsp;at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:194)<br />
&nbsp;at com.us.ebuy.action.BaseAction.execute(BaseAction.java:143)<br />
&nbsp;at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:419)<br />
&nbsp;at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)<br />
&nbsp;at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)<br />
&nbsp;at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)<br />
&nbsp;at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)<br />
&nbsp;at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)<br />
&nbsp;at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)<br />
&nbsp;at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)<br />
&nbsp;at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:174)<br />
&nbsp;at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)<br />
&nbsp;at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)<br />
&nbsp;at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)<br />
&nbsp;at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:75)<br />
&nbsp;at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)<br />
&nbsp;at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)<br />
&nbsp;at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)<br />
&nbsp;at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)<br />
&nbsp;at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)<br />
&nbsp;at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)<br />
&nbsp;at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)<br />
&nbsp;at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)<br />
&nbsp;at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)<br />
&nbsp;at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)<br />
&nbsp;at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)<br />
&nbsp;at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)<br />
&nbsp;at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)<br />
&nbsp;at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)<br />
&nbsp;at java.lang.Thread.run(Thread.java:595)<br />
</p>
<p>可以看出，在更新的时候，他执行了插入操作，才会认为有重复的key，后来我想到了使用hibernate的merge方法，通过合作，才能完成customer的更新操作，但这这种更新方法显然是我们不愿意看到的。后来通过检测配置文件才发现，set　元素的inverse=false，最后我想是这儿的原因，改为false后，还是通过saveOrUpdate()方法更新对象，问题解决了。</p>
<p>通过上面的问题，可以更进一步的清楚了，Hibernate在对对待持久化的对象和游离状态的对象是不一样的，上述问题通常都是发生在处理游离状态的对象时候，而在三层结构中，我们会经常处理这种问题的，看来是要重新理解对象的状态问题。</p>
          <br/>
          <span style="color:red;">
            <a href="http://bbobchen.javaeye.com/blog/62904#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 20 Mar 2007 10:25:25 +0800</pubDate>
        <link>http://bbobchen.javaeye.com/blog/62904</link>
        <guid>http://bbobchen.javaeye.com/blog/62904</guid>
      </item>
      <item>
        <title>成都支付宝面试归来</title>
        <author>卒子99</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://bbobchen.javaeye.com">卒子99</a>&nbsp;
          链接：<a href="http://bbobchen.javaeye.com/blog/60690" style="color:red;">http://bbobchen.javaeye.com/blog/60690</a>&nbsp;
          发表时间: 2007年03月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          昨天，支付宝在成都招聘，一直关心阿里巴巴的招聘信息，所以一收到消息，马上从外地赶过去。到了，才发现，这次他们只招有工作经验的。虽然我是应届毕业的，但是在读研期间，也在公司上过班，有过几个项目开发经验，所以当时我就好说歹说，表现自己一定能胜任这份工作，不会比别人的差的。最后，他们的技术总监总算给了我一个机会，让我面试工，呵呵，这儿再一次感谢支付宝的HR和他们的技术总监Tommy(不知道拼对了么)。<br />   因为我做过多个项目，一直对架构很感兴趣，最近又一直在研究Spring,Hibernate,Struts的源代码，而且前面也有了面试经验，所以前面的技术问题都比较简单的搞定了。但最后一个现现场编程题，现在在我看来，确实让我这个缺乏大型项目经验的人露了马脚。<br />   题目是这样子的：写一个类，读一个txt文件，从中找到aliy这个词，并记录该字符串所在的行数和每一行中的位置。<br />   我第一反应这个问题很简单，每次循环读一行字符串，然后用String.index方法就可以搞定了。但是在写代码的时候，我却把PrintReader搞错了，写成PrintWriter，唉，用管了IDE就是这样子啊。后来就和技术总监聊这个类还需要什么改进的地方。在他的提醒下，我才注意到。<br />   第一   每一行不一定只有一个关键词，这是我所没有注意到的，当然在实际的开发中我后来是可以发现的。后来我还想到用正则表达式。还有就是字符可以设置token，直接split几段，还是能找到，当然这三种方法的效率，我确实不太清楚。<br />   第二  性能的问题，他说，如果是读一个1G的文件，那怎么办。我当时第一反应是那就分段读，然后用多线程处理每一段的字符串。这个问题是我回答的最失败的地方，在回来的车上，我才反应过来，准备的回答应该是通过设置缓存区来读文件。<br />   回答的如此差，我也不报什么希望了。不过还是要给朋友们提点经验吧，特别是那些刚毕业的，有点项目经验的朋友，因为我们可能面临的问题都是这个。那个时候我在公司上班的时候，有写代码，也有做框架，项目经理始终说的“先把做出来再改进” 事实上在小公司真的很忙很累，对于没有什么经验的人来说，能做出来已经不错了，所以后来那个“再改进”通常就被忽略了，像面对上面的那个问题，虽然事后能想到，但是对于有工作经验的人来，马上就能够反应过来。所以在以后的开发中，除了灵活运用基础知识，还就要从代码的质量方面去多考虑，这样才能够慢慢成长。
          <br/>
          <span style="color:red;">
            <a href="http://bbobchen.javaeye.com/blog/60690#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 18 Mar 2007 13:00:58 +0800</pubDate>
        <link>http://bbobchen.javaeye.com/blog/60690</link>
        <guid>http://bbobchen.javaeye.com/blog/60690</guid>
      </item>
      <item>
        <title>RCP应用程序开发系列（3）－－入门程序代码分析</title>
        <author>卒子99</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://bbobchen.javaeye.com">卒子99</a>&nbsp;
          链接：<a href="http://bbobchen.javaeye.com/blog/54532" style="color:red;">http://bbobchen.javaeye.com/blog/54532</a>&nbsp;
          发表时间: 2007年02月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p class="docText">前面介绍了一些文字性的东西，现在还是来看看代码，这样才感觉踏实</p>
<a name="ch04lev2sec1"></a>
<h4 class="docSection2Title">1. Application</h4>
<p class="docText"><a name="idd1e3608"></a><a name="idd1e3615"></a><a name="idd1e3622"></a>Application的作用就是应用程序或产品(product)的入口，它和Java系统中，类定义的main()方法作用一样.&nbsp;当Runtime启动的时候，应用程序开始运行，应用程序退出的时候，Eclipse关闭.</p>
<p class="docText">PDE向导使用 Hello RCP&nbsp;模板产生了edu.swust.cs.soapfirewall<tt>.Application</tt> 类，如下。 Applications必须实现 <tt>IPlatformRunnable接口，这个接口定义了一个</tt> <tt>run()方法，可以把这个方法想像成</tt> <tt>main()</tt> 方法.</p>
<pre><div class="code_title">java 代码</div><div class="dp-highlighter"><div class="bar"></div><ol class="dp-j"><li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Application&nbsp;</span><span class="keyword">implements</span><span>&nbsp;IPlatformRunnable&nbsp;{ &nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;Object&nbsp;run(Object&nbsp;args)&nbsp;</span><span class="keyword">throws</span><span>&nbsp;Exception&nbsp;{ &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;Display&nbsp;display&nbsp;=&nbsp;PlatformUI.createDisplay(); &nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{ &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">int</span><span>&nbsp;returnCode&nbsp;=&nbsp;PlatformUI.createAndRunWorkbench( &nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;display,&nbsp;</span><span class="keyword">new</span><span>&nbsp;ApplicationWorkbenchAdvisor()); &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(returnCode&nbsp;==&nbsp;PlatformUI.RETURN_RESTART)&nbsp;{ &nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;IPlatformRunnable.EXIT_RESTART; &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;IPlatformRunnable.EXIT_OK; &nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">finally</span><span>&nbsp;{ &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;display.dispose(); &nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li><li class=""><span>}&nbsp;&nbsp;</span></li></ol></div></pre>
<br />
<p class="docText">关键的代码就是创建了一个 <tt>Display</tt> 对象，并调用<tt>PlatformUI.createAnd RunWorkbench(Display, WorkbenchWindowAdvisor)方法</tt>启动了一个Eclipse工作台 .它会打开一个窗口，并一直循环下去，止到有事件触发退出应用程序.在returning前，必须dispose创建的<tt>Display，因为SWT都是使用的本地的API，所以必须释放系统分配的资源，MyEclipse用起来会，系统会越用越慢，估计就是这个原因</tt>.</p>
<a name="ch04note05"></a>
<div class="docNote"></div>
<p class="docText">application 类必须和 Eclipse Runtime