﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-和风细雨-随笔分类-J2SE</title><link>http://www.blogjava.net/junglesong/category/29588.html</link><description>世上本无难事，心以为难，斯乃真难。苟不存一难之见于心，则运用之术自出。</description><language>zh-cn</language><lastBuildDate>Tue, 29 Apr 2008 09:40:55 GMT</lastBuildDate><pubDate>Tue, 29 Apr 2008 09:40:55 GMT</pubDate><ttl>60</ttl><item><title>特殊的String</title><link>http://www.blogjava.net/junglesong/archive/2008/04/29/197268.html</link><dc:creator>和风细雨</dc:creator><author>和风细雨</author><pubDate>Tue, 29 Apr 2008 07:10:00 GMT</pubDate><guid>http://www.blogjava.net/junglesong/archive/2008/04/29/197268.html</guid><wfw:comment>http://www.blogjava.net/junglesong/comments/197268.html</wfw:comment><comments>http://www.blogjava.net/junglesong/archive/2008/04/29/197268.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junglesong/comments/commentRss/197268.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junglesong/services/trackbacks/197268.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<p><strong>String的特殊之处</strong></p>
<p>String是Java编程中很常见的一个类,这个类的实例是不可变的(immutable ).为了提高效率,JVM内部对其操作进行了一些特殊处理,本文就旨在于帮助大家辨析这些特殊的地方.<br />
在进入正文之前,你需要澄清这些概念:<br />
1) 堆与栈<br />
2) 相同与相等,==与equals<br />
3) =的真实意义.</p>
<p><strong>栈与堆</strong> </p>
<p>1. 栈(stack)与堆(heap)都是Java用来在内存中存放数据的地方。与C++不同，Java自动管理栈和堆，程序员不能直接地设置栈或堆。每个函数都有自己的栈,而一个程序只有一个堆.<br />
2. 栈的优势是，存取速度比堆要快，仅次于直接位于CPU中的寄存器。但缺点是，存在栈中的数据大小与生存期必须是确定的，缺乏灵活性。另外，栈数据可以共享，详见第3点。堆的优势是可以动态地分配内存大小，生存期也不必事先告诉编译器，Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是，由于要在运行时动态分配内存，存取速度较慢。 3. Java中的数据类型有两种。 　　一种是基本类型(primitive types), 共有8种，即int, short, long, byte, float, double, boolean, char(注意，并没有string的基本类型)。这种类型的定义是通过诸如int a = 3; long b = 255L;的形式来定义的，称为自动变量。值得注意的是，自动变量存的是字面值，不是类的实例，即不是类的引用，这里并没有类的存在。如int a = 3; 这里的a是一个指向int类型的引用，指向3这个字面值。这些字面值的数据，由于大小可知，生存期可知(这些字面值固定定义在某个程序块里面，程序块退出后，字段值就消失了)，出于追求速度的原因，就存在于栈中。 　　另外，栈有一个很重要的特殊性，就是存在栈中的数据可以共享。假设我们同时定义 　　int a = 3;&nbsp; 　　int b = 3； 　　编译器先处理int a = 3；首先它会在栈中创建一个变量为a的引用，然后查找有没有字面值为3的地址，没找到，就开辟一个存放3这个字面值的地址，然后将a指向3的地址。接着处理int b = 3；在创建完b的引用变量后，由于在栈中已经有3这个字面值，便将b直接指向3的地址。这样，就出现了a与b同时均指向3的情况。 　　特别注意的是，这种字面值的引用与类对象的引用不同。假定两个类对象的引用同时指向一个对象，如果一个对象引用变量修改了这个对象的内部状态，那么另一个对象引用变量也即刻反映出这个变化。相反，通过字面值的引用来修改其值，不会导致另一个指向此字面值的引用的值也跟着改变的情况。如上例，我们定义完a与 b的值后，再令a=4；那么，b不会等于4，还是等于3。在编译器内部，遇到a=4；时，它就会重新搜索栈中是否有4的字面值，如果没有，重新开辟地址存放4的值；如果已经有了，则直接将a指向这个地址。因此a值的改变不会影响到b的值。 　　另一种是包装类数据，如Integer, String, Double等将相应的基本数据类型包装起来的类。这些类数据全部存在于堆中，Java用new()语句来显示地告诉编译器，在运行时才根据需要动态创建，因此比较灵活，但缺点是要占用更多的时间。 </p>
<p><strong>相同与相等,==与equals</strong></p>
<p>在Java中,相同指的是两个变量指向的地址相同,地址相同的变量自然值相同;而相等是指两个变量值相等,地址可以不同.<br />
相同的比较使用==,而相等的比较使用equals.<br />
对于字符串变量的值比较来说,我们一定要使用equals而不是==.</p>
<p><strong>=的真实意义</strong></p>
<p>=即赋值操作,这里没有问题,关键是这个值有时是真正的值,有的是地址,具体来说会根据等号右边的部分而变化.<br />
如果是基本类型(八种),则赋值传递的是确定的值,即把右边变量的值传递给左边的变量.<br />
如果是类类型,则赋值传递的是变量的地址,即把等号左边的变量地址指向等号右边的变量地址.</p>
<p><strong>指出下列代码的输出</strong></p>
<p>String andy="andy";<br />
String bill="andy";</p>
<p>if(andy==bill){<br />
&nbsp; System.out.println("andy和bill地址相同");<br />
}<br />
else{<br />
&nbsp; System.out.println("andy和bill地址不同");<br />
}</p>
<p><strong>String str=&#8220;andy&#8221;的机制分析</strong></p>
<p>上页代码的输出是andy和bill地址相同.<br />
当通过String str=&#8220;andy&#8221;;的方式定义一个字符串时,JVM先在栈中寻找是否有值为&#8220;andy&#8221;的字符串,如果有则将str指向栈中原有字符串的地址;如果没有则创建一个,再将str的地址指向它. String andy=&#8220;andy&#8221;这句代码走的是第二步,而String bill=&#8220;andy&#8221;走的是第一步,因此andy和bill指向了同一地址,故而andy==bill,andy和bill地址相等,所以输出是andy和bill地址相同.<br />
这样做能节省空间—少创建一个字符串;也能节省时间—定向总比创建要省时.</p>
<p>指出下列代码的输出</p>
<p>String andy="andy";<br />
String bill="andy";<br />
bill="bill";</p>
<p>if(andy==bill){<br />
&nbsp; System.out.println("andy和bill地址相同");<br />
}<br />
else{<br />
&nbsp; System.out.println("andy和bill地址不同");<br />
}</p>
<p><strong>输出及解释</strong></p>
<p>上页代码的输出是:andy和bill地址不同<br />
当执行bill=&#8220;bill&#8221;一句时,外界看来好像是给bill变换了一个新值bill,但JVM的内部操作是把栈变量bill的地址重新指向了栈中一块值为bill的新地址,这是因为字符串的值是不可变的,要换值(赋值操作)只有将变量地址重新转向. 这样andy和bill的地址在执行bill=&#8220;bill&#8221;一句后就不一样了,因此输出是andy和bill地址不同.</p>
<p><strong>指出下列代码的输出</strong></p>
<p>String andy=new String("andy");<br />
String bill=new String("andy");</p>
<p>// 地址比较<br />
if(andy==bill){<br />
&nbsp; System.out.println("andy和bill地址相同");<br />
}<br />
else{<br />
&nbsp; System.out.println("andy和bill地址不同");<br />
}</p>
<p>// 值比较<br />
if(andy.equals(bill)){<br />
&nbsp; System.out.println("andy和bill值相等");<br />
}<br />
else{<br />
&nbsp; System.out.println("andy和bill值不等");<br />
}</p>
<p><strong>输出及机制分析</strong></p>
<p>andy和bill地址不同<br />
andy和bill值相等<br />
我们知道new操作新建出来的变量一定处于堆中,字符串也是一样.<br />
只要是用new()来新建对象的，都会在堆中创建，而且其字符串是单独存值的,即每个字符串都有自己的值,自然地址就不会相同.因此输出了andy和bill地址不同.<br />
equals操作比较的是值而不是地址,地址不同的变量值可能相同,因此输出了andy和bill值相等.</p>
<p><strong>指出下列代码的输出</strong></p>
<p>String andy=new String("andy");<br />
String bill=new String(andy);</p>
<p>// 地址比较<br />
if(andy==bill){<br />
&nbsp; System.out.println("andy和bill地址相同");<br />
}<br />
else{<br />
&nbsp; System.out.println("andy和bill地址不同");<br />
}</p>
<p>// 值比较<br />
if(andy.equals(bill)){<br />
&nbsp; System.out.println("andy和bill值相等");<br />
}<br />
else{<br />
&nbsp; System.out.println("andy和bill值不等");<br />
}</p>
<p><br />
<strong>输出</strong></p>
<p>andy和bill地址不同<br />
andy和bill值相等</p>
<p>道理仍和第八页相同.只要是用new()来新建对象的，都会在堆中创建，而且其字符串是单独存值的,即每个字符串都有自己的值,自然地址就不会相同.</p>
<p><strong>指出下列代码的输出</strong></p>
<p>String andy="andy";<br />
String bill=new String(&#8220;Bill");<br />
bill=andy;</p>
<p>// 地址比较<br />
if(andy==bill){<br />
&nbsp; System.out.println("andy和bill地址相同");<br />
}<br />
else{<br />
&nbsp; System.out.println("andy和bill地址不同");<br />
}</p>
<p>// 值比较<br />
if(andy.equals(bill)){<br />
&nbsp; System.out.println("andy和bill值相等");<br />
}<br />
else{<br />
&nbsp; System.out.println("andy和bill值不等");<br />
}</p>
<p><br />
<strong>输出及解析</strong></p>
<p>andy和bill地址相同<br />
andy和bill值相等<br />
String bill=new String(&#8220;Bill&#8221;)一句在栈中创建变量bill,指向堆中创建的&#8221;Bill&#8221;,这时andy和bill地址和值都不相同;而执行bill=andy;一句后,栈中变量bill的地址就指向了andy,这时bill和andy的地址和值都相同了.而堆中的&#8221;Bill&#8221;则没有指向它的指针,此后这块内存将等待被垃圾收集.</p>
<p><br />
指出下列代码的输出</p>
<p>String andy="andy";<br />
String bill=new String("bill");<br />
andy=bill;</p>
<p>// 地址比较<br />
if(andy==bill){<br />
&nbsp; System.out.println("andy和bill地址相同");<br />
}<br />
else{<br />
&nbsp; System.out.println("andy和bill地址不同");<br />
}</p>
<p>// 值比较<br />
if(andy.equals(bill)){<br />
&nbsp; System.out.println("andy和bill值相等");<br />
}<br />
else{<br />
&nbsp; System.out.println("andy和bill值不等");<br />
}</p>
<p><strong>输出</strong></p>
<p>andy和bill地址相同<br />
andy和bill值相等</p>
<p>道理同第十二页</p>
<p><strong>结论</strong></p>
<p>使用诸如String str = &#8220;abc&#8221;；的语句在栈中创建字符串时时，str指向的字符串不一定会被创建！唯一可以肯定的是，引用str本身被创建了。至于这个引用到底是否指向了一个新的对象，必须根据上下文来考虑，如果栈中已有这个字符串则str指向它,否则创建一个再指向新创建出来的字符串. 清醒地认识到这一点对排除程序中难以发现的bug是很有帮助的。<br />
使用String str = &#8220;abc&#8221;；的方式，可以在一定程度上提高程序的运行速度，因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str = new String(&#8220;abc&#8221;)；的代码，则一概在堆中创建新对象，而不管其字符串值是否相等，是否有必要创建新对象，从而加重了程序的负担。<br />
如果使用new()来新建字符串的，都会在堆中创建字符串，而且其字符串是单独存值的,即每个字符串都有自己的值,且其地址绝不会相同<br />
当比较包装类里面的数值是否相等时，用equals()方法；当测试两个包装类的引用是否指向同一个对象时，用==。<br />
由于String类的immutable性质，当String变量需要经常变换其值如SQL语句拼接,HTML文本输出时，应该考虑使用StringBuffer类，以提高程序效率。 </p>
<img src ="http://www.blogjava.net/junglesong/aggbug/197268.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junglesong/" target="_blank">和风细雨</a> 2008-04-29 15:10 <a href="http://www.blogjava.net/junglesong/archive/2008/04/29/197268.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>集合综述</title><link>http://www.blogjava.net/junglesong/archive/2008/03/04/183595.html</link><dc:creator>和风细雨</dc:creator><author>和风细雨</author><pubDate>Tue, 04 Mar 2008 00:33:00 GMT</pubDate><guid>http://www.blogjava.net/junglesong/archive/2008/03/04/183595.html</guid><wfw:comment>http://www.blogjava.net/junglesong/comments/183595.html</wfw:comment><comments>http://www.blogjava.net/junglesong/archive/2008/03/04/183595.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junglesong/comments/commentRss/183595.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junglesong/services/trackbacks/183595.html</trackback:ping><description><![CDATA[<p><strong>1.Collection接口</strong></p>
<p>Java集合类中最基础的接口是Collection，它定义了两个基本方法：<br />
Public interface Collection&lt;E&gt;{<br />
&nbsp;&nbsp;&nbsp; boolean add(E element);<br />
&nbsp;&nbsp;&nbsp; Iterator&lt;E&gt; iterator();<br />
}<br />
add是向Collection中添加一个元素，当添加的内容确实对Collection发生了有效变更的话add方法返回真，否则返回假，比如你向一个Set添加重复的元素时，Set内容不会变化，add方法会返回假。<br />
iterator方法返回实现了Iterator接口的对象，你可以借此对Collection中的内容进行挨个遍历。</p>
<p><strong>2.Iterator接口</strong></p>
<p>Iterator有三个方法：<br />
Public interface Iterator&lt;E&gt;{<br />
&nbsp;&nbsp; E next();<br />
&nbsp;&nbsp; boolean hasNext();<br />
&nbsp;&nbsp; void remove();<br />
}<br />
通过重复调用next方法，你可以挨个遍历Collection中的元素。然而，当遍历到Collection末端时，此方法会抛出一个NoSuchElementException异常，因此在遍历时你就需要hasNext方法和next方法配合使用。 hasNext方法在当前遍历位置后仍有元素时会返回真。配合例子如下：<br />
Collection&lt;String&gt; c=&#8230;.;<br />
Iterator&lt;String&gt; iterator=c.iterator();<br />
While(iterator.hasNext()){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String str=iterator.next();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;&#8230;.<br />
}<br />
remove方法能删除上一次调用next时指向的元素,注意不能连续两次调用remove方法,否则会抛出IllegalStateException.</p>
<p><strong>3.Collection接口的其它方法</strong></p>
<p>int size():返回当前存储的元素个数<br />
boolean isEmpty():当集合中没有元素时返回真<br />
boolean contains(Object obj):当集合中有元素和obj值相等时返回真.<br />
boolean containsAll(Collection&lt;?&gt; other):当集合包含另一集合的全部元素时返回真.<br />
bBoolean addAll (Collection&lt;? extends E&gt; other):把其它集合中的元素添加到集合中来,当此集合确实发生变化时返回真.<br />
boolean remove(Object obj):删除一个和obj值相等的元素,当吻合的元素被删除时返回真.<br />
boolean removeAll(Collection&lt;?&gt; other) :从本集合中删除和另一集合中相等的元素,当本集合确实发生变化时返回真.(差集)<br />
void clear():清除集合中的所有元素<br />
boolean retainAll(Collection&lt;?&gt; other) :从本集合中删除和另一集合中不相等的元素,当本集合确实发生变化时返回真.(交集)<br />
Object[] toArray()<br />
返回由集合中元素组成的数组</p>
<p><strong>4.实现了Collection接口的具体类</strong></p>
<p>ArrayList:带下标的队列,增加和收缩时都是动态的.<br />
LinkedList:有序队列,在任意位置插入和删除都是高效的.<br />
HashSet:不存在重复的非排序集合.<br />
TreeSet:自动排序的不存在重复的集合.<br />
LinkedHashSet:保持了插入时顺序的哈希表<br />
PriorityQueue:优先级队列,能有效的删除最小元素.</p>
<p><strong>5.没有重复元素存在的集合HashSet</strong></p>
<p>HashSet通过哈希码来查找一个元素,这比链表的整体查找要迅速得多,但是由此带来的缺陷时它不能保持插入时的顺序.<br />
由于HashSet靠hash码来识别元素,因此它不能包含重复元素,当集合中已经存在值相等的元素时,再次添加同样的元素HashSet不会发生变化.</p>
<p>Set&lt;String&gt; hashSet=new HashSet&lt;String&gt;();<br />
hashSet.add("Andy");<br />
hashSet.add("Andy");<br />
hashSet.add("Bill");<br />
hashSet.add("Cindy");<br />
hashSet.add("Bill");<br />
hashSet.add("Cindy");</p>
<p>Iterator&lt;String&gt; iter=hashSet.iterator();</p>
<p>while(iter.hasNext()){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(iter.next());<br />
}<br />
输出:<br />
Cindy<br />
Andy<br />
Bill</p>
<p><strong>6.自动排序的集合 TreeSet</strong></p>
<p>TreeSet和HashSet类似但它值得一提的一点是无论你以何顺序插入元素,元素都能保持正确的排序位置,这时因为TreeSet是以红黑树的形式存储数据,在插入时就能找到正确的位置.注意插入TreeSet的元素都要实现Comparable接口.<br />
例:<br />
SortedSet&lt;String&gt; treeSet=new TreeSet&lt;String&gt;();<br />
treeSet.add("Andy");<br />
treeSet.add("Andy");<br />
treeSet.add("Bill");<br />
treeSet.add("Cindy");<br />
treeSet.add("Bill");<br />
treeSet.add("Cindy");</p>
<p>Iterator&lt;String&gt; iter=treeSet.iterator();</p>
<p>while(iter.hasNext()){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(iter.next());<br />
}</p>
<p>输出:<br />
Andy<br />
Bill<br />
Cindy</p>
<p><strong>7.优先级队列PriorityQueue</strong></p>
<p>PriorityQueue使用一种名为堆的二叉树高效的存储数据,它检索数据是按排序的顺序而插入则随意,当你调用remove方法时,你总能得到最小的元素.但PriorityQueue并不按序排列它的元素,当你遍历时它是不会排序的,这也没有必要. 在制作一个按优先级执行日程安排或事务安排时你应该首先想到PriorityQueue。<br />
例:<br />
PriorityQueue&lt;String&gt; pq=new PriorityQueue&lt;String&gt;();<br />
pq.add("Cindy");<br />
pq.add("Felix");<br />
pq.add("Andy");<br />
pq.add("Bill");</p>
<p>Iterator&lt;String&gt; iter=pq.iterator();</p>
<p>while(iter.hasNext()){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(iter.next());<br />
}</p>
<p>while(!pq.isEmpty()){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(pq.remove());<br />
}</p>
<p><strong>8.保持插入顺序的哈希表LinkedHashMap</strong></p>
<p>从1.4起Java集合类中多了一个LinkedHashMap,它在HashMap的基础上增加了一个双向链表,由此LinkedHashMap既能以哈希表的形式存储数据,又能保持查询时的顺序.<br />
Map&lt;String,String&gt; members=new LinkedHashMap&lt;String,String&gt;();</p>
<p>members.put("001", "Andy");<br />
members.put("002", "Bill");<br />
members.put("003", "Cindy");<br />
members.put("004", "Dell");</p>
<p>Iterator&lt;String&gt; iter=members.keySet().iterator();</p>
<p>while(iter.hasNext()){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(iter.next());<br />
}</p>
<p>Iterator&lt;String&gt; iter2=members.values().iterator();</p>
<p>while(iter2.hasNext()){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(iter2.next());<br />
}</p>
<p><strong>9.自动按键进行排序的哈希表TreeMap</strong></p>
<p>Map&lt;String,String&gt; members=new TreeMap&lt;String,String&gt;();</p>
<p>members.put("001", "Andy");<br />
members.put("006", "Bill");<br />
members.put("003", "Cindy");<br />
members.put("002", "Dell");<br />
members.put("004", "Felex");</p>
<p>for(Map.Entry&lt;String,String&gt; entry:members.entrySet()){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Key="+entry.getKey()+"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Value="+entry.getValue());<br />
}</p>
<p><br />
<strong>10.1 集合工具类Collections的方法unmodifiable</strong></p>
<p>此方法构建一个不可更改的集合视图，当使用其修改方法时会抛出一个UnsupportedOperationException<br />
static Collection&lt;E&gt; unmodifiableCollection(Collection&lt;E&gt; c)<br />
static List&lt;E&gt; unmodifiableList (List&lt;E&gt; c)<br />
static Set&lt;E&gt; unmodifiableSet (Set&lt;E&gt; c)<br />
static SortedSet&lt;E&gt; unmodifiableSortedSet (SortedSet&lt;E&gt; c)<br />
static Map&lt;K，V&gt; unmodifiableMap (Map&lt;K，V&gt;&nbsp; c)<br />
static SortedMap&lt;K，V&gt; unmodifiableSortedMap (SortedMap&lt;K，V&gt; c)</p>
<p><strong>10.2 集合工具类Collections的方法synchronized</strong></p>
<p>此方法会返回一个线程安全的集合视图<br />
static Collection&lt;E&gt; synchronizedCollection(Collection&lt;E&gt; c)<br />
static List&lt;E&gt; synchronizedList (List&lt;E&gt; c)<br />
static Set&lt;E&gt; synchronizedSet (Set&lt;E&gt; c)<br />
static SortedSet&lt;E&gt; synchronizedSortedSet (SortedSet&lt;E&gt; c)<br />
static Map&lt;K，V&gt;&nbsp; synchronizedMap (Map&lt;K，V&gt;&nbsp; c)<br />
static SortedMap&lt;K，V&gt;&nbsp; synchronizedSortedMap (SortedMap&lt;K，V&gt;&nbsp; c)</p>
<p><br />
集合类静态类图</p>
<img alt="" src="http://www.blogjava.net/images/blogjava_net/junglesong/clections.jpg" border="0" />
<img src ="http://www.blogjava.net/junglesong/aggbug/183595.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junglesong/" target="_blank">和风细雨</a> 2008-03-04 08:33 <a href="http://www.blogjava.net/junglesong/archive/2008/03/04/183595.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>泛型类(Generic Class)</title><link>http://www.blogjava.net/junglesong/archive/2008/03/03/183578.html</link><dc:creator>和风细雨</dc:creator><author>和风细雨</author><pubDate>Mon, 03 Mar 2008 14:55:00 GMT</pubDate><guid>http://www.blogjava.net/junglesong/archive/2008/03/03/183578.html</guid><wfw:comment>http://www.blogjava.net/junglesong/comments/183578.html</wfw:comment><comments>http://www.blogjava.net/junglesong/archive/2008/03/03/183578.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junglesong/comments/commentRss/183578.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junglesong/services/trackbacks/183578.html</trackback:ping><description><![CDATA[<p><strong>C++模版(Template)类在Java中的体现-泛型类</strong></p>
<p>泛型类是C++模版(Template)类思想在java新版本(1.5)中的应用体现.当对类型相同的对象操作时泛型是很有用的,但其中对象的具体类型直到对类实例化时才能知道.这种方式非常适合于包含关联项目的集合或设计查找的类.</p>
<p><strong>泛型类的使用示例一</strong></p>
<p>/**<br />
&nbsp;* 泛型类示例一,成员变量为链表,T可以指代任意类类型.<br />
&nbsp;* @author sitinspring<br />
&nbsp;*<br />
&nbsp;* @date 2007-12-28<br />
&nbsp;*/<br />
public class Service&lt;T&gt;{<br />
&nbsp; // 元素为T的链表<br />
&nbsp; private List&lt;T&gt; elements;<br />
&nbsp; <br />
&nbsp; /**<br />
&nbsp;&nbsp; * 构造函数,这里无须指定类型<br />
&nbsp;&nbsp; *<br />
&nbsp;&nbsp; */<br />
&nbsp; public Service(){<br />
&nbsp;&nbsp;&nbsp; elements=new ArrayList&lt;T&gt;();<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; /**<br />
&nbsp;&nbsp; * 向链表中添加类型为T的元素<br />
&nbsp;&nbsp; * @param element<br />
&nbsp;&nbsp; */<br />
&nbsp; public void add(T element){<br />
&nbsp;&nbsp;&nbsp; elements.add(element);<br />
&nbsp; }<br />
/**<br />
&nbsp;&nbsp; * 打印链表中元素<br />
&nbsp;&nbsp; *<br />
&nbsp;&nbsp; */<br />
&nbsp; public void printElements(){<br />
&nbsp;&nbsp;&nbsp; for(T t:elements){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(t);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp; }<br />
&nbsp;<br />
/**<br />
&nbsp;&nbsp; * 使用示例<br />
&nbsp;&nbsp; * @param args<br />
&nbsp;&nbsp; */<br />
&nbsp; public static void main(String[] args){<br />
&nbsp;&nbsp;&nbsp; // 创建Service类的示例memberService<br />
&nbsp;&nbsp;&nbsp; Service&lt;Member&gt; memberService=new Service&lt;Member&gt;();<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; // 向memberService中添加元素<br />
&nbsp;&nbsp;&nbsp; memberService.add(new Member("Andy",25));<br />
&nbsp;&nbsp;&nbsp; memberService.add(new Member("Bill",24));<br />
&nbsp;&nbsp;&nbsp; memberService.add(new Member("Cindy",55));<br />
&nbsp;&nbsp;&nbsp; memberService.add(new Member("Felex",35));<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; // 打印memberService中诸元素<br />
&nbsp;&nbsp;&nbsp; memberService.printElements();<br />
&nbsp; }<br />
}</p>
<p><strong>泛型类的使用示例二</strong></p>
<p>/**<br />
&nbsp;* 泛型类示例二,成员变量为哈希表,k,v可以指代任意类类型.<br />
&nbsp;* @author sitinspring<br />
&nbsp;*<br />
&nbsp;* @date 2007-12-28<br />
&nbsp;*/<br />
public class ServiceHt&lt;K,V&gt;{<br />
&nbsp; private Map&lt;K,V&gt; elements;<br />
&nbsp; <br />
&nbsp; /**<br />
&nbsp;&nbsp; * 向elements中添加元素<br />
&nbsp;&nbsp; * @param k<br />
&nbsp;&nbsp; * @param v<br />
&nbsp;&nbsp; */<br />
&nbsp; public void add(K k,V v){<br />
&nbsp;&nbsp;&nbsp; // 如果elements为空则创建元素<br />
&nbsp;&nbsp;&nbsp; if(elements==null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elements=new Hashtable&lt;K,V&gt;();<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; // 向elements中添加键值对<br />
&nbsp;&nbsp;&nbsp; elements.put(k, v);<br />
&nbsp; }<br />
&nbsp;/**<br />
&nbsp;&nbsp; * 打印哈希表中的元素<br />
&nbsp;&nbsp; *<br />
&nbsp;&nbsp; */<br />
&nbsp; public void printElements(){<br />
&nbsp;&nbsp;&nbsp; Iterator it=elements.keySet().iterator();<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; while(it.hasNext()){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; K k=(K)it.next();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; V v=elements.get(k);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("键="+k+" 值="+v);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp; }</p>
<p>&nbsp; /**<br />
&nbsp;&nbsp; * 使用示例<br />
&nbsp;&nbsp; * @param args<br />
&nbsp;&nbsp; */<br />
&nbsp; public static void main(String[] args){<br />
&nbsp;&nbsp;&nbsp; // 创建Service类的示例memberService<br />
&nbsp;&nbsp;&nbsp; ServiceHt&lt;String,Member&gt; memberService=new ServiceHt&lt;String,Member&gt;();<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; // 向memberService中添加元素<br />
&nbsp;&nbsp;&nbsp; memberService.add("Andy",new Member("Andy",25));<br />
&nbsp;&nbsp;&nbsp; memberService.add("Bill",new Member("Bill",24));<br />
&nbsp;&nbsp;&nbsp; memberService.add("Cindy",new Member("Cindy",55));<br />
&nbsp;&nbsp;&nbsp; memberService.add("Felex",new Member("Felex",35));<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; // 打印memberService中诸元素<br />
&nbsp;&nbsp;&nbsp; memberService.printElements();<br />
&nbsp; }<br />
}<br />
</p>
<img src ="http://www.blogjava.net/junglesong/aggbug/183578.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junglesong/" target="_blank">和风细雨</a> 2008-03-03 22:55 <a href="http://www.blogjava.net/junglesong/archive/2008/03/03/183578.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字符串比较  ==与equals辨析</title><link>http://www.blogjava.net/junglesong/archive/2008/03/03/183571.html</link><dc:creator>和风细雨</dc:creator><author>和风细雨</author><pubDate>Mon, 03 Mar 2008 14:38:00 GMT</pubDate><guid>http://www.blogjava.net/junglesong/archive/2008/03/03/183571.html</guid><wfw:comment>http://www.blogjava.net/junglesong/comments/183571.html</wfw:comment><comments>http://www.blogjava.net/junglesong/archive/2008/03/03/183571.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junglesong/comments/commentRss/183571.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junglesong/services/trackbacks/183571.html</trackback:ping><description><![CDATA[<p><strong>字符串比较</strong></p>
<p>字符串比较是java程序常遇到的问题,新手常用==进行两个字符串比较,实际上这时进行的地址比较,不一定会返回正确结果.在java中,正确的进行字符串比较的函数String类的equals()函数,这才是真正的值比较.</p>
<p><strong>==的真正意义</strong></p>
<p>Java中,==用来比较两个引用是否指向同一个内存对象.对于String的实例,运行时JVM会尽可能的确保任何两个具有相同字符串信息的String实例指向同一个内部对象,此过程称为&#8221;驻留&#8221;(interning),但它不助于每个String实例的比较.一个原因是垃圾收集器删除了驻留值,另一个原因是String所在的位置可能被别的String实例所取代.这样的话,==将不会返回预想的结果.<br />
下页的示例说明了这个问题:</p>
<p><strong>==和equals比较的示例<br />
</strong></p>
<p><br />
</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">String&nbsp;str1,str2,str3;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />str1</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">Andy</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />str2</span><span style="color: #000000">=</span><span style="color: #000000">str1;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_64_103_Open_Image" onclick="this.style.display='none'; Codehighlighter1_64_103_Open_Text.style.display='none'; Codehighlighter1_64_103_Closed_Image.style.display='inline'; Codehighlighter1_64_103_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_64_103_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_64_103_Closed_Text.style.display='none'; Codehighlighter1_64_103_Open_Image.style.display='inline'; Codehighlighter1_64_103_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span style="color: #0000ff">if</span><span style="color: #000000">(str1</span><span style="color: #000000">==</span><span style="color: #000000">str2)</span><span id="Codehighlighter1_64_103_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_64_103_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">str1,str2地址相等</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img id="Codehighlighter1_126_164_Open_Image" onclick="this.style.display='none'; Codehighlighter1_126_164_Open_Text.style.display='none'; Codehighlighter1_126_164_Closed_Image.style.display='inline'; Codehighlighter1_126_164_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_126_164_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_126_164_Closed_Text.style.display='none'; Codehighlighter1_126_164_Open_Image.style.display='inline'; Codehighlighter1_126_164_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span style="color: #0000ff">if</span><span style="color: #000000">(str1.equals(str2))</span><span id="Codehighlighter1_126_164_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_126_164_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">str1,str2值相等</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />str2</span><span style="color: #000000">=</span><span style="color: #000000">&#8220;Andy&#8221;;<br />
<img id="Codehighlighter1_194_235_Open_Image" onclick="this.style.display='none'; Codehighlighter1_194_235_Open_Text.style.display='none'; Codehighlighter1_194_235_Closed_Image.style.display='inline'; Codehighlighter1_194_235_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_194_235_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_194_235_Closed_Text.style.display='none'; Codehighlighter1_194_235_Open_Image.style.display='inline'; Codehighlighter1_194_235_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span style="color: #0000ff">if</span><span style="color: #000000">(str1</span><span style="color: #000000">==</span><span style="color: #000000">str2)</span><span id="Codehighlighter1_194_235_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_194_235_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">str1,str2通常地址相等</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img id="Codehighlighter1_258_298_Open_Image" onclick="this.style.display='none'; Codehighlighter1_258_298_Open_Text.style.display='none'; Codehighlighter1_258_298_Closed_Image.style.display='inline'; Codehighlighter1_258_298_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_258_298_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_258_298_Closed_Text.style.display='none'; Codehighlighter1_258_298_Open_Image.style.display='inline'; Codehighlighter1_258_298_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span style="color: #0000ff">if</span><span style="color: #000000">(str1.equals(str2))</span><span id="Codehighlighter1_258_298_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_258_298_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">str1,str2值一定相等</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />str3</span><span style="color: #000000">=</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;String(</span><span style="color: #000000">"</span><span style="color: #000000">Andy</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img id="Codehighlighter1_340_379_Open_Image" onclick="this.style.display='none'; Codehighlighter1_340_379_Open_Text.style.display='none'; Codehighlighter1_340_379_Closed_Image.style.display='inline'; Codehighlighter1_340_379_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_340_379_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_340_379_Closed_Text.style.display='none'; Codehighlighter1_340_379_Open_Image.style.display='inline'; Codehighlighter1_340_379_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span style="color: #0000ff">if</span><span style="color: #000000">(str1</span><span style="color: #000000">==</span><span style="color: #000000">str3)</span><span id="Codehighlighter1_340_379_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_340_379_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">str1,str3地址相等</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img id="Codehighlighter1_385_425_Open_Image" onclick="this.style.display='none'; Codehighlighter1_385_425_Open_Text.style.display='none'; Codehighlighter1_385_425_Closed_Image.style.display='inline'; Codehighlighter1_385_425_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_385_425_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_385_425_Closed_Text.style.display='none'; Codehighlighter1_385_425_Open_Image.style.display='inline'; Codehighlighter1_385_425_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span style="color: #0000ff">else</span><span id="Codehighlighter1_385_425_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_385_425_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">str1,str3地址不相等</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_449_489_Open_Image" onclick="this.style.display='none'; Codehighlighter1_449_489_Open_Text.style.display='none'; Codehighlighter1_449_489_Closed_Image.style.display='inline'; Codehighlighter1_449_489_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_449_489_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_449_489_Closed_Text.style.display='none'; Codehighlighter1_449_489_Open_Image.style.display='inline'; Codehighlighter1_449_489_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span style="color: #0000ff">if</span><span style="color: #000000">(str1.equals(str3))</span><span id="Codehighlighter1_449_489_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_449_489_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">str1,str3值一定相等</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<p><br />
<br />
<strong>结论</strong></p>
<p>从上面的例子可以看出,==比较的是地址,在驻留机制的作用下,也许返回正确的结果,但并不可靠,这种不确定性会隐藏在阴暗的角落里,在你以为万事大吉时给你致命一击.<br />
而equal始终进行值比较,它一定会返回正确的结果,无论在什么情况下.</p>
<p>我们应该记住:为了保证程序的正确,进行字符串比较时一定要使用equals,而一定不能使用==.<br />
</p>
<img src ="http://www.blogjava.net/junglesong/aggbug/183571.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junglesong/" target="_blank">和风细雨</a> 2008-03-03 22:38 <a href="http://www.blogjava.net/junglesong/archive/2008/03/03/183571.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>异常机制综述</title><link>http://www.blogjava.net/junglesong/archive/2008/03/03/183570.html</link><dc:creator>和风细雨</dc:creator><author>和风细雨</author><pubDate>Mon, 03 Mar 2008 14:34:00 GMT</pubDate><guid>http://www.blogjava.net/junglesong/archive/2008/03/03/183570.html</guid><wfw:comment>http://www.blogjava.net/junglesong/comments/183570.html</wfw:comment><comments>http://www.blogjava.net/junglesong/archive/2008/03/03/183570.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junglesong/comments/commentRss/183570.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junglesong/services/trackbacks/183570.html</trackback:ping><description><![CDATA[<p>在运行过程中,应用程序可能遭遇各种严重程度不同的问题.异常提供了一种在不弄乱程序的情况下检查错误的巧妙方式.它也提供了一种直接报告错误的机制,而不必检查标志或者具有此作用的域.异常把方法能够报告的错误作为方法约定的一个显式部分.<br />
异常能够被程序员看到,由编译器检查,并且由重载方法的子类保留.<br />
如果遇到意外的错误将抛出异常,然后异常被方法调用栈上的子句捕获.如果异常未被捕获,将导致执行线程的终止.</p>
<p><strong>异常的体系结构</strong></p>
<p>毫无疑问,在java中异常是对象,它必定继承Throwable及其子类.Throwable中含有一个用于描述异常的字符串.Exception是Throwable的一个最常用子类,另一个子类是Error.而RuntimeException继承自Exception.<br />
</p>
<p><strong><img height="337" alt="" src="http://www.blogjava.net/images/blogjava_net/junglesong/ThreadInheritance.jpg" width="292" border="0" /><br />
<br />
异常的种类</strong></p>
<p><strong>非检查型异常(Unchecked Exception):<br />
</strong>非检查型异常反映了程序中的逻辑错误,不能从运行中合理恢复.<br />
标准的运行时异常和错误构成非检查型异常,它们继承自RuntimeException和Error.<br />
非检查型异常不用显示进行捕获.</p>
<p><strong>检查型异常(Checked Exception):</strong><br />
这种异常描述了这种情况,虽然是异常的,但被认为是可以合理发生的,如果这种异常真的发生了,必须调用某种方法处理.<br />
Java异常大多是检查型异常,继承自Exception类,你自己定义的异常必须是继承Exception的检查型异常.<br />
检查型异常必须进行显示捕获.</p>
<p><strong>自定义异常</strong></p>
<p>继承Exception即可定义自己的异常,以下是一种常见写法<br />
public class DBXmlFileReadException extends Exception{<br />
&nbsp; public DBXmlFileReadException(String&nbsp;&nbsp; msg){<br />
&nbsp;&nbsp;&nbsp; super(msg);<br />
&nbsp; }<br />
}</p>
<p><br />
<strong>抛出异常</strong></p>
<p>在Java语句中,可以用throw语句抛出异常,如throw new NoSuchElementException(); <br />
抛出的对象必须是Throwable类的子类型.</p>
<p>抛出异常的策略:<br />
1) 如果抛出后不可能得到处理,可以抛出Error.<br />
2) 如果你想让其它类自由选择是否处理这个异常,就可以抛出RuntimeException.<br />
3) 如果你要求类的用户必须处理这个异常,则可以抛出Exception.</p>
<p><strong>异常抛出后的控制权转移</strong></p>
<p>一旦发生异常,异常发生点后的动作将不会发生.此后将要发生的操作不是在catch块和finally块.</p>
<p>当异常抛出时,导致异常发生的语句和表达式就被称为突然完成.语句的突然完成将导致调用链逐渐展开,直到该异常被捕获.</p>
<p>如果该异常没有捕获,执行线程将中止.</p>
<p>Try,catch和finally</p>
<p>异常由包含在try块中的语句捕获:<br />
&nbsp;&nbsp;&nbsp; try{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 正常执行语句<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; catch(XException e){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 异常执行语句一<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; catch(XXException e){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 异常执行语句二<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; catch(XXXException e){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 异常执行语句三<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; finally{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 中止语句<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>Try中的语句体要么顺利完成,要么执行到抛出异常.<br />
如果抛出异常,就要找出对应于异常类或其父类的catch子句,如果未能找到合适的catch子句,异常就从try语句中扩散出来,进入到外层可能对它进行处理的try语句.<br />
Catch子句可以有多个,只要这些子句捕获的异常类型不同.<br />
如果在try中有finally子句,其代码在try把所有其它处理完成之后执行.<br />
无论是正常完成或是出现异常,甚至是通过return或者break这样的控制语句结束,finally子句总是被执行.<br />
Catch子句和finally子句在try语句之后至少有一个,不要求全部出现.</p>
<p><strong>More&#8230;</strong></p>
<p>在catch语句中捕获通用的异常Exception通常不是最佳策略,因为它会将所有异常进行等同处理.<br />
不能把基类异常的catch语句放到子类异常的catch语句之前,编译器会在运行之前就检查出这样的错误.<br />
Try&#8230;catch对每个catch语句都从头到尾检查,如果找到处理同类异常的catch子句,此catch块中的语句将得以执行,而不再处理同层次的其它catch块.<br />
如果catch或finally抛出另一个异常,程序将不会再去检查try的catch子句.<br />
Try...catch语句可以嵌套,内层抛出的异常可被外层处理.</p>
<p><strong>Throws子句</strong></p>
<p>函数能抛出的检查型异常用throws声明,它后面可以是带用逗号隔开的一系列异常类型.仅仅那些在方法中不被捕获的异常必须列出.</p>
<p>private void readObject(java.io.ObjectInputStream s)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws java.io.IOException, ClassNotFoundException {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Read in any hidden serialization magic<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.defaultReadObject();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Read in size<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int size = s.readInt();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Initialize header<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; header = new Entry&lt;E&gt;(null, null, null);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; header.next = header.previous = header;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Read in all elements in the proper order.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i=0; i&lt;size; i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; addBefore((E)s.readObject(), header);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p><strong>More&#8230;</strong></p>
<p>Throws子句的约定是严格强制性的,只能抛出throws子句中声明的异常类型,抛出其它类型的异常是非法的,不管是直接利用throw,还是调用别的方法间接的抛出.<br />
RuntimeException和Error是仅有的不必由throws子句列出的异常.<br />
调用函数的函数要么处理对声明的异常进行处理,要么也声明同样的异常,将收到的异常抛向上层.</p>
<p><strong>对检查型异常通常进行的几种处理</strong></p>
<p>1) 用e.printStackTrace()输出异常信息.<br />
2) 将异常记录到日志中以备查,如logger.error(e.getMessage()).<br />
3) 试图进行异常恢复.<br />
4) 告知维护者和用户发生的情况.<br />
</p>
<img src ="http://www.blogjava.net/junglesong/aggbug/183570.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junglesong/" target="_blank">和风细雨</a> 2008-03-03 22:34 <a href="http://www.blogjava.net/junglesong/archive/2008/03/03/183570.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>嵌套类和匿名类</title><link>http://www.blogjava.net/junglesong/archive/2008/03/03/183569.html</link><dc:creator>和风细雨</dc:creator><author>和风细雨</author><pubDate>Mon, 03 Mar 2008 14:30:00 GMT</pubDate><guid>http://www.blogjava.net/junglesong/archive/2008/03/03/183569.html</guid><wfw:comment>http://www.blogjava.net/junglesong/comments/183569.html</wfw:comment><comments>http://www.blogjava.net/junglesong/archive/2008/03/03/183569.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junglesong/comments/commentRss/183569.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junglesong/services/trackbacks/183569.html</trackback:ping><description><![CDATA[<p><strong>嵌套类和匿名类</strong></p>
<p><strong>内部类的出现</strong><br />
当进行Java开发时,有时需要实现一个仅包含1-2个方法的接口.在AWT和Swing开发中经常出现这种情况,例如当一个display组件需要一个事件回调方法如一个按钮的ActionListener时. 如果使用普通的类来实现此操作,最终会得到很多仅在单个位置上使用的小型类. <br />
内部类用于处理这种情况,java允许定义内部类,而且可在Gui外使用内部类.</p>
<p><strong>内部类的定义和实现</strong></p>
<p>内部类是指在另一个类内部定义的一个类.可以将内部类定义为一个类的成员.<br />
public class Linker{<br />
&nbsp; public class LinkedNode{<br />
&nbsp;&nbsp;&nbsp; private LinkedNode prev;<br />
&nbsp;&nbsp;&nbsp; private LinkedNode next;<br />
&nbsp;&nbsp;&nbsp; private String content;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public LinkedNode(String content){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.content=content;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; public Linker(){<br />
&nbsp;&nbsp;&nbsp; LinkedNode first=new LinkedNode("First");<br />
&nbsp;&nbsp;&nbsp; LinkedNode second=new LinkedNode("Second");<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; first.next=second;<br />
&nbsp;&nbsp;&nbsp; second.prev=first;<br />
&nbsp; }<br />
}</p>
<p><strong>定义在一个类方法中的内部类</strong></p>
<p>public class Hapiness{<br />
&nbsp; interface Smiler{<br />
&nbsp;&nbsp;&nbsp; public void smile();<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; public static void main(String[] args){<br />
&nbsp;&nbsp;&nbsp; class Happy implements Smiler{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void smile(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(":-}");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; Happy happy=new Happy();<br />
&nbsp;&nbsp;&nbsp; happy.smile();<br />
&nbsp; }<br />
}</p>
<p><strong>匿名类</strong></p>
<p>对很多情况而言,定义在方法内部的类名意义不大,它可以保持为匿名的,程序员关心的只是它的实例名.<br />
如:<br />
Runnable runner=new Runnable(){<br />
&nbsp;&nbsp;&nbsp;&nbsp; public void&nbsp; run(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Run statememnt<br />
&nbsp;&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p><strong>理解匿名类</strong></p>
<p>匿名类并不难理解,它只是把类的定义过程和实例的创建过程混合而已,上页的语句实际上相当于如下语句:<br />
// 定义类<br />
Public class Runner implements Runnable{<br />
&nbsp;&nbsp;&nbsp;&nbsp; public void run(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // do sth<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p>// 创建实例<br />
Runner runner=new Runner();</p>
<p>使用匿名类的筛选解耦过程</p>
<p>需求:从公司的职员列表中,找出男性且年龄大于22的成员.</p>
<p>传统写法: </p>
<p>&nbsp;&nbsp; List allmembers=company.getMembers();// 取得所有成员<br />
&nbsp;&nbsp;&nbsp; List results=new ArrayList();// 结果列表<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; for(Iterator it=allmembers.iterator();it.hasNext();){<br />
&nbsp;&nbsp;&nbsp;&nbsp; Member member=(Member)it.next();<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; if(member.getAge()&gt;22 &amp;&amp; member.isMale()){&nbsp; // 筛选,这里是把查询条件和遴选过程融合在一起,条件一变立即就得加个分支.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; results.add(member);<br />
&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; } </p>
<p><strong>传统方法的缺陷</strong></p>
<p>这种写法没有错,但是不是面向对象的写法,它有以下缺陷:<br />
1.查询条件和筛选过程没有分离.<br />
2.这样写的后果使Company变成了一个失血模型而不是领域模型.<br />
3.换查询条件的话,上面除了"筛选"一句有变化外其它都是模板代码,重复性很高.</p>
<p>使用匿名类实现的OO化查询</p>
<p>真正符合OO的查询应该是这样:</p>
<p>&nbsp;&nbsp; MemberFilter filter1=new MemberFilter(){<br />
&nbsp;&nbsp;&nbsp; public boolean accept(Member member) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return member.isMale() &amp;&amp; member.getAge()&gt;22;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; };<br />
&nbsp;&nbsp; <br />
&nbsp;&nbsp; List ls=company.listMembers(filter1);<br />
&nbsp;</p>
<p>这段代码成功的把查询条件作为一个接口分离了出去,接口代码如下:</p>
<p>public interface MemberFilter{<br />
&nbsp; public boolean accept(Member member); <br />
}</p>
<p><strong>查询函数的变化</strong></p>
<p>而类Company增加了这样一个函数:</p>
<p>public List searchMembers(MemberFilter memberFilter){<br />
&nbsp;&nbsp; List retval=new ArrayList();<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; for(Iterator it=members.iterator();it.hasNext();){<br />
&nbsp;&nbsp;&nbsp;&nbsp; Member member=(Member)it.next();<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; if(memberFilter.accept(member)){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval.add(member);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; }&nbsp; <br />
&nbsp;&nbsp; <br />
&nbsp;&nbsp; return retval;<br />
}<br />
这就把模板代码归结到了类内部,外面不会重复书写了.Company也同时拥有了数据和行为,而不是原来的数据容器了.</p>
<p><br />
<strong>匿名类的例子二</strong></p>
<p>用匿名类处理分类汇总的方法 分类汇总是统计中常用,举例来说如统计学生成绩,及格不及格的归类,分优良中差等级归类等,每个单项代码很好写,但是如果分类汇总的项目多了,能一种汇总写一个函数吗? 比如说有些科目60分才算及格,有些科目50分就算;有些老师喜欢分优良中差四等,有些老师却喜欢分ABCD;不一而足,如果每个都写一个函数无疑是个编写和维护恶梦. 如果我们用匿名类把分类汇总的规则和分类汇总的过程分别抽象出来,代码就清晰灵活多了,以下代码讲述了这个过程.</p>
<p>基本类Student</p>
<p>public class Student{<br />
&nbsp;&nbsp;&nbsp; private String name;<br />
&nbsp;&nbsp;&nbsp; private int score;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public Student(String name,int score){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.name=name;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.score=score;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public String getName() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return name;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; public void setName(String name) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.name = name;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; public int getScore() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return score;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; public void setScore(int score) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.score = score;<br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br />
}</p>
<p><br />
<strong>用于分类汇总的类</strong></p>
<p>它强制子类实现getKey和getvalue两个方法:<br />
public abstract class ClassifyRule {<br />
&nbsp;&nbsp;&nbsp; public Student student;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public ClassifyRule(){&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp; public void setStudent(Student student) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.student = student;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; abstract public String getKey();<br />
&nbsp;&nbsp;&nbsp; abstract public int getValue();<br />
}</p>
<p><strong>对Student进行统计处理的StudentService类</strong></p>
<p>注意getSum方法,它保留了筛选过程,筛选规则则不在其中:<br />
import java.util.ArrayList;<br />
import java.util.Hashtable;<br />
import java.util.List;</p>
<p>public class StudentService {<br />
&nbsp;&nbsp;&nbsp; private List&lt;Student&gt; students;</p>
<p>&nbsp;&nbsp;&nbsp; public StudentService() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; students = new ArrayList&lt;Student&gt;();<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; public void add(Student student) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; students.add(student);<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; public Hashtable&lt;String, Integer&gt; getSum(ClassifyRule rule) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hashtable&lt;String, Integer&gt; ht = new Hashtable&lt;String, Integer&gt;();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (Student student : students) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rule.setStudent(student);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String key = rule.getKey();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int value = rule.getValue();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ht.containsKey(key)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Integer oldValue = ht.remove(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oldValue += value;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ht.put(key, oldValue);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ht.put(key, value);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ht;<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p><strong>测试代码,注意其中筛选规则的创建</strong></p>
<p>public class Test {<br />
&nbsp;&nbsp;&nbsp; public static void main(String[] args) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 初始化<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StudentService service = new StudentService();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service.add(new Student("Andy", 90));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service.add(new Student("Bill", 95));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service.add(new Student("Cindy", 70));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service.add(new Student("Dural", 85));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service.add(new Student("Edin", 60));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service.add(new Student("Felix", 55));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service.add(new Student("Green", 15));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 60分及格筛选<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ClassifyRule rule60 = new ClassifyRule() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getKey() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return student.getScore() &gt;= 60 ? "及格" : "不及格";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int getValue() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("60分及格筛选");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printHt(service.getSum(rule60));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 50分及格筛选<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ClassifyRule rule50 = new ClassifyRule() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getKey() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return student.getScore() &gt;= 50 ? "及格" : "不及格";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int getValue() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("\n50分及格筛选");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printHt(service.getSum(rule50));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 分"优良中差"等级<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ClassifyRule ruleCn = new ClassifyRule() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getKey() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String retval = "";</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int score = student.getScore();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (score &gt;= 90) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = "优";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (score &gt;= 80) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = "良";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (score &gt;= 60) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = "中";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (score &gt; 0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = "差";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int getValue() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</p>
<p><strong>测试代码</strong></p>
<p>System.out.println("\n分优良中差等级筛选");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printHt(service.getSum(ruleCn));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 分"ABCD"等级<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ClassifyRule ruleWest = new ClassifyRule() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getKey() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String retval = "";</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int score = student.getScore();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (score &gt;= 90) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = "A";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (score &gt;= 80) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = "B";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (score &gt;= 60) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = "C";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (score &gt; 0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = "D";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int getValue() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("\n分ABCD等级筛选");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printHt(service.getSum(ruleWest));<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; private static void printHt(Hashtable ht) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (Iterator it = ht.keySet().iterator(); it.hasNext();) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String key = (String) it.next();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Integer value = (Integer) ht.get(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Key=" + key + " Value=" + value);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p><br />
<strong>测试结果如下:</strong></p>
<p>&nbsp;</p>
<p>60分及格筛选<br />
Key=及格 Value=5<br />
Key=不及格 Value=2</p>
<p>50分及格筛选<br />
Key=及格 Value=6<br />
Key=不及格 Value=1</p>
<p>分优良中差等级筛选<br />
Key=优 Value=2<br />
Key=良 Value=1<br />
Key=中 Value=2<br />
Key=差 Value=2</p>
<p>分ABCD等级筛选<br />
Key=A Value=2<br />
Key=D Value=2<br />
Key=C Value=2<br />
Key=B Value=1</p>
<p>后记</p>
<p>内部类也叫嵌套类,一般不提倡书写,但它在java核心类中都存在,如接口Map中的Entry,我们应该了解并能解读这种方法.</p>
<p>匿名类相对而言有用得多,在解耦合和事件回调注册中很常见,大家应该对它的运用融会贯通.<br />
</p>
<img src ="http://www.blogjava.net/junglesong/aggbug/183569.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junglesong/" target="_blank">和风细雨</a> 2008-03-03 22:30 <a href="http://www.blogjava.net/junglesong/archive/2008/03/03/183569.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Socket基础</title><link>http://www.blogjava.net/junglesong/archive/2008/02/26/182207.html</link><dc:creator>和风细雨</dc:creator><author>和风细雨</author><pubDate>Tue, 26 Feb 2008 05:53:00 GMT</pubDate><guid>http://www.blogjava.net/junglesong/archive/2008/02/26/182207.html</guid><wfw:comment>http://www.blogjava.net/junglesong/comments/182207.html</wfw:comment><comments>http://www.blogjava.net/junglesong/archive/2008/02/26/182207.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junglesong/comments/commentRss/182207.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junglesong/services/trackbacks/182207.html</trackback:ping><description><![CDATA[<p><strong>本文内容</strong></p>
<p>Socket概述<br />
Socket的重要API<br />
一个Socket通信的例子</p>
<p><strong>Socket是什么？</strong></p>
<p>Socket通常也称作&#8220;套接字&#8221;，用于描述IP地址和端口，是一个通信链的句柄。应用程序通常通过&#8220;套接字&#8221;向网络发出请求或者应答网络请求。 <br />
在java中，Socket和ServerSocket类库位于java.net包中。ServerSocket用于服务器端，Socket是建立网络连接时使用的。在连接成功时，应用程序两端都会产生一个Socket实例，操作这个实例，完成所需的会话。<br />
对于一个网络连接来说，套接字是平等的，并没有差别，不因为在服务器端或在客户端而产生不同级别。 </p>
<p><strong>Socket的直观描述</strong></p>
<p>Socket的英文原义是&#8220;孔&#8221;或&#8220;插座&#8221;。在这里作为进程通信机制，取后一种意义。socket非常类似于电话插座。以一个国家级电话网为例。电话的通话双方相当于相互通信的2个进程，区号是它的网络地址；区内一个单位的交换机相当于一台主机，主机分配给每个用户的局内号码相当于socket号。任何用户在通话之前，首先要占有一部电话机，相当于申请一个socket；同时要知道对方的号码，相当于对方有一个固定的socket。然后向对方拨号呼叫，相当于发出连接请求(假如对方不在同一区内，还要拨对方区号，相当于给出网络地址)。对方假如在场并空闲(相当于通信的另一主机开机且可以接受连接请求)，拿起电话话筒，双方就可以正式通话，相当于连接成功。双方通话的过程，是一方向电话机发出信号和对方从电话机接收信号的过程，相当于向socket发送数据和从socket接收数据。通话结束后，一方挂起电话机相当于关闭socket，撤消连接。<br />
在电话系统中，一般用户只能感受到本地电话机和对方电话号码的存在，建立通话的过程，话音传输的过程以及整个电话系统的技术细节对他都是透明的，这也与socket机制非常相似。socket利用网间网通信设施实现进程通信，但它对通信设施的细节毫不关心，只要通信设施能提供足够的通信能力，它就满足了。<br />
&nbsp;至此，我们对socket进行了直观的描述。抽象出来，socket实质上提供了进程通信的端点。进程通信之前，双方首先必须各自创建一个端点，否则是没有办法建立联系并相互通信的。正如打电话之前，双方必须各自拥有一台电话机一样。</p>
<p><strong>socket 是面向客户/服务器模型而设计的</strong></p>
<p>socket 是面向客户/服务器模型而设计的，针对客户和服务器程序提供不同的socket 系统调用。客户随机申请一个socket (相当于一个想打电话的人可以在任何一台入网电话上拨号呼叫)，系统为之分配一个socket号；服务器拥有全局公认的 socket ，任何客户都可以向它发出连接请求和信息请求(相当于一个被呼叫的电话拥有一个呼叫方知道的电话号码)。<br />
socket利用客户/服务器模式巧妙地解决了进程之间建立通信连接的问题。服务器socket为全局所公认非常重要。读者不妨考虑一下，两个完全随机的用户进程之间如何建立通信？假如通信双方没有任何一方的socket 固定，就好比打电话的双方彼此不知道对方的电话号码，要通话是不可能的。</p>
<p><strong>Socket的应用</strong></p>
<p>Socket 接口是访问 Internet 使用得最广泛的方法。 如果你有一台刚配好TCP/IP协议的主机，其IP地址是202.120.127.201， 此时在另一台主机或同一台主机上执行ftp 202.120.127.201，显然无法建立连接。因"202.120.127.201" 这台主机没有运行FTP服务软件。同样， 在另一台或同一台主机上运行浏览软件 如Netscape，输入"http://202.120.127.201"，也无法建立连接。现在，如果在这台主机上运行一个FTP服务软件（该软件将打开一个Socket， 并将其绑定到21端口），再在这台主机上运行一个Web 服务软件（该软件将打开另一个Socket，并将其绑定到80端口）。这样，在另一台主机或同一台主机上执行ftp 202.120.127.201，FTP客户软件将通过21端口来呼叫主机上由FTP 服务软件提供的Socket，与其建立连接并对话。而在netscape中输入"http://202.120.127.201"时，将通过80端口来呼叫主机上由Web服务软件提供的Socket，与其建 立连接并对话。 在Internet上有很多这样的主机，这些主机一般运行了多个服务软件，同时提供几种服务。每种服务都打开一个Socket，并绑定到一个端口上，不同的端口对应于不同的服务。Socket正如其英文原意那样，象一个多孔插座。一台主机犹如布满各种插座的房间，每个插座有一个编号，有的插座提供220伏交流电， 有的提供110伏交流电，有的则提供有线电视节目。 客户软件将插头插到不同编号的插座，就可以得到不同的服务。 </p>
<p><strong>重要的Socket API</strong></p>
<p>accept方法用于产生&#8220;阻塞&#8221;，直到接受到一个连接，并且返回一个客户端的Socket对象实例。&#8220;阻塞&#8221;是一个术语，它使程序运行暂时&#8220;停留&#8221;在这个地方，直到一个会话产生，然后程序继续；通常&#8220;阻塞&#8221;是由循环产生的。<br />
getInputStream方法获得网络连接输入，同时返回一个IutputStream对象实例。 <br />
getOutputStream方法连接的另一端将得到输入，同时返回一个OutputStream对象实例。 注意：其中getInputStream和getOutputStream方法均会产生一个IOException，它必须被捕获，因为它们返回的流对象，通常都会被另一个流对象使用。 </p>
<p><strong>一个Server-Client模型的程序的开发原理</strong> </p>
<p>服务器，使用ServerSocket监听指定的端口，端口可以随意指定（由于1024以下的端口通常属于保留端口，在一些操作系统中不可以随意使用，所以建议使用大于1024的端口），等待客户连接请求，客户连接后，会话产生；在完成会话后，关闭连接。<br />
客户端，使用Socket对网络上某一个服务器的某一个端口发出连接请求，一旦连接成功，打开会话；会话完成后，关闭Socket。客户端不需要指定打开的端口，通常临时的、动态的分配一个1024以上的端口。 </p>
<p><strong>服务器端代码</strong></p>
<p>public class ResponseThread implements Runnable {<br />
&nbsp; private static Logger logger = Logger.getLogger(ResponseThread.class);<br />
&nbsp; <br />
&nbsp; // 用于与客户端通信的Socket<br />
&nbsp; private Socket incomingSocket;</p>
<p>&nbsp; /**<br />
&nbsp;&nbsp; * 构造函数,用以将incomingSocket传入<br />
&nbsp;&nbsp; * @param incomingSocket<br />
&nbsp;&nbsp; */<br />
&nbsp; public ResponseThread(Socket incomingSocket) {<br />
&nbsp;&nbsp;&nbsp; this.incomingSocket = incomingSocket;<br />
&nbsp; }</p>
<p>&nbsp; public void run() {<br />
&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 输入流<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputStream inStream = incomingSocket.getInputStream();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 输出流<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OutputStream outStream = incomingSocket.getOutputStream();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 文本扫描器<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Scanner in = new Scanner(inStream);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 输出流打印器<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PrintWriter out = new PrintWriter(outStream,true);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (in.hasNextLine()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String line = in.nextLine();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("从客户端获得文字:"+line);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String responseLine=line+" 门朝大海 三河合水万年流";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.println(responseLine);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("向客户端送出文字:"+responseLine);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } finally {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; incomingSocket.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; } catch (IOException ex) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ex.printStackTrace();<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp; }<br />
&nbsp;public static void main(String[] args) {<br />
&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 建立一个对2009端口进行监听的ServerSocket并开始监听<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ServerSocket socket=new ServerSocket(2009);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("开始监听");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(true){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 产生阻塞,直到客户端连接过来才会往下执行<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("阻塞中,等待来自客户端的连接请求");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Socket incomingSocket=socket.accept();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 执行到这里客户端已经连接过来了,incomingSocket就是创建出来和远程客户端Socket进行通信的Socket<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("获得来自"+incomingSocket.getInetAddress()+"的请求.");&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 开辟一个线程,并把incomingSocket传进去,在这个线程中服务器和客户机开始通信<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResponseThread responseThread=new ResponseThread(incomingSocket);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 启动线程<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread thread=new Thread(responseThread);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; thread.start(); <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; } catch (IOException ex) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ex.printStackTrace();<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp; }<br />
}</p>
<p><strong>客户端代码</strong></p>
<p>/**<br />
&nbsp;* Socket客户端类<br />
&nbsp;* @author sitinspring<br />
&nbsp;*<br />
&nbsp;* @date 2008-2-26<br />
&nbsp;*/<br />
public class SocketClient{<br />
&nbsp; private static Logger logger = Logger.getLogger(ResponseThread.class);<br />
&nbsp; <br />
&nbsp; public static void main(String[] args){<br />
&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 建立一个Socket,试图连接到位于127.0.0.1的主机的2009端口,如果服务器已经在监听则会接收到这个请求,accept方法产生一个和这边通信的Socket<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Socket socket=new Socket("127.0.0.1",2009);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("客户端向服务器发起请求.");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 输入流<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputStream inStream = socket.getInputStream();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 输出流<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OutputStream outStream = socket.getOutputStream();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 向服务器发送文字<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */ <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 输出流打印器<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PrintWriter out = new PrintWriter(outStream);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.println("地震高岗 一派溪山千古秀");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.flush();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 接收服务器发送过来的文字<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 文本扫描器<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Scanner in = new Scanner(inStream);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (in.hasNextLine()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String line = in.nextLine();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("客户端获得响应文字="+ line);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } finally {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 关闭Socket<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; socket.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; } catch (IOException ex) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ex.printStackTrace();<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp; }<br />
}</p>
<img src ="http://www.blogjava.net/junglesong/aggbug/182207.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junglesong/" target="_blank">和风细雨</a> 2008-02-26 13:53 <a href="http://www.blogjava.net/junglesong/archive/2008/02/26/182207.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用java.text.SimpleDateFormat类进行文本日期和Date日期的转换 </title><link>http://www.blogjava.net/junglesong/archive/2008/02/22/181238.html</link><dc:creator>和风细雨</dc:creator><author>和风细雨</author><pubDate>Fri, 22 Feb 2008 00:50:00 GMT</pubDate><guid>http://www.blogjava.net/junglesong/archive/2008/02/22/181238.html</guid><wfw:comment>http://www.blogjava.net/junglesong/comments/181238.html</wfw:comment><comments>http://www.blogjava.net/junglesong/archive/2008/02/22/181238.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junglesong/comments/commentRss/181238.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junglesong/services/trackbacks/181238.html</trackback:ping><description><![CDATA[<p>Date类内部既不存储年月日也不存储时分秒，而是存储一个从1970年1月1日0点0分0秒开始的毫秒数，而真正有用的年月日时分秒毫秒都是从这个毫秒数转化而来，这是它不容易被使用的地方，尤其是显示和存储的场合。但Date类的优势在于方便计算和比较。<br />
另一点，日常生活中我们习惯用年月日时分秒这样的文本日期来表示时间，它方便显示和存储，也容易理解，但不容易计算和比较。<br />
综上所述，我们在程序中进行日期时间处理时经常需要在在文本日期和Date类之间进行转换，为此我们需要借助java.text.SimpleDateFormat类来进行处理，下文列举了它的几个常用示例。</p>
<p><strong><em>1.将Date转化为常见的日期时间字符串<br />
</em></strong>这里我们需要用到java.text.SimpleDateFormat类的format方法，其中可以指定年月日时分秒的模式字符串格式。<br />
Date date = new Date();<br />
Format formatter = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");<br />
System.out.println("转化的时间等于="+formatter.format(date));<br />
其中<br />
yyyy表示四位数的年份<br />
MM表示两位数的月份<br />
dd表示两位数的日期<br />
HH表示两位数的小时<br />
mm表示两位数的分钟<br />
ss表示两位数的秒钟</p>
<p><strong><em>2.将文本日期转化为Date以方便比较</em></strong><br />
文本日期的优势在于便于记忆，容易处理，但缺点是不方便比较，这时我们需要借助SimpleDateFormat的parse方法得到Date对象再进行比较，实例如下：<br />
String strDate1="2004年8月9日";<br />
String strDate2="2004年10月5日";</p>
<p>SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy年MM月dd日");<br />
java.util.Date date1 = myFormatter.parse(strDate1);</p>
<p>java.util.Date date2 = myFormatter.parse(strDate2);</p>
<p>// Date比较能得出正确结果<br />
if(date2.compareTo(date1)&gt;0){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(strDate2+"&gt;"+strDate1);<br />
}</p>
<p>// 字符串比较得不出正确结果<br />
if(strDate2.compareTo(strDate1)&gt;0){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(strDate2+"&gt;"+strDate1);<br />
}</p>
<p><br />
<strong><em>3.将文本日期转化为Date以方便计算</em></strong><br />
文本日期的另一个大问题是不方便计算，比如计算2008年1月9日的100天后是那一天就不容易，此时我们还是需要把文本日期转化为Date进行计算，再把结果转化为文本日期：<br />
SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy年MM月dd日");<br />
java.util.Date date = myFormatter.parse("2008年1月9日");<br />
date.setDate(date.getDate()+100);</p>
<p>Format formatter = new SimpleDateFormat("yyyy年MM月dd日");</p>
<p>// 得到2008年04月18日<br />
System.out.println("100天后为"+formatter.format(date));</p>
  <img src ="http://www.blogjava.net/junglesong/aggbug/181238.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junglesong/" target="_blank">和风细雨</a> 2008-02-22 08:50 <a href="http://www.blogjava.net/junglesong/archive/2008/02/22/181238.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>反射Reflection综述</title><link>http://www.blogjava.net/junglesong/archive/2008/02/21/181198.html</link><dc:creator>和风细雨</dc:creator><author>和风细雨</author><pubDate>Thu, 21 Feb 2008 13:05:00 GMT</pubDate><guid>http://www.blogjava.net/junglesong/archive/2008/02/21/181198.html</guid><wfw:comment>http://www.blogjava.net/junglesong/comments/181198.html</wfw:comment><comments>http://www.blogjava.net/junglesong/archive/2008/02/21/181198.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junglesong/comments/commentRss/181198.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junglesong/services/trackbacks/181198.html</trackback:ping><description><![CDATA[  <img src ="http://www.blogjava.net/junglesong/aggbug/181198.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junglesong/" target="_blank">和风细雨</a> 2008-02-21 21:05 <a href="http://www.blogjava.net/junglesong/archive/2008/02/21/181198.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>异常机制概述</title><link>http://www.blogjava.net/junglesong/archive/2008/02/21/181192.html</link><dc:creator>和风细雨</dc:creator><author>和风细雨</author><pubDate>Thu, 21 Feb 2008 12:09:00 GMT</pubDate><guid>http://www.blogjava.net/junglesong/archive/2008/02/21/181192.html</guid><wfw:comment>http://www.blogjava.net/junglesong/comments/181192.html</wfw:comment><comments>http://www.blogjava.net/junglesong/archive/2008/02/21/181192.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junglesong/comments/commentRss/181192.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junglesong/services/trackbacks/181192.html</trackback:ping><description><![CDATA[<p><strong>异常机制综述</strong></p>
<p>在运行过程中,应用程序可能遭遇各种严重程度不同的问题.异常提供了一种在不弄乱程序的情况下检查错误的巧妙方式.它也提供了一种直接报告错误的机制,而不必检查标志或者具有此作用的域.异常把方法能够报告的错误作为方法约定的一个显式部分.<br />
异常能够被程序员看到,由编译器检查,并且由重载方法的子类保留.<br />
如果遇到意外的错误将抛出异常,然后异常被方法调用栈上的子句捕获.如果异常未被捕获,将导致执行线程的终止.</p>
<p><strong>异常的体系结构</strong></p>
<p>毫无疑问,在java中异常是对象,它必定继承Throwable及其子类.Throwable中含有一个用于描述异常的字符串.Exception是Throwable的一个最常用子类,另一个子类是Error.而RuntimeException继承自Exception.<br />
<img height="337" alt="" src="http://www.blogjava.net/images/blogjava_net/junglesong/ExceptionInheritance.jpg" width="292" border="0" /><br />
<br />
</p>
<p><strong>异常的种类</strong></p>
<p>非检查型异常(Unchecked Exception):<br />
非检查型异常反映了程序中的逻辑错误,不能从运行中合理恢复.<br />
标准的运行时异常和错误构成非检查型异常,它们继承自RuntimeException和Error.<br />
非检查型异常不用显示进行捕获.</p>
<p>检查型异常(Checked Exception):<br />
这种异常描述了这种情况,虽然是异常的,但被认为是可以合理发生的,如果这种异常真的发生了,必须调用某种方法处理.<br />
Java异常大多是检查型异常,继承自Exception类,你自己定义的异常必须是继承Exception的检查型异常.<br />
检查型异常必须进行显示捕获.</p>
<p><strong>自定义异常</strong></p>
<p>继承Exception即可定义自己的异常,以下是一种常见写法<br />
public class DBXmlFileReadException extends Exception{<br />
&nbsp; public DBXmlFileReadException(String&nbsp;&nbsp; msg){<br />
&nbsp;&nbsp;&nbsp; super(msg);<br />
&nbsp; }<br />
}</p>
<p><strong>抛出异常</strong></p>
<p>在Java语句中,可以用throw语句抛出异常,如throw new NoSuchElementException(); <br />
抛出的对象必须是Throwable类的子类型.</p>
<p>抛出异常的策略:<br />
1) 如果抛出后不可能得到处理,可以抛出Error.<br />
2) 如果你想让其它类自由选择是否处理这个异常,就可以抛出RuntimeException.<br />
3) 如果你要求类的用户必须处理这个异常,则可以抛出Exception.</p>
<p><strong>异常抛出后的控制权转移</strong></p>
<p>一旦发生异常,异常发生点后的动作将不会发生.此后将要发生的操作不是在catch块和finally块.</p>
<p>当异常抛出时,导致异常发生的语句和表达式就被称为突然完成.语句的突然完成将导致调用链逐渐展开,直到该异常被捕获.</p>
<p>如果该异常没有捕获,执行线程将中止.</p>
<p><strong>Try,catch和finally</strong></p>
<p>异常由包含在try块中的语句捕获:<br />
&nbsp;&nbsp;&nbsp; try{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 正常执行语句<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; catch(XException e){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 异常执行语句一<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; catch(XXException e){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 异常执行语句二<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; catch(XXXException e){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 异常执行语句三<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; finally{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 中止语句<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>Try中的语句体要么顺利完成,要么执行到抛出异常.<br />
如果抛出异常,就要找出对应于异常类或其父类的catch子句,如果未能找到合适的catch子句,异常就从try语句中扩散出来,进入到外层可能对它进行处理的try语句.<br />
Catch子句可以有多个,只要这些子句捕获的异常类型不同.<br />
如果在try中有finally子句,其代码在try把所有其它处理完成之后执行.<br />
无论是正常完成或是出现异常,甚至是通过return或者break这样的控制语句结束,finally子句总是被执行.<br />
Catch子句和finally子句在try语句之后至少有一个,不要求全部出现.</p>
<p><strong>More&#8230;</strong></p>
<p>在catch语句中捕获通用的异常Exception通常不是最佳策略,因为它会将所有异常进行等同处理.<br />
不能把基类异常的catch语句放到子类异常的catch语句之前,编译器会在运行之前就检查出这样的错误.<br />
Try&#8230;catch对每个catch语句都从头到尾检查,如果找到处理同类异常的catch子句,此catch块中的语句将得以执行,而不再处理同层次的其它catch块.<br />
如果catch或finally抛出另一个异常,程序将不会再去检查try的catch子句.<br />
Try...catch语句可以嵌套,内层抛出的异常可被外层处理.</p>
<p><strong>Throws子句</strong></p>
<p>函数能抛出的检查型异常用throws声明,它后面可以是带用逗号隔开的一系列异常类型.仅仅那些在方法中不被捕获的异常必须列出.</p>
<p>private void readObject(java.io.ObjectInputStream s)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws java.io.IOException, ClassNotFoundException {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Read in any hidden serialization magic<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.defaultReadObject();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Read in size<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int size = s.readInt();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Initialize header<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; header = new Entry&lt;E&gt;(null, null, null);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; header.next = header.previous = header;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Read in all elements in the proper order.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i=0; i&lt;size; i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; addBefore((E)s.readObject(), header);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p><strong>More&#8230;</strong></p>
<p>Throws子句的约定是严格强制性的,只能抛出throws子句中声明的异常类型,抛出其它类型的异常是非法的,不管是直接利用throw,还是调用别的方法间接的抛出.<br />
RuntimeException和Error是仅有的不必由throws子句列出的异常.<br />
调用函数的函数要么处理对声明的异常进行处理,要么也声明同样的异常,将收到的异常抛向上层.</p>
<p><strong>对检查型异常通常进行的几种处理<br />
</strong>1) 用e.printStackTrace()输出异常信息.<br />
2) 将异常记录到日志中以备查,如logger.error(e.getMessage()).<br />
3) 试图进行异常恢复.<br />
4) 告知维护者和用户发生的情况.<br />
</p>
 <img src ="http://www.blogjava.net/junglesong/aggbug/181192.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junglesong/" target="_blank">和风细雨</a> 2008-02-21 20:09 <a href="http://www.blogjava.net/junglesong/archive/2008/02/21/181192.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>嵌套类和匿名类概述</title><link>http://www.blogjava.net/junglesong/archive/2008/02/21/181191.html</link><dc:creator>和风细雨</dc:creator><author>和风细雨</author><pubDate>Thu, 21 Feb 2008 12:03:00 GMT</pubDate><guid>http://www.blogjava.net/junglesong/archive/2008/02/21/181191.html</guid><wfw:comment>http://www.blogjava.net/junglesong/comments/181191.html</wfw:comment><comments>http://www.blogjava.net/junglesong/archive/2008/02/21/181191.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junglesong/comments/commentRss/181191.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junglesong/services/trackbacks/181191.html</trackback:ping><description><![CDATA[<p><strong>内部类的出现</strong></p>
<p>当进行Java开发时,有时需要实现一个仅包含1-2个方法的接口.在AWT和Swing开发中经常出现这种情况,例如当一个display组件需要一个事件回调方法如一个按钮的ActionListener时. 如果使用普通的类来实现此操作,最终会得到很多仅在单个位置上使用的小型类. <br />
内部类用于处理这种情况,java允许定义内部类,而且可在Gui外使用内部类.</p>
<p><strong>内部类的定义和实现</strong></p>
<p>内部类是指在另一个类内部定义的一个类.可以将内部类定义为一个类的成员.<br />
public class Linker{<br />
&nbsp; public class LinkedNode{<br />
&nbsp;&nbsp;&nbsp; private LinkedNode prev;<br />
&nbsp;&nbsp;&nbsp; private LinkedNode next;<br />
&nbsp;&nbsp;&nbsp; private String content;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public LinkedNode(String content){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.content=content;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; public Linker(){<br />
&nbsp;&nbsp;&nbsp; LinkedNode first=new LinkedNode("First");<br />
&nbsp;&nbsp;&nbsp; LinkedNode second=new LinkedNode("Second");<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; first.next=second;<br />
&nbsp;&nbsp;&nbsp; second.prev=first;<br />
&nbsp; }<br />
}</p>
<p>定义在一个类方法中的内部类</p>
<p>public class Hapiness{<br />
&nbsp; interface Smiler{<br />
&nbsp;&nbsp;&nbsp; public void smile();<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; public static void main(String[] args){<br />
&nbsp;&nbsp;&nbsp; class Happy implements Smiler{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void smile(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(":-}");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; Happy happy=new Happy();<br />
&nbsp;&nbsp;&nbsp; happy.smile();<br />
&nbsp; }<br />
}</p>
<p><strong>匿名类</strong></p>
<p>对很多情况而言,定义在方法内部的类名意义不大,它可以保持为匿名的,程序员关心的只是它的实例名.<br />
如:<br />
Runnable runner=new Runnable(){<br />
&nbsp;&nbsp;&nbsp;&nbsp; public void&nbsp; run(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Run statememnt<br />
&nbsp;&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p><br />
<strong>理解匿名类</strong></p>
<p>匿名类并不难理解,它只是把类的定义过程和实例的创建过程混合而已,上页的语句实际上相当于如下语句:<br />
// 定义类<br />
Public class Runner implements Runnable{<br />
&nbsp;&nbsp;&nbsp;&nbsp; public void run(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // do sth<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p>// 创建实例<br />
Runner runner=new Runner();</p>
<p><strong>使用匿名类的筛选解耦过程</strong></p>
<p>需求:从公司的职员列表中,找出男性且年龄大于22的成员.</p>
<p>传统写法: </p>
<p>&nbsp;&nbsp; List allmembers=company.getMembers();// 取得所有成员<br />
&nbsp;&nbsp;&nbsp; List results=new ArrayList();// 结果列表<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; for(Iterator it=allmembers.iterator();it.hasNext();){<br />
&nbsp;&nbsp;&nbsp;&nbsp; Member member=(Member)it.next();<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; if(member.getAge()&gt;22 &amp;&amp; member.isMale()){&nbsp; // 筛选,这里是把查询条件和遴选过程融合在一起,条件一变立即就得加个分支.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; results.add(member);<br />
&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; } <br />
<strong>传统方法的缺陷</strong></p>
<p>这种写法没有错,但是不是面向对象的写法,它有以下缺陷:<br />
1.查询条件和筛选过程没有分离.<br />
2.这样写的后果使Company变成了一个失血模型而不是领域模型.<br />
3.换查询条件的话,上面除了"筛选"一句有变化外其它都是模板代码,重复性很高.</p>
<p><strong>使用匿名类实现的OO化查询</strong></p>
<p>真正符合OO的查询应该是这样:</p>
<p>&nbsp;&nbsp; MemberFilter filter1=new MemberFilter(){<br />
&nbsp;&nbsp;&nbsp; public boolean accept(Member member) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return member.isMale() &amp;&amp; member.getAge()&gt;22;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; };<br />
&nbsp;&nbsp; <br />
&nbsp;&nbsp; List ls=company.listMembers(filter1);<br />
&nbsp;</p>
<p>这段代码成功的把查询条件作为一个接口分离了出去,接口代码如下:</p>
<p>public interface MemberFilter{<br />
&nbsp; public boolean accept(Member member); <br />
}</p>
<p>查询函数的变化</p>
<p>而类Company增加了这样一个函数:</p>
<p>public List searchMembers(MemberFilter memberFilter){<br />
&nbsp;&nbsp; List retval=new ArrayList();<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; for(Iterator it=members.iterator();it.hasNext();){<br />
&nbsp;&nbsp;&nbsp;&nbsp; Member member=(Member)it.next();<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; if(memberFilter.accept(member)){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval.add(member);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; }&nbsp; <br />
&nbsp;&nbsp; <br />
&nbsp;&nbsp; return retval;<br />
}<br />
这就把模板代码归结到了类内部,外面不会重复书写了.Company也同时拥有了数据和行为,而不是原来的数据容器了.</p>
<p><strong>匿名类的例子二</strong></p>
<p>用匿名类处理分类汇总的方法 分类汇总是统计中常用,举例来说如统计学生成绩,及格不及格的归类,分优良中差等级归类等,每个单项代码很好写,但是如果分类汇总的项目多了,能一种汇总写一个函数吗? 比如说有些科目60分才算及格,有些科目50分就算;有些老师喜欢分优良中差四等,有些老师却喜欢分ABCD;不一而足,如果每个都写一个函数无疑是个编写和维护恶梦. 如果我们用匿名类把分类汇总的规则和分类汇总的过程分别抽象出来,代码就清晰灵活多了,以下代码讲述了这个过程.</p>
<p>基本类Student</p>
<p>public class Student{<br />
&nbsp;&nbsp;&nbsp; private String name;<br />
&nbsp;&nbsp;&nbsp; private int score;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public Student(String name,int score){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.name=name;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.score=score;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public String getName() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return name;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; public void setName(String name) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.name = name;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; public int getScore() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return score;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; public void setScore(int score) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.score = score;<br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br />
}</p>
<p>用于分类汇总的类</p>
<p>它强制子类实现getKey和getvalue两个方法:<br />
public abstract class ClassifyRule {<br />
&nbsp;&nbsp;&nbsp; public Student student;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public ClassifyRule(){&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp; public void setStudent(Student student) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.student = student;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; abstract public String getKey();<br />
&nbsp;&nbsp;&nbsp; abstract public int getValue();<br />
}</p>
<p>对Student进行统计处理的StudentService类</p>
<p>注意getSum方法,它保留了筛选过程,筛选规则则不在其中:<br />
import java.util.ArrayList;<br />
import java.util.Hashtable;<br />
import java.util.List;</p>
<p>public class StudentService {<br />
&nbsp;&nbsp;&nbsp; private List&lt;Student&gt; students;</p>
<p>&nbsp;&nbsp;&nbsp; public StudentService() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; students = new ArrayList&lt;Student&gt;();<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; public void add(Student student) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; students.add(student);<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; public Hashtable&lt;String, Integer&gt; getSum(ClassifyRule rule) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hashtable&lt;String, Integer&gt; ht = new Hashtable&lt;String, Integer&gt;();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (Student student : students) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rule.setStudent(student);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String key = rule.getKey();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int value = rule.getValue();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ht.containsKey(key)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Integer oldValue = ht.remove(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oldValue += value;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ht.put(key, oldValue);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ht.put(key, value);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ht;<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p>测试代码,注意其中筛选规则的创建</p>
<p>public class Test {<br />
&nbsp;&nbsp;&nbsp; public static void main(String[] args) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 初始化<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StudentService service = new StudentService();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service.add(new Student("Andy", 90));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service.add(new Student("Bill", 95));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service.add(new Student("Cindy", 70));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service.add(new Student("Dural", 85));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service.add(new Student("Edin", 60));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service.add(new Student("Felix", 55));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service.add(new Student("Green", 15));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 60分及格筛选<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ClassifyRule rule60 = new ClassifyRule() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getKey() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return student.getScore() &gt;= 60 ? "及格" : "不及格";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int getValue() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("60分及格筛选");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printHt(service.getSum(rule60));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 50分及格筛选<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ClassifyRule rule50 = new ClassifyRule() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getKey() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return student.getScore() &gt;= 50 ? "及格" : "不及格";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int getValue() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("\n50分及格筛选");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printHt(service.getSum(rule50));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 分"优良中差"等级<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ClassifyRule ruleCn = new ClassifyRule() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getKey() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String retval = "";</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int score = student.getScore();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (score &gt;= 90) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = "优";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (score &gt;= 80) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = "良";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (score &gt;= 60) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = "中";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (score &gt; 0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = "差";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int getValue() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</p>
<p>测试代码</p>
<p>&nbsp;System.out.println("\n分优良中差等级筛选");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printHt(service.getSum(ruleCn));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 分"ABCD"等级<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ClassifyRule ruleWest = new ClassifyRule() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getKey() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String retval = "";</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int score = student.getScore();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (score &gt;= 90) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = "A";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (score &gt;= 80) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = "B";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (score &gt;= 60) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = "C";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (score &gt; 0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = "D";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int getValue() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("\n分ABCD等级筛选");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printHt(service.getSum(ruleWest));<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; private static void printHt(Hashtable ht) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (Iterator it = ht.keySet().iterator(); it.hasNext();) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String key = (String) it.next();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Integer value = (Integer) ht.get(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Key=" + key + " Value=" + value);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p>测试结果如下:</p>
<p>&nbsp;</p>
<p>60分及格筛选<br />
Key=及格 Value=5<br />
Key=不及格 Value=2</p>
<p>50分及格筛选<br />
Key=及格 Value=6<br />
Key=不及格 Value=1</p>
<p>分优良中差等级筛选<br />
Key=优 Value=2<br />
Key=良 Value=1<br />
Key=中 Value=2<br />
Key=差 Value=2</p>
<p>分ABCD等级筛选<br />
Key=A Value=2<br />
Key=D Value=2<br />
Key=C Value=2<br />
Key=B Value=1</p>
<p><strong>小结</strong></p>
<p>内部类也叫嵌套类,一般不提倡书写,但它在java核心类中都存在,如接口Map中的Entry,我们应该了解并能解读这种方法.</p>
<p>匿名类相对而言有用得多,在解耦合和事件回调注册中很常见,大家应该对它的运用融会贯通.<br />
</p>
 <img src ="http://www.blogjava.net/junglesong/aggbug/181191.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junglesong/" target="_blank">和风细雨</a> 2008-02-21 20:03 <a href="http://www.blogjava.net/junglesong/archive/2008/02/21/181191.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>常用开发术语表</title><link>http://www.blogjava.net/junglesong/archive/2008/02/21/181189.html</link><dc:creator>和风细雨</dc:creator><author>和风细雨</author><pubDate>Thu, 21 Feb 2008 11:57:00 GMT</pubDate><guid>http://www.blogjava.net/junglesong/archive/2008/02/21/181189.html</guid><wfw:comment>http://www.blogjava.net/junglesong/comments/181189.html</wfw:comment><comments>http://www.blogjava.net/junglesong/archive/2008/02/21/181189.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junglesong/comments/commentRss/181189.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junglesong/services/trackbacks/181189.html</trackback:ping><description><![CDATA[<p>Abstract class:抽象类<br />
Abstract method:抽象方法<br />
Annotation:注释<br />
Anonymous class:匿名类<br />
API(Application Programming Interface):应用编程接口,由方法和语言构成的库.<br />
ArrayList:实现了List接口的动态数组<br />
Assertion:断言<br />
Atrribute map:属性映射<br />
Autoboxing:自动装箱,表示一个内置类型如int和它的包装类如Integer之间的自动转换</p>
<p>Boolean function:布尔函数<br />
Bytecode:字节码</p>
<p>Casting:类型强制转换<br />
Channel:频道<br />
ClassCastException:当一个对象引用强制转换程一个不兼容的类型时出现的异常.<br />
Collection:一个表示对象组或集合的接口<br />
CSV(Comma-separated values):一种用于存储表格数据的文件形式<br />
Complier:编译器<br />
Compose:合成<br />
Composite function:复合函数,通过多个函数创建的一个函数</p>
<p>Decimal:十进制<br />
Deep:深度<br />
DOM(Document Object Model):文档对象模型,一种采用树形表示来处理XML数据的API.<br />
Database:数据库</p>
<p>Edge:边<br />
Element:元素,XML文档中的一个节点.<br />
Encapsulation:封装<br />
End tag:结束标签<br />
Enum:枚举<br />
Escaping:转义</p>
<p>Function:函数<br />
Fuzzy search:模糊搜索</p>
<p>Generic:泛型<br />
Graph:图<br />
GUI:用户图形界面<br />
Grid computing:网格计算<br />
Group:组</p>
<p>HashMap:一个将键值映射到值的查找对象<br />
Heap memory:堆内存<br />
HTML(Hyper Text Markup Language):超文本标记语言<br />
HTTP(HyperText Tranfer Protocol):超文本传输协议</p>
<p>Inheritance:继承<br />
Inner class:内部类<br />
Iterator:允许迭代到任何Collection类的一个接口</p>
<p>JDBC(Java Database Connectivity):java数据库连接,一种属于Java核心库的用于操作关系数据库的API.<br />
JDK(Java Development Kit):java开发工具包<br />
JRE(Java Runtime Environment):java运行时环境<br />
JSP(Java Server Page):java服务页<br />
JVM(Java Virtual machine):Java虚拟机<br />
JavaDoc:属于JDK的一种文档生成工具<br />
JavaScript:运行于客户端,用于HTML处理的一种轻量级教本语言,语法部分类似于Java.</p>
<p>Layout:布局<br />
Lexical analysis:词法分析<br />
Linked List:链表</p>
<p>Matcher:一个用于正则表达式模式匹配的Java类<br />
Metadata:元数据<br />
Millisecond:微妙</p>
<p>Namespace:命名空间<br />
Neural network:神经网络<br />
Node:节点</p>
<p>Object-oriented programmming:面向对象编程<br />
Object pool:可以从中获得对象的一个实例池<br />
Origin:原点<br />
Override:子类覆写父类的方法</p>
<p>Parser:分析器<br />
Patch:补丁<br />
Pattern:模式<br />
Polymorphism:多态性<br />
Port:端口<br />
Predicate:谓词<br />
Prefix:前缀<br />
Procedural language:过程式语言,如C<br />
Property:属性</p>
<p>Real time:实时<br />
Recursive:递归<br />
Reference:引用<br />
Reflection:反射<br />
Regular expression:正则表达式<br />
Relative:相对<br />
Resource:资源<br />
Runnable:多线程编程使用的一个接口.</p>
<p>Syntax:语法<br />
Screen scraping:屏幕抓取<br />
Split:分割<br />
State:状态<br />
Static:静态<br />
Sequence:序列<br />
Swing:构建在AWT上更高级的图形用户界面<br />
Synchronized:同步,用于线程安全协作的技术</p>
<p>Tag:标签<br />
Thread:进程<br />
Tiger : Sun给Java1.5的代号<br />
Token:标记<br />
Translation:平移<br />
Triple:三元组<br />
Type:类型</p>
<p>Unicode:统一字符界面<br />
Unit testing:单元测试</p>
<p>Visitor pattern:访问者模式</p>
<p>WAR(Web Application Archive):Web应用程序归档<br />
Web Service:Web服务<br />
Weight:权<br />
Well-formed:格式良好的<br />
Whitespace:空白符</p>
<p>XML(Extensible Markup Language):一种描述分级数据结构的文本标记语言<br />
</p>
 <img src ="http://www.blogjava.net/junglesong/aggbug/181189.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junglesong/" target="_blank">和风细雨</a> 2008-02-21 19:57 <a href="http://www.blogjava.net/junglesong/archive/2008/02/21/181189.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>链表讲解</title><link>http://www.blogjava.net/junglesong/archive/2008/02/21/181185.html</link><dc:creator>和风细雨</dc:creator><author>和风细雨</author><pubDate>Thu, 21 Feb 2008 11:26:00 GMT</pubDate><guid>http://www.blogjava.net/junglesong/archive/2008/02/21/181185.html</guid><wfw:comment>http://www.blogjava.net/junglesong/comments/181185.html</wfw:comment><comments>http://www.blogjava.net/junglesong/archive/2008/02/21/181185.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junglesong/comments/commentRss/181185.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junglesong/services/trackbacks/181185.html</trackback:ping><description><![CDATA[<p><strong>集合框架的继承体系</strong></p>
<p>Java2中包含了6个集合接口,这些接口的通用目的实现类,以及一个集合实用类Collections,共同组成了集合框架的核心.<br />
6个集合接口如下:<br />
Collection及其以下的List,Set,以及Set下的SortedSet<br />
Map及其以下的SortedMap</p>
<p><strong>链表的通用实现</strong></p>
<p>ArrayList:线程不安全的动态数组类,批量查询速度快,单个查找速度慢.<br />
Vector:线程安全的动态数组类,效率比ArrayList低下.<br />
LinkedList:动态链表类,适于在队列首尾频繁增删成员的场合.</p>
<p><strong>链表的创建</strong></p>
<p>List&lt;Member&gt; ls=new ArrayList&lt;Member&gt;();// 1.5版本及以上</p>
<p>List ls=new ArrayList();// 1.5版本以下</p>
<p>之所以将ls类型指定为List&lt;Member&gt;而不是ArrayList&lt;Member&gt;是因为 如果情况变化, ArrayList需要修改成Vector或LinkedList时无须修改其它代码,仅修改实例类型即可.</p>
<p>向List中添加元素</p>
<p>添加单个元素<br />
ls.add(new Member("Andy",21));</p>
<p>从别的链表中添加多个元素<br />
List&lt;Member&gt; ls2=new ArrayList&lt;Member&gt;();<br />
ls2.add(new Member("Felex",21));<br />
ls2.add(new Member("Gates",23));<br />
ls.addAll(ls2);</p>
<p>注意:<br />
1.5及其以上版本中,添加的元素必须和定义时一致,如ls的类型是List&lt;Member&gt;,那么向其中添加的元素必须是Member或其子类.<br />
1.5以下版本中,对添加的元素不作检查,只要是Object即可,如果是基本类型则需装箱成类类型.如ls.add(new Integer(8));</p>
<p><strong>删除链表中元素</strong></p>
<p>ls.remove(member); // 直接删除对象,member=new Member("Edin",28)<br />
ls.remove(2);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 删除第三个元素<br />
ls.clear();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 将已有数据全部清除</p>
<p><strong>对链表进行遍历</strong></p>
<p>1) 1.5中独有的遍历方法,代码最短,使用最方便<br />
for(Member member:ls){<br />
&nbsp;&nbsp;&nbsp;&nbsp; // member就是依次取出的每个元素<br />
}</p>
<p>2) 常规方法,多用于需要取得下标的场合,各版本均适用<br />
for(int i=0;i&lt;ls.size();i++){<br />
&nbsp;&nbsp;&nbsp; Member member=ls.get(i);// member就是依次取出的每个元素, 1.5及其以上版本适用, ls.size()为链表长度<br />
&nbsp;&nbsp;&nbsp; Member member=(Member)ls.get(i);// 1.5以下版本适用<br />
}</p>
<p>3) 使用Iterator对链表进行遍历的方法,各版本均适用<br />
for(Iterator it=ls.iterator();it.hasNext();){<br />
&nbsp;&nbsp;&nbsp; Member member=(Member)it.next();<br />
}</p>
<p><strong>链表的其它常用的方法</strong></p>
<p>ls.contains(Object o);// 返回链表中是否包含某元素<br />
ls.indexOf(Object o);// 返回对象o是链表中的第几号元素<br />
isEmpty();// 返回链表中是否有元素</p>
<p>对链表进行排序<br />
1）让List中元素必须已经实现Comparable接口:<br />
public class Member implements Comparable {<br />
&nbsp; private String name;</p>
<p>&nbsp; private int age;</p>
<p>&nbsp; public Member(String name, int age) {<br />
&nbsp;&nbsp;&nbsp; this.name = name;<br />
&nbsp;&nbsp;&nbsp; this.age = age;<br />
&nbsp; }</p>
<p>&nbsp; public int compareTo(Object obj) {<br />
&nbsp;&nbsp;&nbsp; Member another = (Member) obj;<br />
&nbsp;&nbsp;&nbsp; return this.name.compareTo(another.name);// 按名称排序,如果是this.age-another.age则按年龄排序<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; public String toString(){<br />
&nbsp;&nbsp;&nbsp; return "Member name="+name+" age="+age;<br />
&nbsp; }<br />
}</p>
<p>2）排序过程<br />
List&lt;Member&gt; ls=new ArrayList&lt;Member&gt;();</p>
<p>ls.add(new Member("Felex",21));<br />
ls.add(new Member("Gates",23));<br />
ls.add(new Member("Andy",21));<br />
ls.add(new Member("Bill",23));<br />
ls.add(new Member("Cindy",24));<br />
ls.add(new Member("Dell",27));</p>
<p>Collections.sort(ls);</p>
<p>for(Member member:ls){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(member);<br />
}</p>
<p>输出:<br />
Member name=Andy age=21<br />
Member name=Bill age=23<br />
Member name=Cindy age=24<br />
Member name=Dell age=27<br />
Member name=Felex age=21<br />
Member name=Gates age=23</p>
<p>// 如果需要逆序可以使用Collections.reverse(ls);</p>
<p><strong>链表与数组之间的转换</strong></p>
<p>1) List转换成数组<br />
List&lt;String&gt; ls=new ArrayList&lt;String&gt;();</p>
<p>ls.add("Felex");<br />
ls.add("Gates");<br />
ls.add("Andy");<br />
ls.add("Bill");<br />
ls.add("Cindy");<br />
ls.add("Dell");</p>
<p>Object[] arr=ls.toArray();<br />
for(Object obj:arr){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println((Object)obj);<br />
}</p>
<p>输出为:<br />
Felex<br />
Gates<br />
Andy<br />
Bill<br />
Cindy<br />
Dell</p>
<p>2) 数组转换成List<br />
String[] arr={"Andy","Bill","Cindy","Dell"};<br />
List&lt;String&gt; ls=Arrays.asList(arr);<br />
for(String str:ls){<br />
&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(str);<br />
}</p>
<p>输出:<br />
Andy<br />
Bill<br />
Cindy<br />
Dell<br />
</p>
 <img src ="http://www.blogjava.net/junglesong/aggbug/181185.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junglesong/" target="_blank">和风细雨</a> 2008-02-21 19:26 <a href="http://www.blogjava.net/junglesong/archive/2008/02/21/181185.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hashtable基本用法概述</title><link>http://www.blogjava.net/junglesong/archive/2008/02/21/181184.html</link><dc:creator>和风细雨</dc:creator><author>和风细雨</author><pubDate>Thu, 21 Feb 2008 11:20:00 GMT</pubDate><guid>http://www.blogjava.net/junglesong/archive/2008/02/21/181184.html</guid><wfw:comment>http://www.blogjava.net/junglesong/comments/181184.html</wfw:comment><comments>http://www.blogjava.net/junglesong/archive/2008/02/21/181184.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junglesong/comments/commentRss/181184.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junglesong/services/trackbacks/181184.html</trackback:ping><description><![CDATA[<p>Hashtable-哈希表类</p>
<p>以哈希表的形式存储数据,数据的形式是键值对.<br />
特点:<br />
查找速度快,遍历相对慢<br />
键值不能有空指针和重复数据</p>
<p><strong>创建<br />
</strong>Hashtable&lt;Integer,String&gt; ht=new Hashtable&lt;Integer,String&gt;();</p>
<p><strong>添值</strong></p>
<p>ht.put(1,"Andy");<br />
ht.put(2,"Bill");<br />
ht.put(3,"Cindy");<br />
ht.put(4,"Dell");<br />
ht.put(5,"Felex");<br />
ht.put(6,"Edinburg");<br />
ht.put(7,"Green");</p>
<p><strong>取值</strong></p>
<p>String str=ht.get(1);<br />
System.out.println(str);// Andy</p>
<p><strong>对键进行遍历</strong></p>
<p>Iterator it = ht.keySet().iterator();</p>
<p>while (it.hasNext()) {<br />
&nbsp;&nbsp;&nbsp; Integer key = (Integer)it.next();<br />
&nbsp;&nbsp;&nbsp; System.out.println(key);<br />
}</p>
<p><strong>对值进行遍历</strong></p>
<p>Iterator it = ht.values().iterator();</p>
<p>while (it.hasNext()) {<br />
&nbsp;&nbsp;&nbsp; String value =(String) it.next();<br />
&nbsp;&nbsp;&nbsp; System.out.println(value);<br />
}</p>
<p><strong>取Hashtable记录数</strong></p>
<p>Hashtable&lt;Integer,String&gt; ht=new Hashtable&lt;Integer,String&gt;();</p>
<p>ht.put(1,"Andy");<br />
ht.put(2,"Bill");<br />
ht.put(3,"Cindy");<br />
ht.put(4,"Dell");<br />
ht.put(5,"Felex");<br />
ht.put(6,"Edinburg");<br />
ht.put(7,"Green");</p>
<p>int i=ht.size();// 7</p>
<p><strong>删除元素</strong></p>
<p>Hashtable&lt;Integer,String&gt; ht=new Hashtable&lt;Integer,String&gt;();</p>
<p>ht.put(1,"Andy");<br />
ht.put(2,"Bill");<br />
ht.put(3,"Cindy");<br />
ht.put(4,"Dell");<br />
ht.put(5,"Felex");<br />
ht.put(6,"Edinburg");<br />
ht.put(7,"Green");</p>
<p>ht.remove(1);<br />
ht.remove(2);<br />
ht.remove(3);<br />
ht.remove(4);</p>
<p>System.out.println(ht.size());// 3</p>
<p><br />
Iterator it = ht.values().iterator();</p>
<p>while (it.hasNext()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Get value<br />
&nbsp;&nbsp;&nbsp; String value =(String) it.next();<br />
&nbsp;&nbsp;&nbsp; System.out.println(value);<br />
}</p>
<p>输出:<br />
3<br />
Green<br />
Edinburg<br />
Felex</p>
<p>&nbsp;</p>
 <img src ="http://www.blogjava.net/junglesong/aggbug/181184.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junglesong/" target="_blank">和风细雨</a> 2008-02-21 19:20 <a href="http://www.blogjava.net/junglesong/archive/2008/02/21/181184.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>接口与抽象类概述</title><link>http://www.blogjava.net/junglesong/archive/2008/02/21/181182.html</link><dc:creator>和风细雨</dc:creator><author>和风细雨</author><pubDate>Thu, 21 Feb 2008 11:09:00 GMT</pubDate><guid>http://www.blogjava.net/junglesong/archive/2008/02/21/181182.html</guid><wfw:comment>http://www.blogjava.net/junglesong/comments/181182.html</wfw:comment><comments>http://www.blogjava.net/junglesong/archive/2008/02/21/181182.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junglesong/comments/commentRss/181182.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junglesong/services/trackbacks/181182.html</trackback:ping><description><![CDATA[<p><strong>类,抽象类与接口</strong></p>
<p>类,抽象类与接口都是Java中实现继承和多态的手段.<br />
类强调的是继承<br />
接口强调的是规范<br />
抽象类兼而有之</p>
<p><strong>什么是接口</strong></p>
<p>接口是一种特殊的类,它只有方法定义而没有实现,实现的任务完全交给子类完成.<br />
接口以interface标志.<br />
继承接口用implements关键字实现.<br />
接口可以继承接口.<br />
接口可以有成员,但成员全是public static final类型的.<br />
接口没有构造函数.<br />
接口给Java提供了多继承机制</p>
<p><strong>接口例子—Knockable</strong></p>
<p>public interface Knockable{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String Sound="Bang!";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void knock();<br />
}</p>
<p><strong>接口例子-实现接口</strong></p>
<p>public class Hammer implements Knockable{<br />
&nbsp;&nbsp;&nbsp; public void knock(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(Sound);<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p><strong>接口例子-实现多个接口</strong></p>
<p>public interface Knockable{<br />
&nbsp;&nbsp;&nbsp; public static final String Sound="Bang!";<br />
&nbsp;&nbsp;&nbsp; public void knock();<br />
}</p>
<p>public interface Clampable {<br />
&nbsp;&nbsp;&nbsp; public void clamp();<br />
}</p>
<p>public class Pliers implements Knockable,Clampable{<br />
&nbsp;&nbsp; public void clamp(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // do sth<br />
&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp; public void knock(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(Sound);<br />
&nbsp;&nbsp; }<br />
}</p>
<p><strong>接口继承接口例子</strong></p>
<p>public interface Knockable{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static final String Sound="Bang!";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void knock();<br />
}</p>
<p>public interface Hitable extends Knockable{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void hit();<br />
}</p>
<p>public class Stick implements Hitable{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void knock(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp; do sth<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void hit(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // do sth<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p><strong>什么叫抽象类</strong></p>
<p>类中具有抽象方法的类为抽象类.抽象方法以abstract在函数前修饰,只有定义没有实现,这一点和接口一致.<br />
抽象类在类名前需加上abstract修饰符以标识.<br />
抽象类不能生成实例.<br />
抽象类的继承性和类一致.</p>
<p><strong>抽象类的实现</strong></p>
<p>public abstract class Gun{<br />
&nbsp; protected String cannon;<br />
&nbsp; protected List&lt;Bullet&gt; bullets;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp; public abstract void shoot();<br />
&nbsp; <br />
&nbsp; public void addBullet(Bullet bullet){<br />
&nbsp;&nbsp;&nbsp; if(bullets==null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bullets=new LinkedList&lt;Bullet&gt;();<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; bullets.add(bullet);<br />
&nbsp; }<br />
}</p>
<p><strong>继承抽象类</strong></p>
<p>public class Rifle extends Gun{ <br />
&nbsp; public void shoot(){<br />
&nbsp;&nbsp;&nbsp; // Shoot Sth<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; public void reload(){<br />
&nbsp;&nbsp;&nbsp; if(bullets!=null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bullets.clear();<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; addBullet(new Bullet());<br />
&nbsp;&nbsp;&nbsp; addBullet(new Bullet());<br />
&nbsp;&nbsp;&nbsp; addBullet(new Bullet());<br />
&nbsp;&nbsp;&nbsp; addBullet(new Bullet());<br />
&nbsp;&nbsp;&nbsp; addBullet(new Bullet());<br />
&nbsp;&nbsp;&nbsp; addBullet(new Bullet());<br />
&nbsp; }<br />
}</p>
<p><strong>继承抽象类并实现接口</strong></p>
<p>public abstract class Gun{<br />
&nbsp; protected String cannon;<br />
&nbsp; protected List&lt;Bullet&gt; bullets;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp; public abstract void shoot();<br />
&nbsp; <br />
&nbsp; public void addBullet(Bullet bullet){<br />
&nbsp;&nbsp;&nbsp; if(bullets==null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bullets=new LinkedList&lt;Bullet&gt;();<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; bullets.add(bullet);<br />
&nbsp; }<br />
}</p>
<p>public interface Thornable{<br />
&nbsp; public void thorn();<br />
}</p>
<p>public class SpringFieldRifle extends Gun implements Thornable{<br />
&nbsp; public void thorn(){<br />
&nbsp;&nbsp;&nbsp; // thorn sth<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; public void shoot(){<br />
&nbsp;&nbsp;&nbsp; // shoot sth<br />
&nbsp; }<br />
}</p>
<p><strong>抽象类继承抽象类实现接口的例子</strong></p>
<p>public abstract class Gun{<br />
&nbsp; protected String cannon;<br />
&nbsp; protected List&lt;Bullet&gt; bullets;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp; public abstract void shoot();<br />
&nbsp; <br />
&nbsp; public void addBullet(Bullet bullet){<br />
&nbsp;&nbsp;&nbsp; if(bullets==null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bullets=new LinkedList&lt;Bullet&gt;();<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; bullets.add(bullet);<br />
&nbsp; }<br />
}</p>
<p>public interface Handable{<br />
&nbsp; public void hold();<br />
}</p>
<p>public abstract class HandGun extends Gun implements Handable{</p>
<p>}</p>
<p>public class BlackStar extends HandGun{<br />
&nbsp; public void hold(){<br />
&nbsp;&nbsp;&nbsp; // Hold the gun<br />
&nbsp; }<br />
&nbsp; <br />
&nbsp; public void shoot(){<br />
&nbsp;&nbsp;&nbsp; // Shoot Sth<br />
&nbsp; }<br />
}</p>
<p><strong>抽象类,接口,类的区别<br />
</strong><br />
继承好比家学渊源,所谓"忠厚传家久,诗书继世长",家长总会潜移默化的影响下一代,下一代也会在不经意中学习前辈的特点,但因为年少分辨能力不高加上世易时移有些优点已经不再是有点甚至会变成缺点,下一代会把前辈的优缺点不分良莠的继承下来.这也是日后出现问题的根源.</p>
<p>接口好比拜师学艺,"入了这个门,就得说这行话",比如相声界说学逗唱四门是必须要学的,但是"师傅领进门,修行在个人",学得怎么样还全看自己,指望不费力的继承什么是不可能的,具体功夫还得个人来过. 因为是自己来,具体实现成什么样自由度也很大,比如四门功课中的"唱",原指唱太平歌词,但因为爱听的少,现在相声演员已经不要求这个了,改为唱歌唱戏的唱,其实严格界定的话是"学"的一种.这也无所谓对错,郭德刚坚持唱太平歌词也行,笑林唱流行歌曲也不错,总之实现了就可以,实现得怎么样则留给实践来检验.一个类可以同时实现多个接口,就和艺人拜几个师傅是没有问题的,郭德刚就同时实现了大鼓和相声两个接口.</p>
<p>抽象类则介于继承和接口之间,既可不费力的从上一代继承,也可强制实现某接口,有如某大师收自己的孩子为徒,当然相声界不让这么干,其它曲艺行业还是可以的,比如京剧界的梅兰芳和其子梅葆玖,既有言传身教,也有强制实现,综合了继承和接口的特点. </p>
<p><strong>抽象类,接口,类的详细区别<br />
</strong></p>
<p><strong>
<table style="width: 688px; height: 302px" cellspacing="2" cellpadding="2" width="688" border="1">
    <tbody>
        <tr>
            <td></td>
            <td>接口</td>
            <td>抽象类</td>
            <td>类</td>
        </tr>
        <tr>
            <td style="width: 29px; height: 25px">可以继承自</td>
            <td>接口</td>
            <td>抽象类,类</td>
            <td>抽象类,类</td>
        </tr>
        <tr>
            <td>可以实现自</td>
            <td>无</td>
            <td>一个或多个接口</td>
            <td>一个或多个接口</td>
        </tr>
        <tr>
            <td>有否成员</td>
            <td>只有static final成员</td>
            <td>均可</td>
            <td>均可</td>
        </tr>
        <tr>
            <td>是否有构造函数</td>
            <td>无</td>
            <td>有</td>
            <td>有</td>
        </tr>
        <tr>
            <td>可否实例化</td>
            <td>不可</td>
            <td>不可</td>
            <td>可</td>
        </tr>
        <tr>
            <td>意图</td>
            <td>规范行为</td>
            <td>继承成员+规范行为</td>
            <td>继承成员</td>
        </tr>
    </tbody>
</table>
<br />
<br />
抽象类,接口和类在继承体系中的位置</strong></p>
<p>抽象类,接口一般来说都是从一般类总结归纳出来的抽象共性的东西,类则是实际具体的东西.<br />
一般来说,应该把合理抽象出的抽象类,接口放在类继承体系的上层,子类依靠类来实现.</p>
 <img src ="http://www.blogjava.net/junglesong/aggbug/181182.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junglesong/" target="_blank">和风细雨</a> 2008-02-21 19:09 <a href="http://www.blogjava.net/junglesong/archive/2008/02/21/181182.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>