﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-風向逆轉 - 就要爪哇-文章分类-Java基础知识</title><link>http://www.blogjava.net/iKingQu/category/8100.html</link><description>Java菜鸟升级中...</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 10:43:29 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 10:43:29 GMT</pubDate><ttl>60</ttl><item><title>[收藏]Random类的使用方法</title><link>http://www.blogjava.net/iKingQu/articles/80355.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Fri, 10 Nov 2006 03:37:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/80355.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/80355.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/80355.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/80355.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/80355.html</trackback:ping><description><![CDATA[
		<span style="COLOR: indigo">属于包：java.util.Random</span>
		<br />
		<br />
		<b>Random：随机类型</b>
		<br />
		<br />
		<span style="COLOR: blue">１、属性。</span>
		<br />
		<br />无。<br /><br /><span style="COLOR: blue">２、构造函数。</span><br /><br /><span style="COLOR: green">Random()</span> ：创建一个新的随机数发生器。<br /><br /><span style="COLOR: green">Random(long seed) </span>：用一个种子（长整型）创建一个随机数发生器。<br /><br /><span style="COLOR: blue">３、方法。</span><br /><span style="COLOR: red">说明：<br />1. 所有方法均为public；<br />2. 书写格式：［修饰符］　&lt;返回类型&gt; &lt;方法名（［参数列表］）&gt;</span><span style="COLOR: olive"><br />如：<br />static int parseInt(String s) 表示：此方法（parseInt）为类方法（static），返回类型为（int），方法所需参数为String类型。</span><br /><br /><br /><ul>1. <span style="COLOR: green">protected int next(int bits) </span>：产生下一个伪随机数。<br /><br />2. <span style="COLOR: green">boolean nextBoolean() </span>：返回下一个从随机发生器的系列中得到的均匀分布的布尔值。<br /><br />3. <span style="COLOR: green">void nextBytes(byte[] bytes) </span>：产生随机字节数组放到指定的数组中。<br /><br />4. <span style="COLOR: green">double nextDouble() </span>：返回下一个从随机发生器的系列中得到的均匀分布的0.0到1.0的双精度类型值。<br /><br />5. <span style="COLOR: green">float nextFloat() </span>：返回下一个从随机发生器的系列中得到的均匀分布的0.0到1.0的浮点类型值。<br /><br />6. <span style="COLOR: green">double nextGaussian()</span> ：返回下一个从随机发生器的系列中得到的符合均匀分布的0.0的平均数到1.0方差的高斯分布双精度类型值。<br /><br />7. <span style="COLOR: green">int nextInt() </span>：返回下一个从随机发生器的系列中得到的均匀分布的整型值。<br /><br />8. <span style="COLOR: green">int nextInt(int n) </span>：返回下一个从随机发生器的系列中得到的均匀分布的0到指定整型数（n）之间的整型值。<br /><br />9. <span style="COLOR: green">long nextLong() </span>：返回下一个从随机发生器的系列中得到的均匀分布的长整型值。<br /><br />10. <span style="COLOR: green">void setSeed(long seed) </span>：设置随机数发生器的种子为一个长整型数。</ul><br /><br /><span style="COLOR: red">关于种子的描述：</span><br />这个类的对象使用一个48位的种子，<br />如果这个类的两个实例是用同一个种子创建的，<br />并且，各自对它们以同样的顺序调用方法，<br />则它们会产生相同的数字序列。<br /><br />下面就对上面的介绍做一个实验，<br />尤其注意相同种子时的结果，<br /><span style="COLOR: brown">如果用默认的构造函数构造对象，<br />他们是属于同一个种子的。</span><br /><br /><pre>import java.util.Random;<br /><br />public class TestRandom{<br />	public static void main(String[] args){<br />		Random r1 = new Random(50);<br />		System.out.println("第一个种子为50的Random对象");<br />		System.out.println("r1.nextBoolean():\t" + r1.nextBoolean());<br />		System.out.println("r1.nextInt():\t\t" + r1.nextInt());<br />		System.out.println("r1.nextDouble():\t" + r1.nextDouble());<br />		System.out.println("r1.nextGaussian():\t" + r1.nextGaussian());<br />		System.out.println("---------------------------");<br /><br />		Random r2 = new Random(50);<br />		System.out.println("第二个种子为50的Random对象");<br />		System.out.println("r2.nextBoolean():\t" + r2.nextBoolean());<br />		System.out.println("r2.nextInt():\t\t" + r2.nextInt());<br />		System.out.println("r2.nextDouble():\t" + r2.nextDouble());<br />		System.out.println("r2.nextGaussian():\t" + r2.nextGaussian());<br />		System.out.println("---------------------------");<br /><br />		Random r3 = new Random(100);<br />		System.out.println("种子为100的Random对象");<br />		System.out.println("r3.nextBoolean():\t" + r3.nextBoolean());<br />		System.out.println("r3.nextInt():\t\t" + r3.nextInt());<br />		System.out.println("r3.nextDouble():\t" + r3.nextDouble());<br />		System.out.println("r3.nextGaussian():\t" + r3.nextGaussian());<br /><br />		System.out.println("结果一目了然！");<br />	}<br />}</pre><br />结果：<br /><pre><br />第一个种子为50的Random对象<br />r1.nextBoolean():       true<br />r1.nextInt():           -1727040520<br />r1.nextDouble():        0.6141579720626675<br />r1.nextGaussian():      2.377650302287946<br />---------------------------<br />第二个种子为50的Random对象<br />r2.nextBoolean():       true<br />r2.nextInt():           -1727040520<br />r2.nextDouble():        0.6141579720626675<br />r2.nextGaussian():      2.377650302287946<br />---------------------------<br />种子为100的Random对象<br />r3.nextBoolean():       true<br />r3.nextInt():           -1139614796<br />r3.nextDouble():        0.19497605734770518<br />r3.nextGaussian():      0.6762208162903859<br />结果一目了然！</pre><img src ="http://www.blogjava.net/iKingQu/aggbug/80355.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-11-10 11:37 <a href="http://www.blogjava.net/iKingQu/articles/80355.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]StringBuffer类的使用方法</title><link>http://www.blogjava.net/iKingQu/articles/80354.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Fri, 10 Nov 2006 03:36:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/80354.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/80354.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/80354.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/80354.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/80354.html</trackback:ping><description><![CDATA[
		<strong>StringBuffer：StringBuffer类型<br /><br /></strong>
		<span style="COLOR: darkblue">描述：在实际应用中，经常回遇到对字符串进行动态修改。这时候，String类的功能受到限制，而StringBuffer类可以完成字符串的动态添加、插入和替换等操作。</span>
		<br />
		<br />
		<span style="COLOR: blue">１、构造函数。</span>
		<br />
		<ul>
				<span style="COLOR: green">StringBuffer() </span>：构造一个没有任何字符的StringBuffer类。<br /><span style="COLOR: green">StringBuffer(int length) </span>： ：构造一个没有任何字符的StringBuffer类，并且，其长度为length。<br /><span style="COLOR: green">StringBuffer(String str) </span>：以str为初始值构造一个StringBuffer类。</ul>
		<br />
		<br />
		<span style="COLOR: blue">２、方法。</span>
		<br />
		<span style="COLOR: red">说明：<br />1. 所有方法均为public；<br />2. 书写格式：［修饰符］　&lt;返回类型&gt; &lt;方法名（［参数列表］）&gt;</span>
		<span style="COLOR: olive">
				<br />如：<br />static int parseInt(String s) 表示：此方法（parseInt）为类方法（static），返回类型为（int），方法所需参数为String类型。</span>
		<br />
		<br />
		<ul>
				<span style="COLOR: green">1. StringBuffer append(boolean b) <br />2. StringBuffer append(char c) <br />3. StringBuffer append(char[] str) <br />4. StringBuffer append(char[] str, int offset, int len) <br />5. StringBuffer append(double d) <br />6. StringBuffer append(float f) <br />7. StringBuffer append(int i) <br />8. StringBuffer append(long l) <br />9. StringBuffer append(Object obj) <br />10. StringBuffer append(String str) <br />11. StringBuffer append(StringBuffer sb) </span>
				<br />
				<br />以上的方法都是向字符串缓冲区“追加”元素，但是，这个“元素”参数可以是布尔量、字符、字符数组、双精度数、浮点数、整型数、长整型数对象类型的字符串、字符串和StringBuffer类等。如果添加的字符超出了字符串缓冲区的长度，Java将自动进行扩充。</ul>
		<br />
		<pre>		String question = new String("1+1=");<br />		int answer = 3;<br />		boolean result = (1+1==3);<br /><br />		StringBuffer sb = new StringBuffer();<br />		sb.append(question);<br />		sb.append(answer);<br />		sb.append('\t');<br />		sb.append(result);<br /><br />		System.out.println(sb);<br />结果为：<br />1+1=3   false</pre>
		<br />
		<ul>12. <span style="COLOR: green">int capacity() </span>：返回当前StringBuffer对象（字符串缓冲区）的总空间，而非字符号串的长度。<br />13. <span style="COLOR: green">char charAt(int index) </span>：在当前StringBuffer对象中取索引号为index的字符。第一个字符的索引为“0”<br />14. <span style="COLOR: green">StringBuffer delete(int start, int end) </span>：删除当前StringBuffer对象中以索引号start开始，到end结束的子串。<br />15. <span style="COLOR: green">StringBuffer deleteCharAt(int index) </span>：删除当前StringBuffer对象中索引号为index的字符。<br />16. <span style="COLOR: green">void ensureCapacity(int minimumCapacity)</span> ：重新设置字符号串缓冲区的总空间。如果minimumCapacity大于当前的总空间，则新的空间被设置：一种结果是minimumCapacity；另一种结果是{“老空间”乘2加2}。</ul>
		<br />
		<pre>		StringBuffer sb1 = new StringBuffer(5);<br />		StringBuffer sb2 = new StringBuffer(5);<br /><br />		sb1.ensureCapacity(6);<br />		sb2.ensureCapacity(100);<br /><br />		System.out.println( "sb1.Capacity: " + sb1.capacity() );<br />		System.out.println( "sb2.Capacity: " + sb2.capacity() );<br />结果为：<br />sb1.Capacity: 12<br />sb2.Capacity: 100</pre>
		<br />
		<ul>17. <span style="COLOR: green">void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)</span> ：从当前StringBuffer对象的索引号srcBegin开始，到srcEnd结束的子串，赋值到字符数组dst中，并且从dst的索引号dstBegin开始。</ul>
		<br />
		<pre>		StringBuffer sb = new StringBuffer("I love her!");<br />		char[] i = {'I',' ','l','o','v','e',' ','y','o','u'};<br /><br />		sb.getChars(7,10,i,7);<br /><br />		System.out.println( "sb: " + sb );<br />结果为：sb: I love her!</pre>
		<br />
		<ul>18. <span style="COLOR: green">int indexOf(String str)</span> ：返回当前StringBuffer对象中，第一个满足str子串的位置。<br />19. <span style="COLOR: green">int indexOf(String str, int fromIndex)</span> ：从当前StringBuffer对象的fromIndex开始查找，返回第一个满足str子串的位置。<br /><span style="COLOR: green">20. StringBuffer insert(int offset, boolean b) <br />21. StringBuffer insert(int offset, char c) <br />22. StringBuffer insert(int offset, char[] str) <br />23. StringBuffer insert(int index, char[] str, int offset, int len) <br />24. StringBuffer insert(int offset, double d) <br />25. StringBuffer insert(int offset, float f) <br />26. StringBuffer insert(int offset, int i) <br />27. StringBuffer insert(int offset, long l) <br />28. StringBuffer insert(int offset, Object obj) <br />29. StringBuffer insert(int offset, String str) </span><br /><br />以上的方法都是在当前StringBuffer对象中插入一个元素，在索引号offset处插入相应的值。<br />30. <span style="COLOR: green">int lastIndexOf(String str) </span>：返回当前StringBuffer对象中，最后一个满足str子串的位置。<br />31. <span style="COLOR: green">int lastIndexOf(String str, int fromIndex)</span> ：从当前StringBuffer对象的fromIndex开始查找，返回最后一个满足str子串的位置。<br />32. <span style="COLOR: green">int length() </span>：返回当前StringBuffer对象（字符缓冲区）中，字符串的长度。<span style="COLOR: red">注意：此方法与capacity() 不同。</span><br />33. <span style="COLOR: green">StringBuffer replace(int start, int end, String str)</span> ：替换当前StringBuffer对象的字符串。从start开始，到end结束的位置替换成str。<br />34. <span style="COLOR: green">StringBuffer reverse() </span>：将字符串翻转。</ul>
		<br />
		<pre>		StringBuffer sb = new StringBuffer("0123456789");<br />		System.out.println( "sb.reverse(): " + sb.reverse() );<br />结果为：sb.reverse(): 9876543210</pre>
		<br />
		<ul>35. <span style="COLOR: green">void setCharAt(int index, char ch)</span> ：设置索引号index的字符为ch。<br />36. <span style="COLOR: green">void setLength(int newLength) </span>：重新设置字符串缓冲区中字符串的长度，如果newLength小于当前的字符串长度，将截去多余的字符。</ul>
		<br />
		<pre>		StringBuffer sb = new StringBuffer("0123456789");<br />		sb.setLength(5);<br />		System.out.println( "sb: " + sb );<br />结果为：sb: 01234</pre>
		<br />
		<ul>37.<span style="COLOR: green"> String substring(int start) </span>：取当前StringBuffer对象中，从start开始到结尾的子串。<br />38. <span style="COLOR: green">String substring(int start, int end) </span>：取当前StringBuffer对象中，从start开始到end的子串。<br />39. <span style="COLOR: green">String toString() </span>：将当前StringBuffer对象转换成String对象。</ul>
<img src ="http://www.blogjava.net/iKingQu/aggbug/80354.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-11-10 11:36 <a href="http://www.blogjava.net/iKingQu/articles/80354.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]StringTokenizer类的使用方法</title><link>http://www.blogjava.net/iKingQu/articles/80352.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Fri, 10 Nov 2006 03:35:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/80352.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/80352.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/80352.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/80352.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/80352.html</trackback:ping><description><![CDATA[
		<strong>StringTokenizer：字符串分隔解析类型<br /></strong>
		<span style="COLOR: indigo">属于：java.util包。</span>
		<br />
		<br />
		<span style="COLOR: blue">１、构造函数。</span>
		<br />
		<ul>
				<br />1. <span style="COLOR: green">StringTokenizer(String str)</span> ：构造一个用来解析str的StringTokenizer对象。java默认的分隔符是“空格”、“制表符(‘\t’)”、“换行符(‘\n’)”、“回车符(‘\r’)”。<br />2. <span style="COLOR: green">StringTokenizer(String str, String delim) </span>：构造一个用来解析str的StringTokenizer对象，并提供一个指定的分隔符。<br />3. <span style="COLOR: green">StringTokenizer(String str, String delim, boolean returnDelims) </span>：构造一个用来解析str的StringTokenizer对象，并提供一个指定的分隔符，同时，指定是否返回分隔符。</ul>
		<br />
		<br />
		<span style="COLOR: blue">２、方法。</span>
		<br />
		<span style="COLOR: red">说明：<br />1. 所有方法均为public；<br />2. 书写格式：［修饰符］　&lt;返回类型&gt; &lt;方法名（［参数列表］）&gt;</span>
		<span style="COLOR: olive">
				<br />如：<br />static int parseInt(String s) 表示：此方法（parseInt）为类方法（static），返回类型为（int），方法所需参数为String类型。</span>
		<br />
		<br />
		<ul>1. <span style="COLOR: green">int countTokens() </span>：返回nextToken方法被调用的次数。如果采用构造函数1和2，返回的就是分隔符数量(例2)。<br />2. <span style="COLOR: green">boolean hasMoreTokens() </span>：返回是否还有分隔符。<br />3. <span style="COLOR: green">boolean hasMoreElements() </span>：结果同2。<br />4. <span style="COLOR: green">String nextToken()</span> ：返回从当前位置到下一个分隔符的字符串。<br />5. <span style="COLOR: green">Object nextElement() </span>：结果同4。<br />6. <span style="COLOR: green">String nextToken(String delim)</span> ：与4类似，以指定的分隔符返回结果。</ul>
		<br />
		<br />
		<span style="COLOR: olive">例子：</span>
		<br />
		<pre>		String s = new String("The Java platform is the ideal platform for network computing");<br />		StringTokenizer st = new StringTokenizer(s);<br />		System.out.println( "Token Total: " + st.countTokens() );<br />		while( st.hasMoreElements() ){<br />			System.out.println( st.nextToken() );<br />　　　　　　　　　　　}<br />结果为：<br />Token Total: 10<br />The<br />Java<br />platform<br />is<br />the<br />ideal<br />platform<br />for<br />network<br />computing<br /></pre>
		<br />
		<span style="COLOR: olive">例2:</span>
		<br />
		<pre>		String s = new String("The=Java=platform=is=the=ideal=platform=for=network=computing");<br />		StringTokenizer st = new StringTokenizer(s,"=",true);<br />		System.out.println( "Token Total: " + st.countTokens() );<br />		while( st.hasMoreElements() ){<br />			System.out.println( st.nextToken() );<br />		}<br />结果为：<br />Token Total: 19<br />The<br />=<br />Java<br />=<br />platform<br />=<br />is<br />=<br />the<br />=<br />ideal<br />=<br />platform<br />=<br />for<br />=<br />network<br />=<br />computing<br /></pre>
<img src ="http://www.blogjava.net/iKingQu/aggbug/80352.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-11-10 11:35 <a href="http://www.blogjava.net/iKingQu/articles/80352.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]String类的使用方法</title><link>http://www.blogjava.net/iKingQu/articles/80347.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Fri, 10 Nov 2006 03:29:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/80347.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/80347.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/80347.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/80347.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/80347.html</trackback:ping><description><![CDATA[
		<strong>String：字符串类型<br /></strong>
		<span style="COLOR: brown">此帖参考了maxlyy朋友的帖子，在这里特别感谢。</span>
		<br />
		<span style="COLOR: blue">１、构造函数。</span>
		<br />
		<ul>
				<br />
				<span style="COLOR: green">String()</span> ：构造一个空字符串对象。<br /><span style="COLOR: green">String(byte[] bytes)</span> ：通过byte数组构造字符串对象。<br /><span style="COLOR: green">String(byte[] bytes, int offset, int length)</span> ：通过byte数组，从offset开始，总共length长的字节构造字符串对象。<br /><span style="COLOR: green">String(char[] value)</span> ：通过char数组构造字符串对象。<br /><span style="COLOR: green">String(char[] value, int offset, int count) </span>：通过char数组，从offset开始，总共length长的字节构造字符串对象。<br /><span style="COLOR: green">String(String original)</span> ：构造一个original的副本。既，拷贝一个original。<br /><span style="COLOR: green">String(StringBuffer buffer) </span>：通过StringBuffer数组构造字符串对象；<br /></ul>
		<br />
		<pre>	byte[] b = {'a','b','c','d','e','f','g','h','i','j'};<br />	char[] c = {'0','1','2','3','4','5','6','7','8','9'};<br /><br />	String sb = new String(b);<br />	String sb_sub = new String(b,3,2);<br />	String sc = new String(c);<br />	String sc_sub = new String(c,3,2);<br />	String sb_copy = new String(sb);<br /><br />	System.out.println("sb: " + sb );<br />	System.out.println("sb_sub: " + sb_sub );<br />	System.out.println("sc: " + sc );<br />	System.out.println("sc_sub: " + sc_sub );<br />	System.out.println("sb_copy: " + sb_copy );<br />结果为：<br />sb: abcdefghij<br />sb_sub: de<br />sc: 0123456789<br />sc_sub: 34<br />sb_copy: abcdefghij</pre>
		<br />
		<span style="COLOR: blue">２、方法。</span>
		<br />
		<span style="COLOR: red">说明：<br />1. 所有方法均为public；<br />2. 书写格式：［修饰符］　&lt;返回类型&gt; &lt;方法名（［参数列表］）&gt;</span>
		<span style="COLOR: olive">
				<br />如：<br />static int parseInt(String s) 表示：此方法（parseInt）为类方法（static），返回类型为（int），方法所需参数为String类型。</span>
		<br />
		<br />
		<ul>
				<br />1. <span style="COLOR: green">char charAt(int index)</span> ：取字符串中的某一个字符，其中的参数index指的是字符串中序数。字符串的序数从0开始到length()-1 。</ul>
		<br />
		<pre>	String s = new String("abcdefghijklmnopqrstuvwxyz");<br />	System.out.println("s.charAt(5): " + s.charAt(5) );<br />结果为：s.charAt(5): f</pre>
		<br />
		<ul>2. <span style="COLOR: green">int compareTo(String anotherString)</span> ：当前String对象与anotherString比较。相等关系返回０；不相等时，从两个字符串第0个字符开始比较，返回第一个不相等的字符差，另一种情况，较长字符串的前面部分恰巧是较短的字符串，返回它们的长度差。<br />3. <span style="COLOR: green">int compareTo(Object o)</span> ：如果o是String对象，和2的功能一样；否则抛出ClassCastException异常。</ul>
		<br />
		<pre>	String s1 = new String("abcdefghijklmn");<br />	String s2 = new String("abcdefghij");<br />	String s3 = new String("abcdefghijalmn");<br /><br />	System.out.println("s1.compareTo(s2): " + s1.compareTo(s2) );//返回长度差<br />	System.out.println("s1.compareTo(s3): " + s1.compareTo(s3) );//返回'k'-'a'的差<br />结果为：<br />s1.compareTo(s2): 4<br />s1.compareTo(s3): 10</pre>
		<br />
		<ul>
				<br />4. <span style="COLOR: green">String concat(String str) </span>：将该String对象与str连接在一起。<br />5. <span style="COLOR: green">boolean contentEquals(StringBuffer sb)</span> ：将该String对象与StringBuffer对象sb进行比较。<br />6. <span style="COLOR: green">static String copyValueOf(char[] data) </span>：<br />7. <span style="COLOR: green">static String copyValueOf(char[] data, int offset, int count)</span> ：这两个方法将char数组转换成String，与其中一个构造函数类似。<br />8. <span style="COLOR: green">boolean endsWith(String suffix) </span>：该String对象是否以suffix结尾。</ul>
		<br />
		<pre>	String s1 = new String("abcdefghij");<br />	String s2 = new String("ghij");<br />	System.out.println("s1.endsWith(s2): " + s1.endsWith(s2) );<br />结果为：s1.endsWith(s2): true</pre>
		<br />
		<ul>
				<br />9. <span style="COLOR: green">boolean equals(Object anObject)</span> ：当anObject不为空并且与当前String对象一样，返回true；否则，返回false。<br />10. <span style="COLOR: green">byte[] getBytes()</span> ：将该String对象转换成byte数组。<br />11. <span style="COLOR: green">void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) </span>：该方法将字符串拷贝到字符数组中。其中，srcBegin为拷贝的起始位置、srcEnd为拷贝的结束位置、字符串数值dst为目标字符数组、dstBegin为目标字符数组的拷贝起始位置。</ul>
		<br />
		<pre>	char[] s1 = {'I',' ','l','o','v','e',' ','h','e','r','!'};//s1=I love her!<br />	String s2 = new String("you!");<br />	s2.getChars(0,3,s1,7);	//s1=I love you!<br />	System.out.println( s1 );<br />结果为：I love you!</pre>
		<br />
		<ul>12. <span style="COLOR: green">int hashCode() </span>：返回当前字符的哈希表码。<br />13. <span style="COLOR: green">int indexOf(int ch) </span>：只找第一个匹配字符位置。<br />14. <span style="COLOR: green">int indexOf(int ch, int fromIndex)</span> ：从fromIndex开始找第一个匹配字符位置。<br />15. <span style="COLOR: green">int indexOf(String str)</span> ：只找第一个匹配字符串位置。<br />16. <span style="COLOR: green">int indexOf(String str, int fromIndex) </span>：从fromIndex开始找第一个匹配字符串位置。</ul>
		<br />
		<pre>	String s = new String("write once, run anywhere!");<br />	String ss = new String("run");<br />	System.out.println("s.indexOf('r'): " + s.indexOf('r') );<br />	System.out.println("s.indexOf('r',2): " + s.indexOf('r',2) );<br />	System.out.println("s.indexOf(ss): " + s.indexOf(ss) );<br />结果为：<br />s.indexOf('r'): 1<br />s.indexOf('r',2): 12<br />s.indexOf(ss): 12</pre>
		<br />
		<ul>17. <span style="COLOR: green">int lastIndexOf(int ch) </span><br />18. <span style="COLOR: green">int lastIndexOf(int ch, int fromIndex) </span><br />19. <span style="COLOR: green">int lastIndexOf(String str) </span><br />20. <span style="COLOR: green">int lastIndexOf(String str, int fromIndex) </span>以上四个方法与13、14、15、16类似，不同的是：找最后一个匹配的内容。<br />21. <span style="COLOR: green">int length() </span>：返回当前字符串长度。<br />22. <span style="COLOR: green">String replace(char oldChar, char newChar)</span> ：将字符号串中第一个oldChar替换成newChar。<br />23. <span style="COLOR: green">boolean startsWith(String prefix)</span> ：该String对象是否以prefix开始。<br />24. <span style="COLOR: green">boolean startsWith(String prefix, int toffset)</span> ：该String对象从toffset位置算起，是否以prefix开始。</ul>
		<br />
		<pre>	String s = new String("write once, run anywhere!");<br />	String ss = new String("write");<br />	String sss = new String("once");<br />	System.out.println("s.startsWith(ss): " + s.startsWith(ss) );<br />	System.out.println("s.startsWith(sss,6): " + s.startsWith(sss,6) );<br />结果为：<br />s.startsWith(ss): true<br />s.startsWith(sss,6): true</pre>
		<br />
		<ul>25. <span style="COLOR: green">String substring(int beginIndex)</span> ：取从beginIndex位置开始到结束的子字符串。<br />26.<span style="COLOR: green">String substring(int beginIndex, int endIndex) </span>：取从beginIndex位置开始到endIndex位置的子字符串。<br />27. <span style="COLOR: green">char[] toCharArray() </span>：将该String对象转换成char数组。<br />28. <span style="COLOR: green">String toLowerCase() </span>：将字符串转换成小写。<br />29. <span style="COLOR: green">String toUpperCase()</span> ：将字符串转换成大写。</ul>
		<br />
		<pre>	String s = new String("java.lang.Class String");<br />	System.out.println("s.toUpperCase(): " + s.toUpperCase() );<br />	System.out.println("s.toLowerCase(): " + s.toLowerCase() );<br />结果为：<br />s.toUpperCase(): JAVA.LANG.CLASS STRING<br />s.toLowerCase(): java.lang.class string</pre>
		<br />
		<ul>30. <span style="COLOR: green">static String valueOf(boolean b) </span><br />31. <span style="COLOR: green">static String valueOf(char c) </span><br />32. <span style="COLOR: green">static String valueOf(char[] data) </span><br />33. <span style="COLOR: green">static String valueOf(char[] data, int offset, int count) </span><br />34. <span style="COLOR: green">static String valueOf(double d) </span><br />35. <span style="COLOR: green">static String valueOf(float f) </span><br />36. <span style="COLOR: green">static String valueOf(int i) </span><br />37. <span style="COLOR: green">static String valueOf(long l) </span><br />38. <span style="COLOR: green">static String valueOf(Object obj) </span><br />以上方法用于将各种不同类型转换成Java字符型。这些都是类方法。</ul>
<img src ="http://www.blogjava.net/iKingQu/aggbug/80347.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-11-10 11:29 <a href="http://www.blogjava.net/iKingQu/articles/80347.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]Character类的使用方法</title><link>http://www.blogjava.net/iKingQu/articles/80346.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Fri, 10 Nov 2006 03:28:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/80346.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/80346.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/80346.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/80346.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/80346.html</trackback:ping><description><![CDATA[
		<strong>Character：字符类型<br /><br /></strong>
		<span style="COLOR: blue">１、属性。</span>
		<br />
		<ul>
				<br />
				<span style="COLOR: green">static int MIN_RADIX </span>：返回最小基数。<br /><span style="COLOR: green">static int MAX_RADIX</span> ：返回最大基数。<br /><span style="COLOR: green">static char MAX_VALUE</span> ：字符类型的最大值。<br /><span style="COLOR: green">static char MIN_VALUE</span> ：字符类型的最小值。<br /><span style="COLOR: green">static Class TYPE </span>：返回当前类型。</ul>
		<br />
		<span style="COLOR: blue">２、构造函数。</span>
		<br />
		<ul>
				<br />
				<span style="COLOR: green">Character(char value)</span>：以char参数构造一个Character对象。</ul>
		<br />
		<span style="COLOR: blue">３、方法。</span>
		<br />
		<span style="COLOR: red">说明：<br />1. 所有方法均为public；<br />2. 书写格式：［修饰符］　&lt;返回类型&gt; &lt;方法名（［参数列表］）&gt;</span>
		<span style="COLOR: olive">
				<br />如：<br />static int parseInt(String s) 表示：此方法（parseInt）为类方法（static），返回类型为（int），方法所需参数为String类型。</span>
		<br />
		<ul>
				<br />1. <span style="COLOR: green">char charValue() </span>：返回字符对象的值。<br />2. <span style="COLOR: green">int compareTo(Character anotherCharacter)</span> ：当前Character对象与anotherCharacter比较。相等关系返回０；小于关系返回负数；大于关系返回正数。<br />3. <span style="COLOR: green">int compareTo(Object o) </span>：当前对象与另一个对象进行比较。如果o是Character对象，则与2功能一样；否则，抛出ClassCastException异常。<br />4. <span style="COLOR: green">static int digit(char ch, int radix) </span>：根据基数返回当前字符的值的十进制。如果不满足Character.MIN_RADIX &lt;= radix &lt;= Character.MAX_RADIX，或者，ch不是radix基数中的有效值，返回"-1"；如果ch是“大写”的A到Z之间，则返回ch - 'A' + 10 的值；如果是“小写”a到z之间，返回ch - 'a' + 10 的值。</ul>
		<br />
		<pre>System.out.println("Character.MIN_RADIX: " + Character.MIN_RADIX );<br />System.out.println("Character.MAX_RADIX: " + Character.MAX_RADIX );<br />System.out.println("Character.digit('2',2): " + Character.digit('2',2) );<br />System.out.println("Character.digit('7',10): " + Character.digit('7',10) );<br />System.out.println("Character.digit('F',16): " + Character.digit('F',16) );<br />结果为：<br />Character.MIN_RADIX: 2<br />Character.MAX_RADIX: 36<br />Character.digit('2',2): -1<br />Character.digit('7',10): 7<br />Character.digit('F',16): 15</pre>
		<br />
		<ul>5. <span style="COLOR: green">boolean equals(Object obj) </span>：与obj对象比较。当且仅当obj不为“null”并且和当前Character对象一致时返回“true”。<br />6. <span style="COLOR: green">static char forDigit(int digit, int radix)</span> ：根据特定基数判断当前数值表示的字符。4的逆运算，非法数值时返回“'\u0000'”。</ul>
		<br />
		<pre>System.out.println("Character.MIN_RADIX: " + Character.MIN_RADIX );<br />System.out.println("Character.MAX_RADIX: " + Character.MAX_RADIX );<br />System.out.println("Character.forDigit(2,2): " + Character.forDigit(2,2) );<br />System.out.println("Character.forDigit(7,10): " + Character.forDigit(7,10) );<br />System.out.println("Character.forDigit(15,16): " + Character.forDigit(15,16) );<br />结果为：<br />Character.MIN_RADIX: 2<br />Character.MAX_RADIX: 36<br />Character.forDigit(2,2): <br />Character.forDigit(7,10): 7<br />Character.forDigit(15,16): f<br /></pre>
		<br />
		<ul>
				<br />7. <span style="COLOR: green">static int getNumericValue(char ch) </span>：返回字符ch的数值。<br />8. <span style="COLOR: green">static int getType(char ch)</span> ：返回字符所属类型。具体有哪些种类请查看Java文档资料。<br />9. <span style="COLOR: green">int hashCode()</span> ：返回当前字符的哈希表码。<br />10. <span style="COLOR: green">static boolean isDefined(char ch)</span> ：判断字符ch在Unicode字符集是否用明确定义。<br />11. <span style="COLOR: green">static boolean isDigit(char ch) </span>：判断字符ch是否为数字。<br />12. <span style="COLOR: green">static boolean isIdentifierIgnorable(char ch) </span>：判断字符ch是否为Unicode字符集中可忽略的字符。<br />13. <span style="COLOR: green">static boolean isISOControl(char ch) </span>：判断字符ch是否为ISO标准中的控制字符。<br />14.<span style="COLOR: green">static boolean isJavaIdentifierPart(char ch) </span>：判断字符ch是否为Java中的部分标识符。<br />15. <span style="COLOR: green">static boolean isJavaIdentifierStart(char ch)</span> ：判断字符ch是否为Java中的第一个标识符。<br />16. <span style="COLOR: green">static boolean isLetter(char ch)</span> ：判断字符ch是否为字母。<br />17. <span style="COLOR: green">static boolean isLetterOrDigit(char ch) </span>：判断字符ch是否为字母或数字。<br />18. <span style="COLOR: green">static boolean isLowerCase(char ch) </span>：判断字符ch是否为小写字母。<br />19. <span style="COLOR: green">static boolean isMirrored(char c)</span> ：根据Unicode表判断字符c是否存在与之方向相反的字符。例如：“［”存在与之方向相反的“］”，结果为：true。<br />20. <span style="COLOR: green">static boolean isSpaceChar(char ch)</span> ：判断字符ch是否为Unicode中的空格。<br />21. <span style="COLOR: green">static boolean isUpperCase(char ch)</span> ：判断字符ch是否为大写字母。<br />22. <span style="COLOR: green">static boolean isWhitespace(char ch)</span> ：判断字符ch是否为Java定义中的空字符。<br /><pre>其中包括： <br />	char c1 = '\u0009';//水平列表符<br />	char c2 = '\u000A';//换行<br />	char c3 = '\u000B';//垂直列表符<br />	char c4 = '\u000C';//换页<br />	char c5 = '\u000D';//回车<br />	char c6 = '\u001C';//文件分隔符<br />	char c7 = '\u001D';//组分隔符<br />	char c8 = '\u001E';//记录分隔符<br />	char c9 = '\u001F';//单元分隔符</pre><br />23. <span style="COLOR: green">static char toLowerCase(char ch) </span>：转换ch是否为小写。<br />24. <span style="COLOR: green">String toString()</span> ：将当前Character对象转换成字符串。<br />25. <span style="COLOR: green">static String toString(char c) </span>：此为类方法，将c转换成字符串。<br />26. <span style="COLOR: green">static char toUpperCase(char ch)</span> ：转换ch是否为大写。</ul>
		<br />
		<pre>System.out.println("Character.toUpperCase('q'): " + Character.toUpperCase('q') );<br />System.out.println("Character.toLowerCaseCase('B'): " + Character.toLowerCase('B') );<br />结果为：<br />Character.toUpperCase('q'): Q<br />Character.toLowerCaseCase('B'): b</pre>
<img src ="http://www.blogjava.net/iKingQu/aggbug/80346.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-11-10 11:28 <a href="http://www.blogjava.net/iKingQu/articles/80346.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]Double类的使用方法</title><link>http://www.blogjava.net/iKingQu/articles/80345.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Fri, 10 Nov 2006 03:27:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/80345.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/80345.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/80345.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/80345.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/80345.html</trackback:ping><description><![CDATA[
		<strong>Double：双精度类型<br /><br /></strong>
		<span style="COLOR: blue">１、属性。</span>
		<br />
		<br />
		<ul>
				<br />1. <span style="COLOR: green">static Double MAX_VALUE</span> ： 返回最大双精度数，在不同硬件平台中由Double.longBitsToDouble(0x7fefffffffffffffL)计算得出。<br />2. <span style="COLOR: green">static Double MIN_VALUE</span> ： 返回最小双精度数，在不同硬件平台中由Double.longBitsToDouble(0x1L)计算得出。 <br />3. <span style="COLOR: green">static Double NaN </span>： 表示非数值类型的双精度数，在不同硬件平台中由Double.longBitsToDouble(0x7ff8000000000000L)计算得出。 <br />4. <span style="COLOR: green">static Double NEGATIVE_INFINITY</span>：返回负无穷双精度数，在不同硬件平台中由Double.longBitsToDouble(0xfff0000000000000L)计算得出。<br />5. <span style="COLOR: green">static Double POSITIVE_INFINITY </span>：返回正无穷双精度数，在不同硬件平台中由Double.longBitsToDouble(0x7ff0000000000000L)计算得出。<br />6. <span style="COLOR: green">static Class TYPE</span> ：返回当前类型。</ul>
		<br />
		<span style="COLOR: blue">２、构造函数。</span>
		<br />
		<br />
		<ul>
				<span style="COLOR: green">Double(double value)</span> ：以double类型为参数创建Double对象。<br /><span style="COLOR: green">Double(String s)</span> ：以String类型为参数创建String对象。</ul>
		<br />
		<span style="COLOR: blue">３、方法。</span>
		<br />
		<span style="COLOR: red">说明：<br />1. 所有方法均为public；<br />2. 书写格式：［修饰符］　&lt;返回类型&gt; &lt;方法名（［参数列表］）&gt;</span>
		<span style="COLOR: olive">
				<br />如：<br />static int parseInt(String s) 表示：此方法（parseInt）为类方法（static），返回类型为（int），方法所需参数为String类型。</span>
		<br />
		<br />
		<ul>
				<br />1. <span style="COLOR: green">byte byteValue()</span> ：返回以字节表示的双精度数。<br />2. <span style="COLOR: green">static int compare(double d1, double d2) </span>：此为类方法，比较d1和d2。相当于new Double(d1).compareTo(new Double(d2))。如果d1与d2相等，返回０；小于关系，返回负数；大于关系，返回正数。<br />3. <span style="COLOR: green">int compareTo(Double anotherDouble)</span> ：此为对象方法，当前对象与anotherDouble比较。与2的比较规则相同。<br />4. <span style="COLOR: green">int compareTo(Object o)</span> ：当前对象与o进行比较，如果o属于Double类，那么，相当于3；如果是其他类，则抛出ClassCastException异常。<br />5. <span style="COLOR: green">static long doubleToLongBits(double value) </span>：把value按照IEEE 754转化成long并输出它的十进制数值。<br />6. <span style="COLOR: green">double doubleValue() </span>：返回该双精度数对象的双精度数值。<br />7. <span style="COLOR: green">boolean equals(Object obj) </span>：比较当前Double对象与obj的内容是否相同。大多数情况是比较两个Double对象的值是否相等，相当于d1.doubleValue() == d2.doubleValue()的值。<br />8. <span style="COLOR: green">float floatValue()</span> ：返回该浮点数对象的浮点数值。<br />9. <span style="COLOR: green">int hashCode() </span>：返回该Double对象的哈希表码。<br />10. <span style="COLOR: green">int intValue()</span> ：返回该Double对象的整数值（整数部分）。<br />11. <span style="COLOR: green">boolean isInfinite()</span> ：判断该Double对象是否是无穷。<br />12. <span style="COLOR: green">static boolean isInfinite(double v) </span>：与11类似，不同的是：此为类方法，判断的是v。<br />13. <span style="COLOR: green">boolean isNaN()</span> ：判断该Double对象是否为非数值。<br />14. <span style="COLOR: green">static boolean isNaN(double v) </span>：功能与13一样，只不过判断v。<br />15. <span style="COLOR: green">long longValue()</span> ：返回该Double对象的长整数值。<br />16. <span style="COLOR: green">static float parseFloat(String s) </span>：将字符串转换成双精度数。<br />17. <span style="COLOR: green">short shortValue()</span> ：返回该Double对象的短整数值。<br />18. <span style="COLOR: green">String toString()</span> ：将该Double对象转换成字符串。<br />19. <span style="COLOR: green">static String toString(Double f)</span> ：功能与18一样，只是转换f。<br />20. <span style="COLOR: green">static Double valueOf(String s)</span> ：将字符串转换成双精度数。</ul>
		<br />
		<span style="COLOR: olive">例子：</span>与Float类的相似。<br /><img src ="http://www.blogjava.net/iKingQu/aggbug/80345.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-11-10 11:27 <a href="http://www.blogjava.net/iKingQu/articles/80345.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]Float类的使用方法</title><link>http://www.blogjava.net/iKingQu/articles/80344.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Fri, 10 Nov 2006 03:26:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/80344.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/80344.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/80344.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/80344.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/80344.html</trackback:ping><description><![CDATA[
		<strong>Float：实数类型<br /><br /></strong>
		<span style="COLOR: blue">１、属性。</span>
		<br />
		<ul>
				<br />1. <span style="COLOR: green">static float MAX_VALUE </span>： 返回最大浮点数，在不同硬件平台中由Float.intBitsToFloat(0x7f7fffff)计算得出。<br />2. <span style="COLOR: green">static float MIN_VALUE</span> ： 返回最小浮点数，在不同硬件平台中由Float.intBitsToFloat(0x1)计算得出。 <br />3. <span style="COLOR: green">static float NaN </span>： 表示非数值类型的浮点数，在不同硬件平台中由Float.intBitsToFloat(0x7fc00000)计算得出。 <br />4. <span style="COLOR: green">static float NEGATIVE_INFINITY</span>：返回负无穷浮点数，在不同硬件平台中由Float.intBitsToFloat(0xff800000)计算得出。<br />5. <span style="COLOR: green">static float POSITIVE_INFINITY </span>：返回正无穷浮点数，在不同硬件平台中由Float.intBitsToFloat(0x7f800000)计算得出。<br />6. <span style="COLOR: green">static Class TYPE</span> ：返回当前类型。</ul>
		<br />
		<br />
		<span style="COLOR: blue">２、构造函数。</span>
		<br />
		<ul>
				<br />
				<span style="COLOR: green">Float(double value) </span>：以double类型为参数构造Float对象。<br /><span style="COLOR: green">Float(float value) </span>：以Float类型为参数构造Float对象。<br /><span style="COLOR: green">Float(String s)</span> ：以String类型为参数构造Float对象。</ul>
		<br />
		<br />
		<span style="COLOR: blue">３、方法。</span>
		<br />
		<span style="COLOR: red">说明：<br />1. 所有方法均为public；<br />2. 书写格式：［修饰符］　&lt;返回类型&gt; &lt;方法名（［参数列表］）&gt;</span>
		<span style="COLOR: olive">
				<br />如：<br />static int parseInt(String s) 表示：此方法（parseInt）为类方法（static），返回类型为（int），方法所需参数为String类型。</span>
		<br />
		<br />
		<ul>
				<br />1. <span style="COLOR: green">byte byteValue() </span>：返回以字节表示的浮点数。<br />2. <span style="COLOR: green">static int compare(float f1, float f2)</span> ：此为类方法，比较f1和f2。相当于new Float(f1).compareTo(new Float(f2))。如果f1与f2相等，返回０；小于关系，返回负数；大于关系，返回正数。<br />3. <span style="COLOR: green">int compareTo(Float anotherFloat) </span>：此为对象方法，当前对象与anotherFloat比较。与2的比较规则相同。<br />4. <span style="COLOR: green">int compareTo(Object o)</span> ：当前对象与o进行比较，如果o属于Float类，那么，相当于3；如果是其他类，则抛出ClassCastException异常。<br />5. <span style="COLOR: green">double doubleValue()</span> ：返回浮点数的双精度值。<br />6. <span style="COLOR: green">boolean equals(Object obj)</span> ：比较当前Float对象与obj的内容是否相同。大多数情况是比较两个Float对象的值是否相等，相当于f1.floatValue() == f2.floatValue()的值。与2、3、4不同的是：6返回boolean型。<br />7. <span style="COLOR: green">static int floatToIntBits(float value)</span>：按照IEEE 754转化成float并输出它的十进制数值。<br />8. <span style="COLOR: green">float floatValue()</span> ：返回该浮点数对象的浮点数值。<br />9. <span style="COLOR: green">int hashCode()</span> ：返回该Float对象的哈希表码。<br />10. <span style="COLOR: green">int intValue() </span>：返回该Float对象的整数值（整数部分）。<br />11. <span style="COLOR: green">boolean isInfinite()</span> ：判断该Float对象是否是无穷。<br />12. st<span style="COLOR: green">atic boolean isInfinite(float v)</span> ：与11类似，不同的是：此为类方法，判断的是v。<br />13. <span style="COLOR: green">boolean isNaN()</span> ：判断该Float对象是否为非数值。<br />14. <span style="COLOR: green">static boolean isNaN(float v) </span>：功能与13一样，只不过判断v。<br />15. <span style="COLOR: green">long longValue() </span>：返回该Float对象的长整数值。<br />16. <span style="COLOR: green">static float parseFloat(String s) </span>：将字符串转换成浮点数。<br />17. <span style="COLOR: green">short shortValue() </span>：返回该Float对象的短整数值。<br />18. <span style="COLOR: green">String toString()</span> ：将该Float对象转换成字符串。<br />19. <span style="COLOR: green">static String toString(float f) </span>：功能与18一样，只是转换f。<br />20. <span style="COLOR: green">static Float valueOf(String s)</span> ：将字符串转换成浮点数。</ul>
		<br />
		<br />
		<span style="COLOR: olive">例子：</span>
		<br />
		<pre>Float f = new Float(1237.45);<br />Float fs = new Float("123.45");<br />Float fd = new Float(1234146865679824657987947924623724749.16416925);<br /><br />System.out.println("f.compare(fs): " + f.compareTo(fs) );<br />System.out.println("f.compareTo(fd): " + f.compareTo(fd) );<br />System.out.println("Float.compare(1.23f,3.25f): " + Float.compare(1.23f,3.25f) );<br />结果为：<br />f.compare(fs): 1<br />f.compareTo(fd): -1<br />Float.compare(1.23f,3.25f): -1</pre>
		<br />
		<br />
		<pre>Float f = new Float(1237.45);<br />System.out.println("f.equals(fs): " + f.equals(fs) );<br />结果为：f.equals(fs): false</pre>
<img src ="http://www.blogjava.net/iKingQu/aggbug/80344.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-11-10 11:26 <a href="http://www.blogjava.net/iKingQu/articles/80344.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]Integer类的使用方法 </title><link>http://www.blogjava.net/iKingQu/articles/80342.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Fri, 10 Nov 2006 03:25:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/80342.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/80342.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/80342.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/80342.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/80342.html</trackback:ping><description><![CDATA[
		<strong>Interger：整数类型<br /><br /></strong>
		<span style="COLOR: blue">１、属性。</span>
		<br />
		<ul>
				<br />
				<span style="COLOR: green">static int MAX_VALUE</span>：返回最大的整型数；<br /><span style="COLOR: green">static int MIN_VALUE</span>：返回最小的整型数；<br /><span style="COLOR: green">static Class TYPE </span>：返回当前类型。</ul>
		<br />
		<span style="COLOR: olive">例子：</span>
		<br />
		<pre>System.out.println("Integer.MAX_VALUE: " + Integer.MAX_VALUE );<br />结果为：Integer.MAX_VALUE: 2147483647<br /></pre>
		<br />
		<br />
		<span style="COLOR: blue">２、构造函数。</span>
		<br />
		<ul>
				<br />
				<span style="COLOR: green">Integer(int value)</span> ：通过一个int的类型构造对象；<br /><span style="COLOR: green">Integer(String s)</span> ：通过一个String的类型构造对象；</ul>
		<br />
		<span style="COLOR: olive">例子：</span>
		<br />
		<pre>Integer i = new Integer("1234");<br />生成了一个值为1234的Integer对象。<br /></pre>
		<br />
		<br />
		<span style="COLOR: blue">３、方法。</span>
		<br />
		<span style="COLOR: red">说明：<br />1. 所有方法均为public；<br />2. 书写格式：［修饰符］　&lt;返回类型&gt; &lt;方法名（［参数列表］）&gt;</span>
		<span style="COLOR: olive">
				<br />如：<br />static int parseInt(String s) 表示：此方法（parseInt）为类方法（static），返回类型为（int），方法所需参数为String类型。</span>
		<br />
		<br />
		<ul>
				<br />1. <span style="COLOR: green">byteValue()：</span>取得用byte类型表示的整数；<br />2. <span style="COLOR: green">int compareTo(Integer anotherInteger) </span>：比较两个整数。相等时返回０；小于时返回负数；大于时返回正数。</ul>
		<br />
		<span style="COLOR: olive">例子：</span>
		<br />
		<pre>
				<br />Integer i = new Integer(1234);<br />System.out.println("i.compareTo: " + i.compareTo(new Integer(123)) );<br />结果为：i.compareTo: 1<br /></pre>
		<br />
		<ul>
				<br />3. <span style="COLOR: green">int compareTo(Object o) </span>：将该整数与其他类进行比较。如果o也为Integer类，进行方法2 的操作；否则，抛出ClassCastException异常。<br />4. <span style="COLOR: green">static Integer decode(String nm)</span> ：将字符串转换为整数。<br />5. <span style="COLOR: green">double doubleValue()</span> ：取得该整数的双精度表示。<br />6. <span style="COLOR: green">boolean equals(Object obj) </span>：比较两个对象。<br />7. <span style="COLOR: green">float floatValue() </span>：取得该整数的浮点数表示。<br />8. <span style="COLOR: green">static Integer getInteger(String nm) </span>：根据指定名确定系统特征值。<br />9. <span style="COLOR: green">static Integer getInteger(String nm, int val)</span> ：上面的重载。<br />10. <span style="COLOR: green">static Integer getInteger(String nm, Integer val) </span>：上面的重载。<br />11. <span style="COLOR: green">int hashCode() </span>：返回该整数类型的哈希表码。<br />12. <span style="COLOR: green">int intValue()</span> ： 返回该整型数所表示的整数。<br />13. <span style="COLOR: green">long longValue() </span>：返回该整型数所表示的长整数。<br />14. <span style="COLOR: green">static int parseInt(String s)</span> ：将字符串转换成整数。s必须是时进制数组成，否则抛出NumberFormatException异常。<br />15. <span style="COLOR: green">static int parseInt(String s, int radix)</span> ：以radix为基数radix返回s的十进制数。<span style="COLOR: red">所谓的基数，就是“几进制”。</span></ul>
		<br />
		<span style="COLOR: olive">例子：</span>
		<br />
		<pre>
				<br />String s1 = new String("1010");<br />System.out.println("Integer.parseInt(String s, int radix): " + Integer.parseInt(s1,2) );<br />结果为：Integer.parseInt(String s, int radix): 10<br /></pre>
		<br />
		<ul>
				<br />16. <span style="COLOR: green">short shortValue() </span>：返回该整型数所表示的短整数。<br />17. <span style="COLOR: green">static String toBinaryString(int i) </span>：将整数转为二进制数的字符串。<br />18. <span style="COLOR: green">static String toHexString(int i)</span> ：将整数转为十六进制数的字符串。<br />19. <span style="COLOR: green">static String toOctalString(int i) </span>：将整数转为八进制数的字符串。<br />20. <span style="COLOR: green">String toString()</span> ：将该整数类型转换为字符串。<br />21. <span style="COLOR: green">static String toString(int i) </span>：将该整数类型转换为字符串。不同的是，此为类方法。<br />22. <span style="COLOR: green">static String toString(int i, int radix) </span>：将整数i以基数radix的形式转换成字符串。</ul>
		<br />
		<span style="COLOR: olive">例子：</span>
		<br />
		<pre>int i1 = 54321;<br />System.out.println("Integer.toString(int i, int radix): " + Integer.toString(i1,16) );<br />结果为：Integer.toString(int i, int radix): d431</pre>
		<br />
		<ul>
				<br />
				<span style="COLOR: green">23. static Integer valueOf(String s)</span> ：将字符串转换成整数类型。<br /><span style="COLOR: green">24. static Integer valueOf(String s, int radix) </span>：将字符串以基数radix的要求转换成整数类型。</ul>
<img src ="http://www.blogjava.net/iKingQu/aggbug/80342.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-11-10 11:25 <a href="http://www.blogjava.net/iKingQu/articles/80342.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]JAVA 正则表达式实现</title><link>http://www.blogjava.net/iKingQu/articles/75783.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Tue, 17 Oct 2006 18:22:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/75783.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/75783.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/75783.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/75783.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/75783.html</trackback:ping><description><![CDATA[§1黑暗岁月<br />       有一个String，如何查询其中是否有y和f字符？最黑暗的办法就是：<br />程序1：我知道if、for语句和charAt()啊。<br />class Test{<br />  public static void main(String args[]) {<br />         String str="For my money, the important thing "+<br />         "about the meeting was bridge-building";<br />         char x='y';<br />         char y='f';<br />         boolean result=false;<br />         for(int i=0;i&lt;str.length();i++){<br />                char z=str.charAt(i);  //System.out.println(z);<br />                if(x==z||y==z) {<br />                       result=true;<br />                       break;<br />                }<br />                else result=false;<br />         }   <br />         System.out.println(result);<br />       }<br />}<br />       好像很直观，但这种方式难以应付复杂的工作。如查询一段文字中，是否有is？是否有thing或ting等。这是一个讨厌的工作。<br />§2 Java的java.util.regex包<br />       按照面向对象的思路，把希望查询的字符串如is、thing或ting封装成一个对象，以这个对象作为模板去匹配一段文字，就更加自然了。作为模板的那个东西就是下面要讨论的正则表达式。先不考虑那么复杂，看一个例子：<br />程序2：不懂。先看看可以吧？<br />import java.util.regex.*;<br />class Regex1{<br />  public static void main(String args[]) {<br />         String str="For my money, the important thing "+<br />         "about the meeting was bridge-building";<br />         String regEx="a|f";   //表示a或f <br />         Pattern p=Pattern.compile(regEx);<br />         Matcher m=p.matcher(str);<br />         boolean result=m.find();<br />         System.out.println(result);<br />       }<br />}<br />       如果str匹配regEx，那么result为true，否则为flase。如果想在查找时忽略大小写，则可以写成：<br />Pattern p=Pattern.compile(regEx,Pattern.CASE_INSENSITIVE);<br />       虽然暂时不知道Pattern（模板、模式）和Matcher（匹配器）的细节，程序的感觉就比较爽，如果先查询is、后来又要查询thing或ting，我们只需要修改一下模板Pattern，而不是考虑if语句和for语句，或者通过charAt()。<br />1、写一个特殊的字符串??正则表达式如a|f。<br />2、将正则表达式编译成一个模板：p<br />3、用模板p去匹配字符串str。<br />       思路清楚了，现在看Java是如何处理的（Java程序员直到JDK1.4才能使用这些类。<br />§3 Pattern类与查找<br />       ①public final class java.util.regex.Pattern是正则表达式编译后的表达法。下面的语句将创建一个Pattern对象并赋值给句柄p：Pattern p=Pattern.compile(regEx);<br />       有趣的是，Pattern类是final类，而且它的构造器是private。也许有人告诉你一些设计模式的东西，或者你自己查有关资料。这里的结论是：Pattern类不能被继承，我们不能通过new创建Pattern类的对象。<br />       因此在Pattern类中，提供了2个重载的静态方法，其返回值是Pattern对象（的引用）。如：<br />    public static Pattern compile(String regex) {<br />        return new Pattern(regex, 0);<br />    }<br />       当然，我们可以声明Pattern类的句柄，如Pattern p=null；<br />       ②p.matcher(str)表示以用模板p去生成一个字符串str的匹配器，它的返回值是一个Matcher类的引用，为什么要这个东西呢？按照自然的想法，返回一个boolean值不行吗？<br />       我们可以简单的使用如下方法：<br />       boolean result=Pattern.compile(regEx).matcher(str).find();<br />       呵呵，其实是三个语句合并的无句柄方式。无句柄常常不是好方式。后面再学习Matcher类吧。先看看regEx??这个怪咚咚。<br />§4 正则表达式之限定符<br />       正则表达式（Regular Expression）是一种生成字符串的字符串。晕吧。比如说，String regEx="me+";这里字符串me+能够生成的字符串是：me、mee、meee、meeeeeeeeee等等，一个正则表达式可能生成无穷的字符串，所以我们不可能（有必要吗？）输出正则表达式产生的所有东西。<br />反过来考虑，对于字符串：me、mee、meee、meeeeeeeeee等等，我们能否有一种语言去描述它们呢？显然，正则表达式语言是这种语言，它是一些字符串的模式??简洁而深刻的描述。<br />我们使用正则表达式，用于字符串查找、匹配、指定字符串替换、字符串分割等等目的。<br /> <br />       生成字符串的字符串??正则表达式，真有些复杂，因为我们希望由普通字符（例如字符 a 到 z）以及特殊字符（称为元字符）描述任意的字符串，而且要准确。<br />       先搞几个正则表达式例子：<br />       程序3：我们总用这个程序测试正则表达式。<br />       import java.util.regex.*;<br />class Regex1{<br />  public static void main(String args[]) {<br />         String str="For my money, the important thing "；<br />         String regEx="ab*"; <br />         boolean result=Pattern.compile(regEx).matcher(str).find();<br />         System.out.println(result);<br />       }<br />}//ture<br />①"ab*"??能匹配a、ab、abb、abbb……。所以，*表示前面字符可以有零次或多次。如果仅仅考虑查找，直接用"a"也一样。但想想替换的情况。 问题regEx="abb*"结果如何？<br />②"ab+"??能匹配ab、abb、abbb……。等价于"abb*"。问题regEx="or+"结果如何？<br />③"or?"??能匹配o和or。? 表示前面字符可以有零次或一次。<br />       这些限定符*、+、?方便地表示了其前面字符(子串)出现的次数（我们用{}来描述）：<br />x*    零次或多次 ≡{0,}<br />x+    一次或多次 ≡{1,}<br />x?    零次或一次 ≡{0,1}<br />x{n}    n次（n&gt;0）<br />x{n,m}    最少n次至最多m次（0&lt;n&lt;m）<br />x{n,}    最少n次,<br />       <br />现在我们知道了连续字符串的查找、匹配。下面的是一些练习题：<br />①查找粗体字符串（不要求精确或要求精确匹配），写出其正则表达式：<br />str    regEX(不要求精确)    regEX(要求精确)    试一试<br />abcffd    b或bcff或bcf*或bc*或bc+    bcff或bcf{2}    bc{3}<br />gooooogle    o{1,}、o+    o{5}     <br />banana    (an)+    (an){2}a、a(na) {2}     <br />                <br />                <br />                <br />②正则表达式匹配字符串，输出是什么？<br />§5替换（删除）、Matcher类<br />现在我们可能厌烦了true/false，我们看看替换。如把book，google替换成bak（这个文件后缀名，在EditPlus中还行）、look或goooogle。<br />       程序4：字符串的替换。<br />       import java.util.regex.*;<br />class Regex1{<br />       public static void main(String args[]) {<br />              String regEx="a+";//表示一个或多个a<br />              String str="abbbaaa an banana hhaana";<br />              Pattern p=Pattern.compile(regEx);<br />              Matcher m=p.matcher(str);<br />              String s=m.replaceAll("⊙⊙"); // ("") 删除<br />              System.out.println(s);<br />       }<br />}        <br />       这个程序与前面的程序的区别，在于使用了m.replaceAll(String)方法。看来Matcher类还有点用处。<br />①    public final class Matcher是一个匹配器。可以把他看成一个人，一手拿着模子（Pattern类的对象），一手拿着一个字符序列（CharSequence），通过解释该模子而对字符序列进行匹配操作（match operations）。常常我们这样编程：“喂，模子p，你和字符串str一起创建一个匹配器对象”。即Matcher m=p.matcher(str);<br />②    m可以进行一些操作，如public String replaceAll(String replacement)，它以replacement替换所有匹配的字符串。<br />§6正则表达式之特殊字符<br />我们熟悉这样一个字符串"\n" 如：System.out.print(s+"\nbbb");这是Java中常用的转移字符之一。其实转移字符就是一种正则表达式，它使用了特殊字符 \ 。<br /> <br />下面是正则表达式中常用的特殊字符：<br />匹配次数符号    *    +    ？    {n}、{n,}、{n,m}<br />“或”符号    |     程序2已经使用过了<br />句点符号    .     句点符号匹配所有字符（一个），包括空格、Tab字符甚至换行符。<br />方括号    [ ]   仅仅匹配方括号其中的字符)<br />圆括号    ()    分组，圆括号中的字符视为一个整体。<br />连字符    -     表示一个范围。 <br />“否”符号    ^    表示不希望被匹配的字符（排除）<br />我们一下子学不了太多的东西，这不是正则表达式的全部内容和用法。但已经够我们忙活的了。我们用程序4 验证。(⊙⊙表示替换的字符)<br />①    regEx为下列字符串时，能够表示什么？<br />regEx    匹配    测试用str<br />(a|b){2}    aa、ab、bb、ba    aabbfooaabfooabfoob<br />a[abc]b    aab、abb、acb    3dfacb5ooyfo6abbfooaab<br />.     all string    3dfac<br />a.     aa、ax……等等    3dfacgg<br />d[^j]a    daa、d9a等等，除dja    3dfacggdjad5a<br />[d-g][ac]c    dac、ecc、gac等    3dfacggggccad5c<br />[d-g].{2}c    d⊙⊙c……    3dfacggggccad5c<br />g{1,10}    g、ggg……    3dfacggggccad5c<br />[a|c][^a]         3dfacggggccad5c<br /> <br />②    下列字符串如何用regEx表示？<br />测试用str    匹配    regEx<br />aabbfoaoabfooafobob     a⊙⊙b    a..b<br />aabbfoaaobfooafbob    a⊙b、除aab    a[^a]b、<br />gooooooogle    oooo……变成oo    o{2,20}<br />一本书中的“tan”、“ten”、“tin”和“ton”    t.n、t[aeio]n<br />abcaccbcbaacabccaa    删除ac、ca    (ca)|(ac)<br />abccbcbaabca    再删除ab、ba    结果ccbcca（如何与上面的合并）<br />           <br />           <br />           <br />注：<br />1、String str="一本书中的tan、ten、tin和ton"; <br />输出：     一本书中的⊙⊙、⊙⊙、⊙⊙和⊙⊙<br />2、String str=" abcaccbcbaacabccaa "; 输出：ccbcca<br />       程序5：if、for语句和charAt()，886。<br />import java.util.regex.*;<br />class Regex1{<br />    public static void main(String args[]) {<br />           String str="abcaccbcbaacabccaa";<br />           String regEx="(ac)|(ca)";<br />           Pattern p=Pattern.compile(regEx);<br />           Matcher m=p.matcher(str);<br />           String s=m.replaceAll("");//⊙⊙<br />           regEx="(ab)|(ba)";<br />           p=Pattern.compile(regEx);<br />           s=p.matcher(s).replaceAll("");<br /> <br />           System.out.print(s+"\n");<br />    }<br />}<br /> <br />§7 开始<br />好像我们知道了一些正则表达式与 Java的知识，事实上，我们才刚刚开始。这里列出我们知道的东西，也说一点我们不知道的东西。<br />①              Java在JDK1.4引入了（java.util.regex包）以支持正则表达式，包中有两个类，分别是Pattern和Matcher。它们都有很多的方法，我们还不知道。String类中的split、matches方法等等也使用到了正则表达式。StringTokenizer是否没有用处了？<br />②             正则表达式是一门语言。有许多正则表达式语法、选项和特殊字符，在Pattern.java源文件中大家可以查看。可能比想象中的要复杂。系统学习正则表达式的历史、语法、全部特殊字符（相当于Java中的关键字的地位），组合逻辑是下一步的事情。<br />③             正则表达式是文本处理的重要技术，在Perl、PHP、Python、JavaScript、Java、C＃中被广泛支持。被列为“保证你现在和未来不失业的十种关键技术”，呵呵，信不信由你<br /><img src ="http://www.blogjava.net/iKingQu/aggbug/75783.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-10-18 02:22 <a href="http://www.blogjava.net/iKingQu/articles/75783.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]在JAVA中使用正则表达式</title><link>http://www.blogjava.net/iKingQu/articles/75782.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Tue, 17 Oct 2006 18:20:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/75782.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/75782.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/75782.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/75782.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/75782.html</trackback:ping><description><![CDATA[jdk1.4中加入了java.util.regex包提供对正则表达式的支持。而且Java.lang.String类中的replaceAll和split函数也是调用的正则表达式来实现的。<br /><br /><script id="ad_text_pcjob" src="/script/ad_text_pcjob.js" defer=""></script>
　正则表达式对字符串的操作主要包括：字符串匹配，指定字符串替换，指定字符串查找和字符串分割。下面就用一个例子来说明这些操作是如何实现的：<br /><br />　　&lt; %@ page import="java.util.regex.*"%&gt;<br /><br />　　&lt; %<br /><br />　　Pattern p=null; //正则表达式<br /><br />　　Matcher m=null; //操作的字符串<br /><br />　　boolean b;<br /><br />　　String s=null;<br /><br />　　StringBuffer sb=null;<br /><br />　　int i=0;<br /><br />　　//字符串匹配，这是不符合的<br /><br />　　p = Pattern.compile("a*b");<br /><br />　　m = p.matcher("baaaaab");<br /><br />　　b = m.matches();<br /><br />　　out.println(b+"&lt; br&gt;");<br /><br />　　//字符串匹配，这是符合的 <br /><br clear="all" />　　p = Pattern.compile("a*b");<br /><br />　　m = p.matcher("aaaaab");<br /><br />　　b = m.matches();<br /><br />　　out.println(b+"&lt; br&gt;");<br /><br />　　//字符串替换<br /><br />　　p = Pattern.compile("ab");<br /><br />　　m = p.matcher("aaaaab");<br /><br />　　s = m.replaceAll("d"); <br /><br />　　out.println(s+"&lt; br&gt;");<br /><br />　　p = Pattern.compile("a*b");<br /><br />　　m = p.matcher("aaaaab");<br /><br />　　s = m.replaceAll("d"); <br /><br />　　out.println(s+"&lt; br&gt;");<br /><br />　　p = Pattern.compile("a*b"); <br /><br clear="all" />　　m = p.matcher("caaaaab");<br /><br />　　s = m.replaceAll("d"); <br /><br />　　out.println(s+"&lt; br&gt;");<br /><br />　　//字符串查找<br /><br />　　p = Pattern.compile("cat");<br /><br />　　m = p.matcher("one cat two cats in the yard");<br /><br />　　sb = new StringBuffer();<br /><br />　　while (m.find()) {<br /><br />m.appendReplacement(sb, "dog");<br /><br />i++;<br /><br />　　}<br /><br />　　m.appendTail(sb);<br /><br />　　out.println(sb.toString()+"&lt; br&gt;");<br /><br />　　out.println(i+"&lt; br&gt;");<br /><br />　　i=0; <br clear="all" /><br />　　p = Pattern.compile("cat");<br /><br />　　m = p.matcher("one cat two ca tsi nthe yard");<br /><br />　　sb = new StringBuffer();<br /><br />　　while (m.find()) {<br /><br />m.appendReplacement(sb, "dog");<br /><br />i++;<br /><br />　　}<br /><br />　　m.appendTail(sb);<br /><br />　　 out.println(sb.toString()+"&lt; br&gt;");<br /><br />　　out.println(i+"&lt; br&gt;");<br /><br /><br /><br /><br /><br />　　p = Pattern.compile("cat");<br /><br />　　m = p.matcher("one cat two cats in the yard");<br /><br />　　p=m.pattern(); <br clear="all" /><br />　　m = p.matcher("bacatab");<br /><br />　　b = m.matches();<br /><br />　　out.println(b+"&lt; br&gt;"); <br /><br />　　s = m.replaceAll("dog"); <br /><br />　　out.println(s+"&lt; br&gt;"); <br /><br /><br /><br />　　 i=0;<br /><br />　　p = Pattern.compile("(fds){2,}");<br /><br />　　 m = p.matcher("dsa da fdsfds aaafdsafds aaf");<br /><br />　　 sb = new StringBuffer();<br /><br />　　while (m.find()) {<br /><br />m.appendReplacement(sb, "dog");<br /><br />i++;<br /><br />　　}<br /><br />　　m.appendTail(sb);<br /><br />　　out.println(sb.toString()+"&lt; br&gt;"); <br clear="all" /><br />　　out.println(i+"&lt; br&gt;");<br /><br /><br /><br />　　 p = Pattern.compile("cat");<br /><br />　　 m = p.matcher("one cat two cats in the yard");<br /><br />　　 sb = new StringBuffer();<br /><br />　　while (m.find()) {<br /><br />m.appendReplacement(sb, "<font color="#00ed00">cat</font>");<br /><br />　　 }<br /><br />　　m.appendTail(sb);<br /><br />　　out.println(sb.toString()+"&lt; br&gt;");<br /><br />　　String aa=sb.toString();<br /><br />　　out.println(aa+"&lt; br&gt;");<br /><br />　　//字符串分割<br /><br />　　 p = Pattern.compile("a+");<br /><br />　　 String[] a=p.split("caaaaaat");<br /><br />　　 for(i=0;i<br />　　 {<br /><br />　　 out.println(a[i]+"&lt; br&gt;");<br /><br />　　 }<br /><br />　　 p = Pattern.compile("a+");<br /><br />　　 a=p.split("c aa aaaa t",0);<br /><br />　　 for(i=0;i<a.length;i++)><br /><br />　　 {<br /><br />　　 out.println(a[i]+"&lt; br&gt;");<br /><br />　　 }<br /><br />　　 p = Pattern.compile(" +");<br /><br />　　 a=p.split("c aa aaaa t",0);<br /><br />　　 for(i=0;i<a.length;i++)><br /><br />　　 {<br /><br />　　 out.println(a[i]+"&lt; br&gt;");<br /><br />　　}<br /><br />　　p = Pattern.compile("\\+");<br /><br />　　 a=p.split("dsafasdfdsafsda+dsagfasdfa+sdafds");<br /><br />　　out.println(a.length+"&lt; br&gt;");<br /><br />　　for(i=0;i<a.length;i++)><br /><br />　　{<br /><br />　　out.println(a[i]+"&lt; br&gt;");<br /><br />　　}<br /><br />　　%&gt;（www.csdn.net） <br clear="all" /><a.length;i++)><br clear="all" /></a.length;i++)></a.length;i++)></a.length;i++)></a.length;i++)><img src ="http://www.blogjava.net/iKingQu/aggbug/75782.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-10-18 02:20 <a href="http://www.blogjava.net/iKingQu/articles/75782.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]Java正则表达式详解</title><link>http://www.blogjava.net/iKingQu/articles/75781.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Tue, 17 Oct 2006 18:14:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/75781.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/75781.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/75781.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/75781.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/75781.html</trackback:ping><description><![CDATA[
		<p>
		</p>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">如果你曾经用过Perl或任何其他内建正则表达式支持的语言，你一定知道用正则表达式处理文本和匹配模式是多么简单。如果你不熟悉这个术语，那么“正则表达式”（Regular Expression）就是一个字符构成的串，它定义了一个用来搜索匹配字符串的模式。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">许多语言，包括Perl、PHP、Python、JavaScript和JScript，都支持用正则表达式处理文本，一些文本编辑器用正则表达式实现高级“搜索-替换”功能。那么Java又怎样呢？本文写作时，一个包含了用正则表达式进行文本处理的Java规范需求（Specification Request）已经得到认可，你可以期待在JDK的下一版本中看到它。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">然而，如果现在就需要使用正则表达式，又该怎么办呢？你可以从Apache.org下载源代码开放的Jakarta-ORO库。本文接下来的内容先简要地介绍正则表达式的入门知识，然后以Jakarta-ORO API为例介绍如何使用正则表达式。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<b>
												<font size="4">一、正则表达式基础知识</font>
										</b>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">我们先从简单的开始。假设你要搜索一个包含字符“cat”的字符串，搜索用的正则表达式就是“cat”。如果搜索对大小写不敏感，单词“catalog”、“Catherine”、“sophisticated”都可以匹配。也就是说： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_a.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<b>1.1 句点符号</b>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">假设你在玩英文拼字游戏，想要找出三个字母的单词，而且这些单词必须以“t”字母开头，以“n”字母结束。另外，假设有一本英文字典，你可以用正则表达式搜索它的全部内容。要构造出这个正则表达式，你可以使用一个通配符——句点符号“.”。这样，完整的表达式就是“t.n”，它匹配“tan”、“ten”、“tin”和“ton”，还匹配“t#n”、“tpn”甚至“t n”，还有其他许多无意义的组合。这是因为句点符号匹配所有字符，包括空格、Tab字符甚至换行符： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_b.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<b>1.2 方括号符号</b>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">为了解决句点符号匹配范围过于广泛这一问题，你可以在方括号（“[]”）里面指定看来有意义的字符。此时，只有方括号里面指定的字符才参与匹配。也就是说，正则表达式“t[aeio]n”只匹配“tan”、“Ten”、“tin”和“ton”。但“Toon”不匹配，因为在方括号之内你只能匹配单个字符： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_c.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<b>1.3 “或”符号</b>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">如果除了上面匹配的所有单词之外，你还想要匹配“toon”，那么，你可以使用“|”操作符。“|”操作符的基本意义就是“或”运算。要匹配“toon”，使用“t(a|e|i|o|oo)n”正则表达式。这里不能使用方扩号，因为方括号只允许匹配单个字符；这里必须使用圆括号“()”。圆括号还可以用来分组，具体请参见后面介绍。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_d.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<b>1.4 表示匹配次数的符号</b>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">表一显示了表示匹配次数的符号，这些符号用来确定紧靠该符号左边的符号出现的次数： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">
												<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4n.jpg" border="0" />
										</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">假设我们要在文本文件中搜索美国的社会安全号码。这个号码的格式是999-99-9999。用来匹配它的正则表达式如图一所示。在正则表达式中，连字符（“-”）有着特殊的意义，它表示一个范围，比如从0到9。因此，匹配社会安全号码中的连字符号时，它的前面要加上一个转义字符“\”。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">
												<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4a.gif" border="0" />
										</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">图一：匹配所有123-12-1234形式的社会安全号码</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">假设进行搜索的时候，你希望连字符号可以出现，也可以不出现——即，999-99-9999和999999999都属于正确的格式。这时，你可以在连字符号后面加上“？”数量限定符号，如图二所示： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">
												<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4b.gif" border="0" />
										</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">图二：匹配所有123-12-1234和123121234形式的社会安全号码</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">下面我们再来看另外一个例子。美国汽车牌照的一种格式是四个数字加上二个字母。它的正则表达式前面是数字部分“[0-9]{4}”，再加上字母部分“[A-Z]{2}”。图三显示了完整的正则表达式。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">
												<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4c.gif" border="0" />
										</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">图三：匹配典型的美国汽车牌照号码，如8836KV</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">1.5 “否”符号 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">“^”符号称为“否”符号。如果用在方括号内，“^”表示不想要匹配的字符。例如，图四的正则表达式匹配所有单词，但以“X”字母开头的单词除外。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">
												<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4d.gif" border="0" />
										</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">图四：匹配所有单词，但“X”开头的除外</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">1.6 圆括号和空白符号 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">假设要从格式为“June 26, 1951”的生日日期中提取出月份部分，用来匹配该日期的正则表达式可以如图五所示： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">
												<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4e.gif" border="0" />
										</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">图五：匹配所有Moth DD,YYYY格式的日期</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">新出现的“\s”符号是空白符号，匹配所有的空白字符，包括Tab字符。如果字符串正确匹配，接下来如何提取出月份部分呢？只需在月份周围加上一个圆括号创建一个组，然后用ORO API（本文后面详细讨论）提取出它的值。修改后的正则表达式如图六所示： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">
												<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4f.gif" border="0" />
										</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">图六：匹配所有Month DD,YYYY格式的日期，定义月份值为第一个组</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<b>1.7 其它符号</b>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">为简便起见，你可以使用一些为常见正则表达式创建的快捷符号。如表二所示： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">表二：常用符号 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">
												<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4o.jpg" border="0" />
										</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">例如，在前面社会安全号码的例子中，所有出现“[0-9]”的地方我们都可以使用“\d”。修改后的正则表达式如图七所示： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">
												<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4g.gif" border="0" />
										</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">图七：匹配所有123-12-1234格式的社会安全号码</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<b>
												<font size="4">二、Jakarta-ORO库</font>
										</b>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">有许多源代码开放的正则表达式库可供Java程序员使用，而且它们中的许多支持Perl 5兼容的正则表达式语法。我在这里选用的是Jakarta-ORO正则表达式库，它是最全面的正则表达式API之一，而且它与Perl 5正则表达式完全兼容。另外，它也是优化得最好的API之一。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">Jakarta-ORO库以前叫做OROMatcher，Daniel Savarese大方地把它赠送给了Jakarta Project。你可以按照本文最后参考资源的说明下载它。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">我首先将简要介绍使用Jakarta-ORO库时你必须创建和访问的对象，然后介绍如何使用Jakarta-ORO API。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<b>▲ PatternCompiler对象</b>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">首先，创建一个Perl5Compiler类的实例，并把它赋值给PatternCompiler接口对象。Perl5Compiler是PatternCompiler接口的一个实现，允许你把正则表达式编译成用来匹配的Pattern对象。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_e.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<b>▲ Pattern对象</b>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">要把正则表达式编译成Pattern对象，调用compiler对象的compile()方法，并在调用参数中指定正则表达式。例如，你可以按照下面这种方式编译正则表达式“t[aeio]n”： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_f.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">默认情况下，编译器创建一个大小写敏感的模式（pattern）。因此，上面代码编译得到的模式只匹配“tin”、“tan”、 “ten”和“ton”，但不匹配“Tin”和“taN”。要创建一个大小写不敏感的模式，你应该在调用编译器的时候指定一个额外的参数： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_g.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">创建好Pattern对象之后，你就可以通过PatternMatcher类用该Pattern对象进行模式匹配。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<b>▲ PatternMatcher对象</b>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">PatternMatcher对象根据Pattern对象和字符串进行匹配检查。你要实例化一个Perl5Matcher类并把结果赋值给PatternMatcher接口。Perl5Matcher类是PatternMatcher接口的一个实现，它根据Perl 5正则表达式语法进行模式匹配： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_h.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">使用PatternMatcher对象，你可以用多个方法进行匹配操作，这些方法的第一个参数都是需要根据正则表达式进行匹配的字符串： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">· boolean matches(String input, Pattern pattern)：当输入字符串和正则表达式要精确匹配时使用。换句话说，正则表达式必须完整地描述输入字符串。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">· boolean matchesPrefix(String input, Pattern pattern)：当正则表达式匹配输入字符串起始部分时使用。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">· boolean contains(String input, Pattern pattern)：当正则表达式要匹配输入字符串的一部分时使用（即，它必须是一个子串）。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">另外，在上面三个方法调用中，你还可以用PatternMatcherInput对象作为参数替代String对象；这时，你可以从字符串中最后一次匹配的位置开始继续进行匹配。当字符串可能有多个子串匹配给定的正则表达式时，用PatternMatcherInput对象作为参数就很有用了。用PatternMatcherInput对象作为参数替代String时，上述三个方法的语法如下： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">· boolean matches(PatternMatcherInput input, Pattern pattern) </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">· boolean matchesPrefix(PatternMatcherInput input, Pattern pattern) </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">· boolean contains(PatternMatcherInput input, Pattern pattern) </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<b>
												<font size="4">三、应用实例</font>
										</b>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">下面我们来看看Jakarta-ORO库的一些应用实例。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<b>3.1 日志文件处理</b>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">任务：分析一个Web服务器日志文件，确定每一个用户花在网站上的时间。在典型的BEA WebLogic日志文件中，日志记录的格式如下： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_i.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">分析这个日志记录，可以发现，要从这个日志文件提取的内容有两项：IP地址和页面访问时间。你可以用分组符号（圆括号）从日志记录提取出IP地址和时间标记。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">首先我们来看看IP地址。IP地址有4个字节构成，每一个字节的值在0到255之间，各个字节通过一个句点分隔。因此，IP地址中的每一个字节有至少一个、最多三个数字。图八显示了为IP地址编写的正则表达式： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">
												<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4h.gif" border="0" />
										</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">图八：匹配IP地址</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">IP地址中的句点字符必须进行转义处理（前面加上“\”），因为IP地址中的句点具有它本来的含义，而不是采用正则表达式语法中的特殊含义。句点在正则表达式中的特殊含义本文前面已经介绍。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">日志记录的时间部分由一对方括号包围。你可以按照如下思路提取出方括号里面的所有内容：首先搜索起始方括号字符（“[”），提取出所有不超过结束方括号字符（“]”）的内容，向前寻找直至找到结束方括号字符。图九显示了这部分的正则表达式。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">
												<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4i.gif" border="0" />
										</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">图九：匹配至少一个字符，直至找到“]”</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">现在，把上述两个正则表达式加上分组符号（圆括号）后合并成单个表达式，这样就可以从日志记录提取出IP地址和时间。注意，为了匹配“- -”（但不提取它），正则表达式中间加入了“\s-\s-\s”。完整的正则表达式如图十所示。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">
												<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4j.gif" border="0" />
										</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">图十：匹配IP地址和时间标记</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">现在正则表达式已经编写完毕，接下来可以编写使用正则表达式库的Java代码了。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">为使用Jakarta-ORO库，首先创建正则表达式字符串和待分析的日志记录字符串： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_j.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">这里使用的正则表达式与图十的正则表达式差不多完全相同，但有一点例外：在Java中，你必须对每一个向前的斜杠（“\”）进行转义处理。图十不是Java的表示形式，所以我们要在每个“\”前面加上一个“\”以免出现编译错误。遗憾的是，转义处理过程很容易出现错误，所以应该小心谨慎。你可以首先输入未经转义处理的正则表达式，然后从左到右依次把每一个“\”替换成“\\”。如果要复检，你可以试着把它输出到屏幕上。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">初始化字符串之后，实例化PatternCompiler对象，用PatternCompiler编译正则表达式创建一个Pattern对象： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_k.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">现在，创建PatternMatcher对象，调用PatternMatcher接口的contain()方法检查匹配情况： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_l.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">接下来，利用PatternMatcher接口返回的MatchResult对象，输出匹配的组。由于logEntry字符串包含匹配的内容，你可以看到类如下面的输出： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_m.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<b>3.2 HTML处理实例一</b>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">下面一个任务是分析HTML页面内FONT标记的所有属性。HTML页面内典型的FONT标记如下所示： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<font face="Arial, Serif" color="red" size="+2">
										</font>
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_n.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">程序将按照如下形式，输出每一个FONT标记的属性： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_o.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">在这种情况下，我建议你使用两个正则表达式。第一个如图十一所示，它从字体标记提取出“"face="Arial, Serif" size="+2" color="red"”。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">
												<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4k.gif" border="0" />
										</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">图十一：匹配FONT标记的所有属性</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">第二个正则表达式如图十二所示，它把各个属性分割成名字-值对。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">
												<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4l.gif" border="0" />
										</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">图十二：匹配单个属性，并把它分割成名字-值对</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">分割结果为： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_p.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">现在我们来看看完成这个任务的Java代码。首先创建两个正则表达式字符串，用Perl5Compiler把它们编译成Pattern对象。编译正则表达式的时候，指定Perl5Compiler.CASE_INSENSITIVE_MASK选项，使得匹配操作不区分大小写。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">接下来，创建一个执行匹配操作的Perl5Matcher对象。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_q.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">假设有一个String类型的变量html，它代表了HTML文件中的一行内容。如果html字符串包含FONT标记，匹配器将返回true。此时，你可以用匹配器对象返回的MatchResult对象获得第一个组，它包含了FONT的所有属性： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_r.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">接下来创建一个PatternMatcherInput对象。这个对象允许你从最后一次匹配的位置开始继续进行匹配操作，因此，它很适合于提取FONT标记内属性的名字-值对。创建PatternMatcherInput对象，以参数形式传入待匹配的字符串。然后，用匹配器实例提取出每一个FONT的属性。这通过指定PatternMatcherInput对象（而不是字符串对象）为参数，反复地调用PatternMatcher对象的contains()方法完成。PatternMatcherInput对象之中的每一次迭代将把它内部的指针向前移动，下一次检测将从前一次匹配位置的后面开始。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">本例的输出结果如下： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_s.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<b>3.3 HTML处理实例二</b>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">下面我们来看看另一个处理HTML的例子。这一次，我们假定Web服务器从widgets.acme.com移到了newserver.acme.com。现在你要修改一些页面中的链接： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_t.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">执行这个搜索的正则表达式如图十三所示： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">
												<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4m.gif" border="0" />
										</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<p align="center">图十三：匹配修改前的链接</p>
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">如果能够匹配这个正则表达式，你可以用下面的内容替换图十三的链接： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<a href="http://newserver.acme.com/interface.html#$1">
										</a>
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_u.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">注意#字符的后面加上了$1。Perl正则表达式语法用$1、$2等表示已经匹配且提取出来的组。图十三的表达式把所有作为一个组匹配和提取出来的内容附加到链接的后面。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">现在，返回Java。就象前面我们所做的那样，你必须创建测试字符串，创建把正则表达式编译到Pattern对象所必需的对象，以及创建一个PatternMatcher对象：<br /><img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_v.jpg" border="0" /></td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">接下来，用com.oroinc.text.regex包Util类的substitute()静态方法进行替换，输出结果字符串： </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_w.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">Util.substitute()方法的语法如下： </td>
						</tr>
				</tbody>
		</table>
		<table height="17" width="620" align="center">
				<tbody>
						<tr>
								<td class="a14" height="13">
										<img src="http://www.ccw.com.cn/htm/app/aprog/01_7_31_4_x.jpg" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">这个调用的前两个参数是以前创建的PatternMatcher和Pattern对象。第三个参数是一个Substiution对象，它决定了替换操作如何进行。本例使用的是Perl5Substitution对象，它能够进行Perl5风格的替换。第四个参数是想要进行替换操作的字符串，最后一个参数允许指定是否替换模式的所有匹配子串（Util.SUBSTITUTE_ALL），或只替换指定的次数。 </td>
						</tr>
				</tbody>
		</table>
		<table width="620" align="center">
				<tbody>
						<tr>
								<td class="a14">
										<b>【结束语】</b>在这篇文章中，我为你介绍了正则表达式的强大功能。只要正确运用，正则表达式能够在字符串提取和文本修改中起到很大的作用。另外，我还介绍了如何在Java程序中通过Jakarta-ORO库利用正则表达式。至于最终采用老式的字符串处理方式（使用StringTokenizer，charAt，和substring），还是采用正则表达式，这就有待你自己决定了。</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/iKingQu/aggbug/75781.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-10-18 02:14 <a href="http://www.blogjava.net/iKingQu/articles/75781.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]Java基本数据类型转换</title><link>http://www.blogjava.net/iKingQu/articles/75755.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Tue, 17 Oct 2006 14:21:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/75755.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/75755.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/75755.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/75755.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/75755.html</trackback:ping><description><![CDATA[
		<p>1 字符串转换成数据 <br />字符串转换成整数： <br />String MyNumber ="1234"; <br />int MyInt = Integer.parseInt(MyNumber); <br />字符串转换成byte, short, int, float, double, long等数据类型，可以分别参考Byte, Short, Integer, Float, Double, Long类的parseXXX方法。 </p>
		<p>
				<br />2 数据转换成字符串 <br />整数转换成字符串： <br />int MyInt = 1234; <br />String MyString = "" + MyInt; <br />其它数据类型可以利用同样的方法转换成字符串。 </p>
		<p>
				<br />3 十进制到其他进制的转换 <br />十进制整数转换成二进制整数，返回结果是一个字符串： <br />Integer.toBinaryString(int i); <br />Integer和Long提供了toBinaryString, toHexString和toOctalString方法，可以方便的将数据转换成二进制、十六进制和八进制字符串。功能更加强大的是其toString(int/long i, int radix)方法，可以将一个十进制数转换成任意进制的字符串形式。 <br />byte, short, float和double等数据类型，可以利用Integer或者是Long的toBinaryString, toHexString, to OctalString和toString方法转换成其他进制的字符串形式。 </p>
		<p>
				<br />4 其它进制到十进制的转换 <br />五进制字符串14414转换成十进制整数，结果是1234： <br />System.out.println(Integer.valueOf("14414", 5); <br />Integer和Long提供的valueOf(String source, int radix)方法，可以将任意进制的字符串转换成十进制数据。 </p>
		<p>
				<br />5 整数到字节数组的转换 <br />public static byte[] toByteArray(int number) <br />{ <br />int temp = number; <br />byte[] b=new byte[4]; <br />for (int i = b.length - 1; i &gt; -1; i--) <br />{ <br />b[i] = new Integer(temp &amp; 0xff).byteValue(); <br />temp = temp &gt;&gt; 8; <br />} <br />return b; <br />} </p>
		<p>
				<br />6 字节数组到整数的转换 <br />public static int toInteger(byte[] b) <br />{ <br />int s = 0; <br />for (int i = 0; i &lt; 3; i++) <br />{ <br />if (b[i] &gt; 0) <br />s = s + b[i]; <br />else <br />s = s + 256 + b[i]; <br />s = s * 256; <br />} <br />if (b[3] &gt; 0) <br />s = s + b[3]; <br />else <br />s = s + 256 + b[3]; <br />return s; <br />} </p>
		<p>
				<br />7 短整数与字节数组之间的相互转换 <br />short与int之间的区别在于short是两个字节的，而int是四个字节的。因此，只需要将5 与6 中的范例程序小做改动，即可实现短整数与字节数组之间的相互转换。 </p>
		<p>
				<br />8 字节数组转换成双精度浮点数 <br />public double toDouble(byte[] b) <br />{ <br />long l = 0; <br />Double D = new Double(0.0); <br />l = b[0]; <br />l |= ((long)b[1]&lt;&lt;8); <br />l |= ((long)b[2]&lt;&lt;16); <br />l |= ((long)b[3]&lt;&lt;24); <br />l |= ((long)b[4]&lt;&lt;32); <br />l |= ((long)b[5]&lt;&lt;40); <br />l |= ((long)b[6]&lt;&lt;48); <br />l |= ((long)b[7]&lt;&lt;56); <br />return D.longBitsToDouble(l); <br />} </p>
		<p>
				<br />9 布尔类型转换成字符串<br />第一种方法是： </p>
		<p>
				<br />boolean bool = true;<br />String s = new Boolean(bool).toString();//将bool利用对象封装器转化为对象<br />s.equals("true");<br />/* 其中，toString方法是一个继承方法。java中所有的类都是object的继承，object的一个重要方法就是toString，用于将对象转化为字符串。*/ </p>
		<p>
				<br />第二种方法是： </p>
		<p>
				<br />boolean bool = true;<br />String s = String.valueOf( bool ); </p>
		<p>
				<br />首先，从代码长度上讲第二种方法明显要比第一种方法简洁；其次，第一种方法在转化过程中多引入了一个完全没有必要的对象，因此，相对第二种方法来说这就造成了内存空间的浪费，大大减慢了运行速度。所以，推荐使用第二种方法。 </p>
		<p>
				<br />10 数字类型与数字类对象之间的转换<br />byte b = 169; <br />Byte bo = new Byte( b ); <br />b = bo.byteValue(); </p>
		<p>
				<br />short t = 169; <br />Short to = new Short( t ); <br />t = to.shortValue(); </p>
		<p>
				<br />int i = 169; <br />Integer io = new Integer( i ); <br />i = io.intValue(); </p>
		<p>
				<br />long l = 169; <br />Long lo = new Long( l ); <br />l = lo.longValue(); </p>
		<p>
				<br />float f = 169f; <br />Float fo = new Float( f ); <br />f = fo.floatValue(); </p>
		<p>
				<br />double d = 169f; <br />Double dObj = new Double( d ); <br />d = dObj.doubleValue(); </p>
<img src ="http://www.blogjava.net/iKingQu/aggbug/75755.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-10-17 22:21 <a href="http://www.blogjava.net/iKingQu/articles/75755.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]"hi there".equals("cheers !") == true </title><link>http://www.blogjava.net/iKingQu/articles/39088.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Tue, 04 Apr 2006 01:44:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/39088.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/39088.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/39088.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/39088.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/39088.html</trackback:ping><description><![CDATA[
		<p>不知道这个标题是否让读者产生一种想打我的冲动。至少今天我的主管被我用这个小把戏诧异了一把，当他看到<span class="ts">"hi there".equals("cheers !") 的结果居然是true时，脸上的表情实在是可爱。</span></p>
		<p>
				<span class="ts">OK，言归正传。System.out.println(<span class="ts">"hi there".equals("cheers !")); 这个看来再显然不过的句子，输出的结果居然是true。聪明的读者，你知道是为什么吗？如果一时还猜不出来，给你一点提示：</span></span>
		</p>
		<p>
				<span class="ts">
						<span class="ts">1、Java语言规范规定，同一个程序中任何相同的字符串常量（literal string）都只是同一个String对象的不同引用，不论它们是否在同一个类、同一个包中。</span>
				</span>
		</p>
		<p>
				<span class="ts">
						<span class="ts">2、Java语言规范规定，由常量表达式计算得到的String对象将在编译期被求值，并在运行时被作为字符串常量对待；在运行时计算得到的String对象将是一个完全独立的新对象。</span>
				</span>
		</p>
		<p>
				<span class="ts">
						<span class="ts">如果你仍然不明就里，或者想知道这个把戏实现的细节，请看下面这篇来自artima的webLog<br /><br /></span>
				</span>
		</p>
		<p>
				<span class="ts">
						<span class="ts">——————————————————</span>
				</span>
		</p>
		<span class="ts">
				<span class="ts">
						<div class="vegies">
								<div class="tc">
										<span class="sts">Artima Weblogs</span>
										<br />
										<font size="6">
												<span class="ts">"hi there".equals("cheers !") == true</span>
												<br />
										</font>
										<span class="as">by Heinz Kabutz</span>
										<br />
										<span class="pd">May 21, 2003</span>
										<br />
								</div>
								<blockquote>
										<b>Summary</b>
										<br />Java Strings are strange animals. They are all kept in one pen, especially the constant strings. This can lead to bizarre behaviour when we intentionally modify the innards of the constant strings through reflection. Join us, as we take apart one of Java's most prolific beasts. </blockquote>
								<hr align="left" width="90%" />
								<p>
								</p>
								<p>Whenever we used to ask our dad a question that he could not possibly have known the answer to (such as: what's the point of school, dad?) he would ask back: "How long is a piece of string?" </p>
								<p>Were he to ask me that now, I would explain to him that String is immutable (supposedly) and that it contains its length, all you have to do is ask the String how long it is. This you can do by calling length(). </p>
								<p>OK, so the first thing we learn about Java is that String is immutable. It is like when we first learn about the stork that brings the babies? There are some things you are not supposed to know until you are older! Secrets so dangerous that merely knowing them would endanger the fibres of electrons pulsating through your Java Virtual Machine. </p>
								<p>So, are Strings immutable? </p>
								<h3>Playing with your sanity - Strings</h3>
								<p>Have a look at the following code: </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 id="Codehighlighter1_22_294_Open_Image" onclick="this.style.display='none'; Codehighlighter1_22_294_Open_Text.style.display='none'; Codehighlighter1_22_294_Closed_Image.style.display='inline'; Codehighlighter1_22_294_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
										<img id="Codehighlighter1_22_294_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_22_294_Closed_Text.style.display='none'; Codehighlighter1_22_294_Open_Image.style.display='inline'; Codehighlighter1_22_294_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />
										<span style="COLOR: #0000ff">public</span>
										<span style="COLOR: #000000"> </span>
										<span style="COLOR: #0000ff">class</span>
										<span style="COLOR: #000000"> MindWarp </span>
										<span id="Codehighlighter1_22_294_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" />
										</span>
										<span id="Codehighlighter1_22_294_Open_Text">
												<span style="COLOR: #000000">{<br /><img id="Codehighlighter1_65_147_Open_Image" onclick="this.style.display='none'; Codehighlighter1_65_147_Open_Text.style.display='none'; Codehighlighter1_65_147_Closed_Image.style.display='inline'; Codehighlighter1_65_147_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_65_147_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_65_147_Closed_Text.style.display='none'; Codehighlighter1_65_147_Open_Image.style.display='inline'; Codehighlighter1_65_147_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />  </span>
												<span style="COLOR: #0000ff">public</span>
												<span style="COLOR: #000000"> </span>
												<span style="COLOR: #0000ff">static</span>
												<span style="COLOR: #000000"> </span>
												<span style="COLOR: #0000ff">void</span>
												<span style="COLOR: #000000"> main(String[] args) </span>
												<span id="Codehighlighter1_65_147_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" />
												</span>
												<span id="Codehighlighter1_65_147_Open_Text">
														<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    System.out.println(<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />      </span>
														<span style="COLOR: #000000">"</span>
														<span style="COLOR: #000000">Romeo, Romeo, wherefore art thou oh Romero?</span>
														<span style="COLOR: #000000">"</span>
														<span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />  }</span>
												</span>
												<span style="COLOR: #000000">
														<br />
														<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />  </span>
												<span style="COLOR: #0000ff">private</span>
												<span style="COLOR: #000000"> </span>
												<span style="COLOR: #0000ff">static</span>
												<span style="COLOR: #000000"> </span>
												<span style="COLOR: #0000ff">final</span>
												<span style="COLOR: #000000"> String OH_ROMEO </span>
												<span style="COLOR: #000000">=</span>
												<span style="COLOR: #000000">
														<br />
														<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
												<span style="COLOR: #000000">"</span>
												<span style="COLOR: #000000">Romeo, Romeo, wherefore art thou oh Romero?</span>
												<span style="COLOR: #000000">"</span>
												<span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />  </span>
												<span style="COLOR: #0000ff">private</span>
												<span style="COLOR: #000000"> </span>
												<span style="COLOR: #0000ff">static</span>
												<span style="COLOR: #000000"> </span>
												<span style="COLOR: #0000ff">final</span>
												<span style="COLOR: #000000"> Warper warper </span>
												<span style="COLOR: #000000">=</span>
												<span style="COLOR: #000000"> </span>
												<span style="COLOR: #0000ff">new</span>
												<span style="COLOR: #000000"> Warper();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
										</span>
										<span style="COLOR: #000000">
												<br />
												<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
										</span>
								</div>
								<p>
										<br />If we are told that the class Warper does not produce any visible output when you construct it, what is the output of this program? The most correct answer is, "you don't know, depends on what Warper does". Now THERE's a nice question for the Sun Certified Java Programmer Examination. </p>
								<p>In my case, running "java MindWarp" produces the following output </p>
								<font size="3">
										<pre>C:&gt; java MindWarp &lt;ENTER&gt;
Stop this romance nonsense, or I'll be sick
</pre>
								</font>
								<p>And here is the code for Warper: </p>
								<font size="3">
										<pre>
												<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" />
														<span style="COLOR: #0000ff">import <span style="COLOR: #000000">java.lang.reflect.<span style="COLOR: #000000">*<font style="BACKGROUND-COLOR: #eeeeee"></font><span style="COLOR: #000000">;</span></span></span></span>
														<span style="COLOR: #000000">
																<br />
																<img id="Codehighlighter1_48_743_Open_Image" onclick="this.style.display='none'; Codehighlighter1_48_743_Open_Text.style.display='none'; Codehighlighter1_48_743_Closed_Image.style.display='inline'; Codehighlighter1_48_743_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
																<img id="Codehighlighter1_48_743_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_48_743_Closed_Text.style.display='none'; Codehighlighter1_48_743_Open_Image.style.display='inline'; Codehighlighter1_48_743_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />
														</span>
														<span style="COLOR: #0000ff">public</span>
														<span style="COLOR: #000000"> </span>
														<span style="COLOR: #0000ff">class</span>
														<span style="COLOR: #000000"> Warper </span>
														<span id="Codehighlighter1_48_743_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" />
														</span>
														<span id="Codehighlighter1_48_743_Open_Text">
																<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />  </span>
																<span style="COLOR: #0000ff">private</span>
																<span style="COLOR: #000000"> </span>
																<span style="COLOR: #0000ff">static</span>
																<span style="COLOR: #000000"> Field stringValue;<br /><img id="Codehighlighter1_95_280_Open_Image" onclick="this.style.display='none'; Codehighlighter1_95_280_Open_Text.style.display='none'; Codehighlighter1_95_280_Closed_Image.style.display='inline'; Codehighlighter1_95_280_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_95_280_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_95_280_Closed_Text.style.display='none'; Codehighlighter1_95_280_Open_Image.style.display='inline'; Codehighlighter1_95_280_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />  </span>
																<span style="COLOR: #0000ff">static</span>
																<span style="COLOR: #000000"> </span>
																<span id="Codehighlighter1_95_280_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" />
																</span>
																<span id="Codehighlighter1_95_280_Open_Text">
																		<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
																		<span style="COLOR: #008000">//</span>
																		<span style="COLOR: #008000"> String has a private char [] called "value"<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
																		<span style="COLOR: #008000">//</span>
																		<span style="COLOR: #008000"> if it does not, find the char [] and assign it to valuetry {</span>
																		<span style="COLOR: #008000">
																				<br />
																				<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />
																		</span>
																		<span style="COLOR: #000000">      stringValue </span>
																		<span style="COLOR: #000000">=</span>
																		<span style="COLOR: #000000"> String.</span>
																		<span style="COLOR: #0000ff">class</span>
																		<span style="COLOR: #000000">.getDeclaredField(</span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">value</span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">);<br /><img id="Codehighlighter1_313_642_Open_Image" onclick="this.style.display='none'; Codehighlighter1_313_642_Open_Text.style.display='none'; Codehighlighter1_313_642_Closed_Image.style.display='inline'; Codehighlighter1_313_642_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_313_642_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_313_642_Closed_Text.style.display='none'; Codehighlighter1_313_642_Open_Image.style.display='inline'; Codehighlighter1_313_642_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    }</span>
																</span>
																<span style="COLOR: #000000"> </span>
																<span style="COLOR: #0000ff">catch</span>
																<span style="COLOR: #000000">(NoSuchFieldException ex) </span>
																<span id="Codehighlighter1_313_642_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" />
																</span>
																<span id="Codehighlighter1_313_642_Open_Text">
																		<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />      </span>
																		<span style="COLOR: #008000">//</span>
																		<span style="COLOR: #008000"> safety net in case we are running on a VM with a<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />      </span>
																		<span style="COLOR: #008000">//</span>
																		<span style="COLOR: #008000"> different name for the char array.</span>
																		<span style="COLOR: #008000">
																				<br />
																				<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />
																		</span>
																		<span style="COLOR: #000000">      Field[] all </span>
																		<span style="COLOR: #000000">=</span>
																		<span style="COLOR: #000000"> String.</span>
																		<span style="COLOR: #0000ff">class</span>
																		<span style="COLOR: #000000">.getDeclaredFields();<br /><img id="Codehighlighter1_533_636_Open_Image" onclick="this.style.display='none'; Codehighlighter1_533_636_Open_Text.style.display='none'; Codehighlighter1_533_636_Closed_Image.style.display='inline'; Codehighlighter1_533_636_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_533_636_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_533_636_Closed_Text.style.display='none'; Codehighlighter1_533_636_Open_Image.style.display='inline'; Codehighlighter1_533_636_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />      </span>
																		<span style="COLOR: #0000ff">for</span>
																		<span style="COLOR: #000000"> (</span>
																		<span style="COLOR: #0000ff">int</span>
																		<span style="COLOR: #000000"> i</span>
																		<span style="COLOR: #000000">=</span>
																		<span style="COLOR: #000000">0</span>
																		<span style="COLOR: #000000">; stringValue </span>
																		<span style="COLOR: #000000">==</span>
																		<span style="COLOR: #000000"> </span>
																		<span style="COLOR: #0000ff">null</span>
																		<span style="COLOR: #000000"> </span>
																		<span style="COLOR: #000000">&amp;&amp;</span>
																		<span style="COLOR: #000000"> i</span>
																		<span style="COLOR: #000000">&lt;</span>
																		<span style="COLOR: #000000">all.length; i</span>
																		<span style="COLOR: #000000">++</span>
																		<span style="COLOR: #000000">) </span>
																		<span id="Codehighlighter1_533_636_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" />
																		</span>
																		<span id="Codehighlighter1_533_636_Open_Text">
																				<span style="COLOR: #000000">{<br /><img id="Codehighlighter1_586_628_Open_Image" onclick="this.style.display='none'; Codehighlighter1_586_628_Open_Text.style.display='none'; Codehighlighter1_586_628_Closed_Image.style.display='inline'; Codehighlighter1_586_628_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_586_628_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_586_628_Closed_Text.style.display='none'; Codehighlighter1_586_628_Open_Image.style.display='inline'; Codehighlighter1_586_628_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />        </span>
																				<span style="COLOR: #0000ff">if</span>
																				<span style="COLOR: #000000"> (all[i].getType().equals(</span>
																				<span style="COLOR: #0000ff">char</span>
																				<span style="COLOR: #000000">[].</span>
																				<span style="COLOR: #0000ff">class</span>
																				<span style="COLOR: #000000">)) </span>
																				<span id="Codehighlighter1_586_628_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" />
																				</span>
																				<span id="Codehighlighter1_586_628_Open_Text">
																						<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />          stringValue </span>
																						<span style="COLOR: #000000">=</span>
																						<span style="COLOR: #000000"> all[i];<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />        }</span>
																				</span>
																				<span style="COLOR: #000000">
																						<br />
																						<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />      }</span>
																		</span>
																		<span style="COLOR: #000000">
																				<br />
																				<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span>
																</span>
																<span style="COLOR: #000000">
																		<br />
																		<img id="Codehighlighter1_673_739_Open_Image" onclick="this.style.display='none'; Codehighlighter1_673_739_Open_Text.style.display='none'; Codehighlighter1_673_739_Closed_Image.style.display='inline'; Codehighlighter1_673_739_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" />
																		<img id="Codehighlighter1_673_739_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_673_739_Closed_Text.style.display='none'; Codehighlighter1_673_739_Open_Image.style.display='inline'; Codehighlighter1_673_739_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
																<span style="COLOR: #0000ff">if</span>
																<span style="COLOR: #000000"> (stringValue </span>
																<span style="COLOR: #000000">!=</span>
																<span style="COLOR: #000000"> </span>
																<span style="COLOR: #0000ff">null</span>
																<span style="COLOR: #000000">) </span>
																<span id="Codehighlighter1_673_739_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" />
																</span>
																<span id="Codehighlighter1_673_739_Open_Text">
																		<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />      stringValue.setAccessible(</span>
																		<span style="COLOR: #0000ff">true</span>
																		<span style="COLOR: #000000">); </span>
																		<span style="COLOR: #008000">//</span>
																		<span style="COLOR: #008000"> make field public</span>
																		<span style="COLOR: #008000">
																				<br />
																				<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />
																		</span>
																		<span style="COLOR: #000000">    }</span>
																</span>
																<span style="COLOR: #000000">
																		<br />
																		<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />  }</span>
														</span>
														<span style="COLOR: #000000">
																<br />
																<img id="Codehighlighter1_763_1047_Open_Image" onclick="this.style.display='none'; Codehighlighter1_763_1047_Open_Text.style.display='none'; Codehighlighter1_763_1047_Closed_Image.style.display='inline'; Codehighlighter1_763_1047_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
																<img id="Codehighlighter1_763_1047_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_763_1047_Closed_Text.style.display='none'; Codehighlighter1_763_1047_Open_Image.style.display='inline'; Codehighlighter1_763_1047_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />  </span>
														<span style="COLOR: #0000ff">public</span>
														<span style="COLOR: #000000"> Warper() </span>
														<span id="Codehighlighter1_763_1047_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" />
														</span>
														<span id="Codehighlighter1_763_1047_Open_Text">
																<span style="COLOR: #000000">{<br /><img id="Codehighlighter1_773_999_Open_Image" onclick="this.style.display='none'; Codehighlighter1_773_999_Open_Text.style.display='none'; Codehighlighter1_773_999_Closed_Image.style.display='inline'; Codehighlighter1_773_999_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_773_999_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_773_999_Closed_Text.style.display='none'; Codehighlighter1_773_999_Open_Image.style.display='inline'; Codehighlighter1_773_999_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
																<span style="COLOR: #0000ff">try</span>
																<span style="COLOR: #000000"> </span>
																<span id="Codehighlighter1_773_999_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" />
																</span>
																<span id="Codehighlighter1_773_999_Open_Text">
																		<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />      stringValue.set(<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">Romeo, Romeo, wherefore art thou oh Romero?</span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">Stop this romance nonsense, or I'll be sick</span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">.<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />          toCharArray());<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />      stringValue.set(</span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">hi there</span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">, </span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">cheers !</span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">.toCharArray());<br /><img id="Codehighlighter1_1034_1035_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1034_1035_Open_Text.style.display='none'; Codehighlighter1_1034_1035_Closed_Image.style.display='inline'; Codehighlighter1_1034_1035_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_1034_1035_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1034_1035_Closed_Text.style.display='none'; Codehighlighter1_1034_1035_Open_Image.style.display='inline'; Codehighlighter1_1034_1035_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    }</span>
																</span>
																<span style="COLOR: #000000"> </span>
																<span style="COLOR: #0000ff">catch</span>
																<span style="COLOR: #000000">(IllegalAccessException ex) </span>
																<span id="Codehighlighter1_1034_1035_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" />
																</span>
																<span id="Codehighlighter1_1034_1035_Open_Text">
																		<span style="COLOR: #000000">{}</span>
																</span>
																<span style="COLOR: #000000"> </span>
																<span style="COLOR: #008000">//</span>
																<span style="COLOR: #008000"> shhh</span>
																<span style="COLOR: #008000">
																		<br />
																		<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />
																</span>
																<span style="COLOR: #000000">  }</span>
														</span>
														<span style="COLOR: #000000">
																<br />
																<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />}<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span>
												</div>
										</pre>
								</font>
								<p>How is this possible? How can String manipulation in a completely different part of the program affect our class MindWarp? </p>
								<p>To understand that, we have to look under the hood of Java. In the language specification it says in ?3.10.5: </p>
								<p>"Each string literal is a reference (?4.3) to an instance (?4.3.1, ?12.5) of class String (?4.3.3). String objects have a constant value. String literals-or, more generally, strings that are the values of constant expressions (?15.28)-are "interned" so as to share unique instances, using the method String.intern." </p>
								<p>The usefulness of this is quite obvious, we will use less memory if we have two Strings which are equivalent pointing at the same object. We can also manually intern Strings by calling the intern() method. </p>
								<p>The language spec goes a bit further: </p>
								<ol>
										<li>Literal strings within the same class (?8) in the same package (?7) represent references to the same String object (?4.3.1). 
</li>
										<li>Literal strings within different classes in the same package represent references to the same String object. 
</li>
										<li>Literal strings within different classes in different packages likewise represent references to the same String object. 
</li>
										<li>Strings computed by constant expressions (?15.28) are computed at compile time and then treated as if they were literals. 
</li>
										<li>Strings computed at run time are newly created and therefore distinct. 
</li>
										<li>The result of explicitly interning a computed string is the same string as any pre-existing literal string with the same contents. </li>
								</ol>
								<p>This means that if a class in another package "fiddles" with an interned String, it can cause havoc in your program. Is this a good thing? (You don't need to answer ;-) </p>
								<p>Consider this example </p>
								<font size="3">
										<pre>
												<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 id="Codehighlighter1_26_226_Open_Image" onclick="this.style.display='none'; Codehighlighter1_26_226_Open_Text.style.display='none'; Codehighlighter1_26_226_Closed_Image.style.display='inline'; Codehighlighter1_26_226_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
														<img id="Codehighlighter1_26_226_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_26_226_Closed_Text.style.display='none'; Codehighlighter1_26_226_Open_Image.style.display='inline'; Codehighlighter1_26_226_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />
														<span style="COLOR: #0000ff">public</span>
														<span style="COLOR: #000000"> </span>
														<span style="COLOR: #0000ff">class</span>
														<span style="COLOR: #000000"> StringEquals </span>
														<span id="Codehighlighter1_26_226_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" />
														</span>
														<span id="Codehighlighter1_26_226_Open_Text">
																<span style="COLOR: #000000">{<br /><img id="Codehighlighter1_67_122_Open_Image" onclick="this.style.display='none'; Codehighlighter1_67_122_Open_Text.style.display='none'; Codehighlighter1_67_122_Closed_Image.style.display='inline'; Codehighlighter1_67_122_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_67_122_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_67_122_Closed_Text.style.display='none'; Codehighlighter1_67_122_Open_Image.style.display='inline'; Codehighlighter1_67_122_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /></span>
																<span style="COLOR: #0000ff">public</span>
																<span style="COLOR: #000000"> </span>
																<span style="COLOR: #0000ff">static</span>
																<span style="COLOR: #000000"> </span>
																<span style="COLOR: #0000ff">void</span>
																<span style="COLOR: #000000"> main(String[] args) </span>
																<span id="Codehighlighter1_67_122_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" />
																</span>
																<span id="Codehighlighter1_67_122_Open_Text">
																		<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />  System.out.println(</span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">hi there</span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">.equals(</span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">cheers !</span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />}</span>
																</span>
																<span style="COLOR: #000000">
																		<br />
																		<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />
																</span>
																<span style="COLOR: #0000ff">private</span>
																<span style="COLOR: #000000"> </span>
																<span style="COLOR: #0000ff">static</span>
																<span style="COLOR: #000000"> </span>
																<span style="COLOR: #0000ff">final</span>
																<span style="COLOR: #000000"> String greeting </span>
																<span style="COLOR: #000000">=</span>
																<span style="COLOR: #000000"> </span>
																<span style="COLOR: #000000">"</span>
																<span style="COLOR: #000000">hi there</span>
																<span style="COLOR: #000000">"</span>
																<span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span>
																<span style="COLOR: #0000ff">private</span>
																<span style="COLOR: #000000"> </span>
																<span style="COLOR: #0000ff">static</span>
																<span style="COLOR: #000000"> </span>
																<span style="COLOR: #0000ff">final</span>
																<span style="COLOR: #000000"> Warper warper </span>
																<span style="COLOR: #000000">=</span>
																<span style="COLOR: #000000"> </span>
																<span style="COLOR: #0000ff">new</span>
																<span style="COLOR: #000000"> Warper();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
														</span>
														<span style="COLOR: #000000">
																<br />
																<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
														</span>
												</div>
										</pre>
								</font>
								<p>Running this against the Warper produces a result of true, which is really weird, and in my opinion, quite mind-bending. Hey, you can SEE the values there right in front of you and they are clearly NOT equal! </p>
								<p>BTW, for simplicity, the Strings in my examples are exactly the same length, but you can change the length quite easily as well. </p>
								<p>Last example concerns the HashCode of String, which is now cached for performance reasons mentioned in "Java Idiom and Performance Guide", ISBN 0130142603. (Just for the record, I was never and am still not convinced that caching the String hash code in a wrapper object is a good idea, but caching it in String itself is almost acceptable, considering String literals.) </p>
								<font size="3">
										<pre>
												<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 id="Codehighlighter1_29_320_Open_Image" onclick="this.style.display='none'; Codehighlighter1_29_320_Open_Text.style.display='none'; Codehighlighter1_29_320_Closed_Image.style.display='inline'; Codehighlighter1_29_320_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
														<img id="Codehighlighter1_29_320_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_29_320_Closed_Text.style.display='none'; Codehighlighter1_29_320_Open_Image.style.display='inline'; Codehighlighter1_29_320_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />
														<span style="COLOR: #0000ff">public</span>
														<span style="COLOR: #000000"> </span>
														<span style="COLOR: #0000ff">class</span>
														<span style="COLOR: #000000"> CachingHashcode </span>
														<span id="Codehighlighter1_29_320_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" />
														</span>
														<span id="Codehighlighter1_29_320_Open_Text">
																<span style="COLOR: #000000">{<br /><img id="Codehighlighter1_72_265_Open_Image" onclick="this.style.display='none'; Codehighlighter1_72_265_Open_Text.style.display='none'; Codehighlighter1_72_265_Closed_Image.style.display='inline'; Codehighlighter1_72_265_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_72_265_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_72_265_Closed_Text.style.display='none'; Codehighlighter1_72_265_Open_Image.style.display='inline'; Codehighlighter1_72_265_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />  </span>
																<span style="COLOR: #0000ff">public</span>
																<span style="COLOR: #000000"> </span>
																<span style="COLOR: #0000ff">static</span>
																<span style="COLOR: #000000"> </span>
																<span style="COLOR: #0000ff">void</span>
																<span style="COLOR: #000000"> main(String[] args) </span>
																<span id="Codehighlighter1_72_265_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" />
																</span>
																<span id="Codehighlighter1_72_265_Open_Text">
																		<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    java.util.Map map </span>
																		<span style="COLOR: #000000">=</span>
																		<span style="COLOR: #000000"> </span>
																		<span style="COLOR: #0000ff">new</span>
																		<span style="COLOR: #000000"> java.util.HashMap();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    map.put(</span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">hi there</span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">, </span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">You found the value</span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
																		<span style="COLOR: #0000ff">new</span>
																		<span style="COLOR: #000000"> Warper();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    System.out.println(map.get(</span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">hi there</span>
																		<span style="COLOR: #000000">"</span>
																		<span style="COLOR: #000000">));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    System.out.println(map);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />  }</span>
																</span>
																<span style="COLOR: #000000">
																		<br />
																		<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />  </span>
																<span style="COLOR: #0000ff">private</span>
																<span style="COLOR: #000000"> </span>
																<span style="COLOR: #0000ff">static</span>
																<span style="COLOR: #000000"> </span>
																<span style="COLOR: #0000ff">final</span>
																<span style="COLOR: #000000"> String greeting </span>
																<span style="COLOR: #000000">=</span>
																<span style="COLOR: #000000"> </span>
																<span style="COLOR: #000000">"</span>
																<span style="COLOR: #000000">hi there</span>
																<span style="COLOR: #000000">"</span>
																<span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
														</span>
														<span style="COLOR: #000000">
																<br />
																<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
														</span>
												</div>
										</pre>
								</font>
								<p>The output under JDK 1.3 is: </p>
								<font size="3">
										<pre>You found the value
{cheers !=You found the value}
</pre>
								</font>
								<p>Under JDK 1.2 it is </p>
								<font size="3">
										<pre>null
{cheers !=You found the value}
</pre>
								</font>
								<p>This is because in the JDK 1.3 SUN is caching the hash code so if it once is calculated, it doesn't get recalculated, so if the value field changes, the hashcode stays the same. </p>
								<p>Imagine trying to debug this program where SOMEWHERE, one of your hackers has done a "workaround" by modifying a String literal. The thought scares me. </p>
								<p>The practical application of this blog? Let's face it, none. </p>
								<p>This is my first blog ever, I would be keen to hear what you thought of it? <br /><br /><br /><br />摘自：<a href="http://www.daima.com.cn/Info/55/Info14695/">http://www.daima.com.cn/Info/55/Info14695/</a></p>
						</div>
				</span>
		</span>
<img src ="http://www.blogjava.net/iKingQu/aggbug/39088.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-04-04 09:44 <a href="http://www.blogjava.net/iKingQu/articles/39088.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]interface 与 abstract ...</title><link>http://www.blogjava.net/iKingQu/articles/37853.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Tue, 28 Mar 2006 10:52:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/37853.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/37853.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/37853.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/37853.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/37853.html</trackback:ping><description><![CDATA[虽然一直觉得 interface 和abstract其实各自作用不同，而且有各自所适应的情况。但是就是说不清楚，他们在使用时应该在注意的区别。<br />    看了 Erich Gamma的说法，恍然大悟。java interface作为接口时是应该相对稳定的。一旦你修改了一个接口，其实现都会作废，需要按照从新修改来遵守这个已发布的契约。而从，领域抽象的角度来看。java 中的interface 应该作为一个行为契约来用。所以，只有相对稳定的行为集可以作为一个接口公告和契约发布出来，让client调用，这才是java interface的真实含义。比如，发布一个Transcation interface作为，事务行为契约再好不过了。<br />    而abstract作为接口时是相对稳定性是宽松的。如果你想增加一个方法，来让一个比较特殊的实例来作为实现。你可以直接在抽象方法实现一个默认方法，这样其他子类就不会受到较大的牵连。从领域抽象的角度来说，对象既可以描述实体也可以描述行为。然而，通常一旦描述行为，使用整个对象来描述一个整体行为的（注意不是一个行为集）。所以，总体来说，abstract应该用以描述内部行为相对不太确定的实体，或内部子行为不太确定的行为的。比如，java collection框架中的AbstractList<br />    Erich Gamma: 接口提取出对象之间的协作关系。接口是独立于实现细节的，而且它定义了协作的语汇（vocabulary）。一旦我理解了接口，我就理解了系统的大部分。为什么？因为当我理解了所有接口以后，我应该就能够理解关于这个问题的语汇。<br />    精辟啊。。。系统分治以后，整个系统的复杂度就转化为子系统之间的交互上了。一旦定义了套接口，那么对于各个子系统来说已经制导整个系统了，复杂的问题就变得简单了。 <br /><br />原文地址：<a href="/wfeng007/archive/2006/03/28/37740.html">http://www.blogjava.net/wfeng007/archive/2006/03/28/37740.html</a><br /><br /><a id="Comments1_CommentList_ctl01_NameLink" href="/mixlee/" target="_blank"><font color="#366900">mixlee</font></a> 评论<br /><br />我认为接口是约定遵守的行为标准，具体怎么实现可以由各使用者自行确定。 <br />所以一般技术标准都是以接口形式公布。可以方便各厂商自行实现。所以接口主要是对外的。 <br />abstract更大程度上是应用在自己能掌控的内部，比如自己是软件开发商，那么在自己的系统里就可以大张旗鼓的使用abstract而不用考虑别人会怎么实现。 <br />表达能力不好，说的不太清楚。也就是说如果有第三方实现的参与，最好用接口，如果是自己实现，接口和abstract都可以考虑 <br /><img src ="http://www.blogjava.net/iKingQu/aggbug/37853.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-28 18:52 <a href="http://www.blogjava.net/iKingQu/articles/37853.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]全面理解Java中的String数据类型</title><link>http://www.blogjava.net/iKingQu/articles/37423.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Sat, 25 Mar 2006 16:53:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/37423.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/37423.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/37423.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/37423.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/37423.html</trackback:ping><description><![CDATA[
		<span class="span">作者：qzg589<br /><br />1. 首先String不属于8种基本数据类型，String是一个对象。 <br /><br />　　因为对象的默认值是null，所以String的默认值也是null；但它又是一种特殊的对象，有其它对象没有的一些特性。 <br /><br />　　2. new String()和new String(“”)都是申明一个新的空字符串，是空串不是null； <br /><br />　　3. String str=”kvill”； <br />String str=new String (“kvill”);的区别： <br /><br />　　在这里，我们不谈堆，也不谈栈，只先简单引入常量池这个简单的概念。 <br /><br />　　常量池(constant pool)指的是在编译期被确定，并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量，也包括字符串常量。 <br /><br />　　看例1： <br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1"><tbody><tr><td>String s0=”kvill”; <br />String s1=”kvill”; <br />String s2=”kv” + “ill”; <br />System.out.println( s0==s1 ); <br />System.out.println( s0==s2 ); </td></tr></tbody></table><br />　　结果为： <br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1"><tbody><tr><td>true <br />true </td></tr></tbody></table><br />　　首先，我们要知道Java会确保一个字符串常量只有一个拷贝。 <br /><br />　　因为例子中的s0和s1中的”kvill”都是字符串常量，它们在编译期就被确定了，所以s0==s1为true；而”kv”和”ill”也都是字符串常量，当一个字符串由多个字符串常量连接而成时，它自己肯定也是字符串常量，所以s2也同样在编译期就被解析为一个字符串常量，所以s2也是常量池中”kvill”的一个引用。 <br /><br />　　所以我们得出s0==s1==s2; <br /><br />　　用new String() 创建的字符串不是常量，不能在编译期就确定，所以new String() 创建的字符串不放入常量池中，它们有自己的地址空间。 <br /><br />　　看例2： <br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1"><tbody><tr><td>String s0=”kvill”; <br />String s1=new String(”kvill”); <br />String s2=”kv” + new String(“ill”); <br />System.out.println( s0==s1 ); <br />System.out.println( s0==s2 ); <br />System.out.println( s1==s2 ); </td></tr></tbody></table><br />　　结果为： <br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1"><tbody><tr><td>false <br />false <br />false </td></tr></tbody></table><br />　　例2中s0还是常量池中”kvill”的应用，s1因为无法在编译期确定，所以是运行时创建的新对象”kvill”的引用，s2因为有后半部分new String(“ill”)所以也无法在编译期确定，所以也是一个新创建对象”kvill”的应用;明白了这些也就知道为何得出此结果了。 <br /><br />　　4. String.intern()： <br /><br />　　再补充介绍一点：存在于.class文件中的常量池，在运行期被JVM装载，并且可以扩充。String的intern()方法就是扩充常量池的一个方法；当一个String实例str调用intern()方法时，Java查找常量池中是否有相同Unicode的字符串常量，如果有，则返回其的引用，如果没有，则在常量池中增加一个Unicode等于str的字符串并返回它的引用；看例3就清楚了 <br /><br />　　例3： <br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1"><tbody><tr><td>String s0= “kvill”; <br />String s1=new String(”kvill”); <br />String s2=new String(“kvill”); <br />System.out.println( s0==s1 ); <br />System.out.println( “**********” ); <br />s1.intern(); <br />s2=s2.intern(); //把常量池中“kvill”的引用赋给s2 <br />System.out.println( s0==s1); <br />System.out.println( s0==s1.intern() ); <br />System.out.println( s0==s2 ); </td></tr></tbody></table><br />　　结果为： <br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1"><tbody><tr><td>false <br />********** <br />false //虽然执行了s1.intern(),但它的返回值没有赋给s1 <br />true //说明s1.intern()返回的是常量池中”kvill”的引用 <br />true </td></tr></tbody></table><br />　　最后我再破除一个错误的理解： <br /><br />　　有人说，“使用String.intern()方法则可以将一个String类的保存到一个全局String表中，如果具有相同值的Unicode字符串已经在这个表中，那么该方法返回表中已有字符串的地址，如果在表中没有相同值的字符串，则将自己的地址注册到表中“如果我把他说的这个全局的String表理解为常量池的话，他的最后一句话，“如果在表中没有相同值的字符串，则将自己的地址注册到表中”是错的： <br /><br />　　看例4： <br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1"><tbody><tr><td>String s1=new String("kvill"); <br />String s2=s1.intern(); <br />System.out.println( s1==s1.intern() ); <br />System.out.println( s1+" "+s2 ); <br />System.out.println( s2==s1.intern() ); </td></tr></tbody></table><br />　　结果： <br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1"><tbody><tr><td>false <br />kvill kvill <br />true </td></tr></tbody></table><br />　　在这个类中我们没有声名一个”kvill”常量，所以常量池中一开始是没有”kvill”的，当我们调用s1.intern()后就在常量池中新添加了一个”kvill”常量，原来的不在常量池中的”kvill”仍然存在，也就不是“将自己的地址注册到常量池中”了。 <br /><br />　　s1==s1.intern()为false说明原来的“kvill”仍然存在； <br /><br />　　s2现在为常量池中“kvill”的地址，所以有s2==s1.intern()为true。 <br /><br />　　5. 关于equals()和==: <br /><br />　　这个对于String简单来说就是比较两字符串的Unicode序列是否相当，如果相等返回true;而==是比较两字符串的地址是否相同，也就是是否是同一个字符串的引用。 <br /><br />　　6. 关于String是不可变的<br /><br />　　这一说又要说很多，大家只要知道String的实例一旦生成就不会再改变了，比如说：String str=”kv”+”ill”+” “+”ans”; <br />就是有4个字符串常量，首先”kv”和”ill”生成了”kvill”存在内存中，然后”kvill”又和” “ 生成 ”kvill “存在内存中，最后又和生成了”kvill ans”;并把这个字符串的地址赋给了str,就是因为String的“不可变”产生了很多临时变量，这也就是为什么建议用StringBuffer的原因了，因为StringBuffer是可改变的 </span>
<img src ="http://www.blogjava.net/iKingQu/aggbug/37423.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-26 00:53 <a href="http://www.blogjava.net/iKingQu/articles/37423.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]用Java实现几种常见的排序算法</title><link>http://www.blogjava.net/iKingQu/articles/37330.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Sat, 25 Mar 2006 05:08:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/37330.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/37330.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/37330.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/37330.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/37330.html</trackback:ping><description><![CDATA[
		<p>出处：CSDN    作者：treeroot<br /><br />用Java语言实现的各种排序，包括插入排序、冒泡排序、选择排序、Shell排序、快速排序、归并排序、堆排序、SortUtil等。<br /><br /></p>
		<p clear="both">插入排序：</p>
		<p class="code">package org.rut.util.algorithm.support;<br /><br />import org.rut.util.algorithm.SortUtil;<br />/**<br /> * @author treeroot<br /> * @since 2006-2-2<br /> * @version 1.0<br /> */<br />public class InsertSort implements SortUtil.Sort{<br /><br />    /* (non-Javadoc)<br />     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])<br />     */<br />    public void sort(int[] data) {<br />        int temp;<br />        for(int i=1;i&lt;data.length;i++){<br />            for(int j=i;(j&gt;0)&amp;&amp;(data[j]&lt;data[j-1]);j--){<br />                SortUtil.swap(data,j,j-1);<br />            }<br />        }        <br />    }<br /><br />}</p>
		<p>冒泡排序：</p>
		<p class="code">package org.rut.util.algorithm.support;<br /><br />import org.rut.util.algorithm.SortUtil;<br /><br />/**<br /> * @author treeroot<br /> * @since 2006-2-2<br /> * @version 1.0<br /> */<br />public class BubbleSort implements SortUtil.Sort{<br /><br />    /* (non-Javadoc)<br />     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])<br />     */<br />    public void sort(int[] data) {<br />        int temp;<br />        for(int i=0;i&lt;data.length;i++){<br />            for(int j=data.length-1;j&gt;i;j--){<br />                if(data[j]&lt;data[j-1]){<br />                    SortUtil.swap(data,j,j-1);<br />                }<br />            }<br />        }<br />    }<br /><br />}<br /><br /></p>
		<table cellspacing="0" cellpadding="0" width="98%" align="center" border="0">
				<tbody>
						<tr>
								<td class="article" width="100%" height="62">
										<p>
										</p>
										<p>选择排序：</p>
										<p class="code">package org.rut.util.algorithm.support;<br /><br />import org.rut.util.algorithm.SortUtil;<br /><br />/**<br /> * @author treeroot<br /> * @since 2006-2-2<br /> * @version 1.0<br /> */<br />public class SelectionSort implements SortUtil.Sort {<br /><br />    /*<br />     * (non-Javadoc)<br />     * <br />     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])<br />     */<br />    public void sort(int[] data) {<br />        int temp;<br />        for (int i = 0; i &lt; data.length; i++) {<br />            int lowIndex = i;<br />            for (int j = data.length - 1; j &gt; i; j--) {<br />                if (data[j] &lt; data[lowIndex]) {<br />                    lowIndex = j;<br />                }<br />            }<br />            SortUtil.swap(data,i,lowIndex);<br />        }<br />    }<br /><br />}</p>
										<p>Shell排序：</p>
										<p class="code">package org.rut.util.algorithm.support;<br /><br />import org.rut.util.algorithm.SortUtil;<br /><br />/**<br /> * @author treeroot<br /> * @since 2006-2-2<br /> * @version 1.0<br /> */<br />public class ShellSort implements SortUtil.Sort{<br /><br />    /* (non-Javadoc)<br />     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])<br />     */<br />    public void sort(int[] data) {<br />        for(int i=data.length/2;i&gt;2;i/=2){<br />            for(int j=0;j&lt;i;j++){<br />                insertSort(data,j,i);<br />            }<br />        }<br />        insertSort(data,0,1);<br />    }<br /><br />    /**<br />     * @param data<br />     * @param j<br />     * @param i<br />     */<br />    private void insertSort(int[] data, int start, int inc) {<br />        int temp;<br />        for(int i=start+inc;i&lt;data.length;i+=inc){<br />            for(int j=i;(j&gt;=inc)&amp;&amp;(data[j]&lt;data[j-inc]);j-=inc){<br />                SortUtil.swap(data,j,j-inc);<br />            }<br />        }<br />    }<br /><br />}<br /><br /></p>
										<table cellspacing="0" cellpadding="0" width="98%" align="center" border="0">
												<tbody>
														<tr>
																<td class="article" width="100%" height="62">
																		<p>
																		</p>
																		<p>快速排序：</p>
																		<p class="code">package org.rut.util.algorithm.support;<br /><br />import org.rut.util.algorithm.SortUtil;<br /><br />/**<br /> * @author treeroot<br /> * @since 2006-2-2<br /> * @version 1.0<br /> */<br />public class QuickSort implements SortUtil.Sort{<br /><br />    /* (non-Javadoc)<br />     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])<br />     */<br />    public void sort(int[] data) {<br />        quickSort(data,0,data.length-1);        <br />    }<br />    private void quickSort(int[] data,int i,int j){<br />        int pivotIndex=(i+j)/2;<br />        //swap<br />        SortUtil.swap(data,pivotIndex,j);<br />        <br />        int k=partition(data,i-1,j,data[j]);<br />        SortUtil.swap(data,k,j);<br />        if((k-i)&gt;1) quickSort(data,i,k-1);<br />        if((j-k)&gt;1) quickSort(data,k+1,j);<br />        <br />    }<br />    /**<br />     * @param data<br />     * @param i<br />     * @param j<br />     * @return<br />     */<br />    private int partition(int[] data, int l, int r,int pivot) {<br />        do{<br />           while(data[++l]&lt;pivot);<br />           while((r!=0)&amp;&amp;data[--r]&gt;pivot);<br />           SortUtil.swap(data,l,r);<br />        }<br />        while(l&lt;r);<br />        SortUtil.swap(data,l,r);        <br />        return l;<br />    }<br /><br />}</p>
																		<p>改进后的快速排序：</p>
																		<p class="code">package org.rut.util.algorithm.support;<br /><br />import org.rut.util.algorithm.SortUtil;<br /><br />/**<br /> * @author treeroot<br /> * @since 2006-2-2<br /> * @version 1.0<br /> */<br />public class ImprovedQuickSort implements SortUtil.Sort {<br /><br />    private static int MAX_STACK_SIZE=4096;<br />    private static int THRESHOLD=10;<br />    /* (non-Javadoc)<br />     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])<br />     */<br />    public void sort(int[] data) {<br />        int[] stack=new int[MAX_STACK_SIZE];<br />        <br />        int top=-1;<br />        int pivot;<br />        int pivotIndex,l,r;<br />        <br />        stack[++top]=0;<br />        stack[++top]=data.length-1;<br />        <br />        while(top&gt;0){<br />            int j=stack[top--];<br />            int i=stack[top--];<br />            <br />            pivotIndex=(i+j)/2;<br />            pivot=data[pivotIndex];<br />            <br />            SortUtil.swap(data,pivotIndex,j);<br />            <br />            //partition<br />            l=i-1;<br />            r=j;<br />            do{<br />                while(data[++l]&lt;pivot);<br />                while((r!=0)&amp;&amp;(data[--r]&gt;pivot));<br />                SortUtil.swap(data,l,r);<br />            }<br />            while(l&lt;r);<br />            SortUtil.swap(data,l,r);<br />            SortUtil.swap(data,l,j);<br />            <br />            if((l-i)&gt;THRESHOLD){<br />                stack[++top]=i;<br />                stack[++top]=l-1;<br />            }<br />            if((j-l)&gt;THRESHOLD){<br />                stack[++top]=l+1;<br />                stack[++top]=j;<br />            }<br />            <br />        }<br />        //new InsertSort().sort(data);<br />        insertSort(data);<br />    }<br />    /**<br />     * @param data<br />     */<br />    private void insertSort(int[] data) {<br />        int temp;<br />        for(int i=1;i&lt;data.length;i++){<br />            for(int j=i;(j&gt;0)&amp;&amp;(data[j]&lt;data[j-1]);j--){<br />                SortUtil.swap(data,j,j-1);<br />            }<br />        }       <br />    }<br /><br />}<br /><br /></p>
																		<table cellspacing="0" cellpadding="0" width="98%" align="center" border="0">
																				<tbody>
																						<tr>
																								<td class="article" width="100%" height="62">
																										<p>
																										</p>
																										<p>归并排序：</p>
																										<p class="code">package org.rut.util.algorithm.support;<br /><br />import org.rut.util.algorithm.SortUtil;<br /><br />/**<br /> * @author treeroot<br /> * @since 2006-2-2<br /> * @version 1.0<br /> */<br />public class MergeSort implements SortUtil.Sort{<br /><br />    /* (non-Javadoc)<br />     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])<br />     */<br />    public void sort(int[] data) {<br />        int[] temp=new int[data.length];<br />        mergeSort(data,temp,0,data.length-1);<br />    }<br />    <br />    private void mergeSort(int[] data,int[] temp,int l,int r){<br />        int mid=(l+r)/2;<br />        if(l==r) return ;<br />        mergeSort(data,temp,l,mid);<br />        mergeSort(data,temp,mid+1,r);<br />        for(int i=l;i&lt;=r;i++){<br />            temp[i]=data[i];<br />        }<br />        int i1=l;<br />        int i2=mid+1;<br />        for(int cur=l;cur&lt;=r;cur++){<br />            if(i1==mid+1)<br />                data[cur]=temp[i2++];<br />            else if(i2&gt;r)<br />                data[cur]=temp[i1++];<br />            else if(temp[i1]&lt;temp[i2])<br />                data[cur]=temp[i1++];<br />            else<br />                data[cur]=temp[i2++];            <br />        }<br />    }<br /><br />}</p>
																										<p>改进后的归并排序:</p>
																										<p class="code">package org.rut.util.algorithm.support;<br /><br />import org.rut.util.algorithm.SortUtil;<br /><br />/**<br /> * @author treeroot<br /> * @since 2006-2-2<br /> * @version 1.0<br /> */<br />public class ImprovedMergeSort implements SortUtil.Sort {<br /><br />    private static final int THRESHOLD = 10;<br /><br />    /*<br />     * (non-Javadoc)<br />     * <br />     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])<br />     */<br />    public void sort(int[] data) {<br />        int[] temp=new int[data.length];<br />        mergeSort(data,temp,0,data.length-1);<br />    }<br /><br />    private void mergeSort(int[] data, int[] temp, int l, int r) {<br />        int i, j, k;<br />        int mid = (l + r) / 2;<br />        if (l == r)<br />            return;<br />        if ((mid - l) &gt;= THRESHOLD)<br />            mergeSort(data, temp, l, mid);<br />        else<br />            insertSort(data, l, mid - l + 1);<br />        if ((r - mid) &gt; THRESHOLD)<br />            mergeSort(data, temp, mid + 1, r);<br />        else<br />            insertSort(data, mid + 1, r - mid);<br /><br />        for (i = l; i &lt;= mid; i++) {<br />            temp[i] = data[i];<br />        }<br />        for (j = 1; j &lt;= r - mid; j++) {<br />            temp[r - j + 1] = data[j + mid];<br />        }<br />        int a = temp[l];<br />        int b = temp[r];<br />        for (i = l, j = r, k = l; k &lt;= r; k++) {<br />            if (a &lt; b) {<br />                data[k] = temp[i++];<br />                a = temp[i];<br />            } else {<br />                data[k] = temp[j--];<br />                b = temp[j];<br />            }<br />        }<br />    }<br /><br />    /**<br />     * @param data<br />     * @param l<br />     * @param i<br />     */<br />    private void insertSort(int[] data, int start, int len) {<br />        for(int i=start+1;i&lt;start+len;i++){<br />            for(int j=i;(j&gt;start) &amp;&amp; data[j]&lt;data[j-1];j--){<br />                SortUtil.swap(data,j,j-1);<br />            }<br />        }<br />    }</p>
																										<p>}<br /><br /></p>
																										<p>堆排序：</p>
																										<p class="code">package org.rut.util.algorithm.support;<br /><br />import org.rut.util.algorithm.SortUtil;<br /><br />/**<br /> * @author treeroot<br /> * @since 2006-2-2<br /> * @version 1.0<br /> */<br />public class HeapSort implements SortUtil.Sort{<br /><br />    /* (non-Javadoc)<br />     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])<br />     */<br />    public void sort(int[] data) {<br />        MaxHeap h=new MaxHeap();<br />        h.init(data);<br />        for(int i=0;i&lt;data.length;i++)<br />            h.remove();<br />        System.arraycopy(h.queue,1,data,0,data.length);<br />    }<br /><br />     private static class MaxHeap{         <br />        <br />        void init(int[] data){<br />            this.queue=new int[data.length+1];<br />            for(int i=0;i&lt;data.length;i++){<br />                queue[++size]=data[i];<br />                fixUp(size);<br />            }<br />        }<br />         <br />        private int size=0;<br /><br />        private int[] queue;<br />                <br />        public int get() {<br />            return queue[1];<br />        }<br /><br />        public void remove() {<br />            SortUtil.swap(queue,1,size--);<br />            fixDown(1);<br />        }<br />        //fixdown<br />        private void fixDown(int k) {<br />            int j;<br />            while ((j = k &lt;&lt; 1) &lt;= size) {<br />                if (j &lt; size &amp;&amp; queue[j]&lt;queue[j+1])<br />                    j++; <br />                if (queue[k]&gt;queue[j]) //不用交换<br />                    break;<br />                SortUtil.swap(queue,j,k);<br />                k = j;<br />            }<br />        }<br />        private void fixUp(int k) {<br />            while (k &gt; 1) {<br />                int j = k &gt;&gt; 1;<br />                if (queue[j]&gt;queue[k])<br />                    break;<br />                SortUtil.swap(queue,j,k);<br />                k = j;<br />            }<br />        }<br /><br />    }<br /><br />}<br /><br /></p>
																										<p>SortUtil：</p>
																										<p class="code">package org.rut.util.algorithm;<br /><br />import org.rut.util.algorithm.support.BubbleSort;<br />import org.rut.util.algorithm.support.HeapSort;<br />import org.rut.util.algorithm.support.ImprovedMergeSort;<br />import org.rut.util.algorithm.support.ImprovedQuickSort;<br />import org.rut.util.algorithm.support.InsertSort;<br />import org.rut.util.algorithm.support.MergeSort;<br />import org.rut.util.algorithm.support.QuickSort;<br />import org.rut.util.algorithm.support.SelectionSort;<br />import org.rut.util.algorithm.support.ShellSort;<br /><br />/**<br /> * @author treeroot<br /> * @since 2006-2-2<br /> * @version 1.0<br /> */<br />public class SortUtil {<br />    public final static int INSERT = 1;<br />    public final static int BUBBLE = 2;<br />    public final static int SELECTION = 3;<br />    public final static int SHELL = 4;<br />    public final static int QUICK = 5;<br />    public final static int IMPROVED_QUICK = 6;<br />    public final static int MERGE = 7;<br />    public final static int IMPROVED_MERGE = 8;<br />    public final static int HEAP = 9;<br /><br />    public static void sort(int[] data) {<br />        sort(data, IMPROVED_QUICK);<br />    }<br />    private static String[] name={<br />            "insert", "bubble", "selection", "shell", "quick", "improved_quick", "merge", "improved_merge", "heap"<br />    };<br />    <br />    private static Sort[] impl=new Sort[]{<br />            new InsertSort(),<br />            new BubbleSort(),<br />            new SelectionSort(),<br />            new ShellSort(),<br />            new QuickSort(),<br />            new ImprovedQuickSort(),<br />            new MergeSort(),<br />            new ImprovedMergeSort(),<br />            new HeapSort()<br />    };<br /><br />    public static String toString(int algorithm){<br />        return name[algorithm-1];<br />    }<br />    <br />    public static void sort(int[] data, int algorithm) {<br />        impl[algorithm-1].sort(data);<br />    }<br /><br />    public static interface Sort {<br />        public void sort(int[] data);<br />    }<br /><br />    public static void swap(int[] data, int i, int j) {<br />        int temp = data[i];<br />        data[i] = data[j];<br />        data[j] = temp;<br />    }<br />}</p>
																								</td>
																						</tr>
																				</tbody>
																		</table>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/iKingQu/aggbug/37330.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-25 13:08 <a href="http://www.blogjava.net/iKingQu/articles/37330.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]Java初学者容易混淆的几个问题</title><link>http://www.blogjava.net/iKingQu/articles/36882.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Wed, 22 Mar 2006 08:34:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/36882.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/36882.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/36882.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/36882.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/36882.html</trackback:ping><description><![CDATA[
		<span class="span">作者：Javazealot<br /><br />1.String类和StringBuffer类 <br /><br />　　它们都是处理字符串的类,但是它们有一个最大的区别,那就是String对象是存储你不能改动的文本字符串,相反,如果你希望改动,则应使用StringBuffer类作为替换<br /><br /><br />　　eg1: <br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>...... <br />//omit some code <br />String s1="You are hired!"; <br />System.out.println(s1.replace(′h′,′f′));//用f把字串中的h替换了 <br />System.out.println(s1); <br />...... <br />//omit some code </td></tr></tbody></table><br />　　运行结果: <br /><br />　　　You are fired! <br />　　　You are hired! <br /><br />　　结果分析: <br /><br />　　从结果,明显可知,s1的值并没有被改变,而第一行结果只是屏幕内容的替换. <br /><br />　　eg2: <br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>...... <br />//omit some code <br />StringBuffer s2=new StringBuffer("Hello from Java!"); <br />s2.replace(6,10,"to"); <br />System.out.println(s2); <br />...... <br />//omit some code </td></tr></tbody></table><br />　　运行结果: <br /><br />　　Hello to Java! <br /><br />　　结果分析: <br /><br />　　显然,s2的值已改变. <br /><br />　<br />　　2.位逻辑与条件逻辑 <br /><br />　　首先声明, 为了与位逻辑更好区分开来,我把通常所说的逻辑取了个别名叫做条件逻辑. <br /><br />　　它们都有各自的操作符,位逻辑操作符有:&amp;<font color="#000000">amp</font>;(与运算),^(异或运算),|(或运算);条件逻辑操作符有:&amp;&amp;(并 <br />且),||(或者)。 <br /><br />　　位逻辑运算通常是针对两个数而言,实行位操作;而条件逻辑运算是针对两个条件表达式而言,实行条件操作.其实,位逻辑操作符一样可以实现条件操作,但是此时有一个重要的区别:用位操作符时,不管操作符两边的条件表达式成不成立,它都要通通进行运算判断,而条件逻辑操作符不一样了,如果通过左侧的操作数就可以进行它们需要的判断,那么它就不会再<font color="#000000">计算</font>右侧的操作数了,这种情况叫短路.废话少说!且看下例. <br /><br />　　eg1: <br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>...... <br />//omit some code <br /><font color="#000000">double</font> value=0; <br />if(value!=0 &amp;&amp; 1/value&lt;1000){ <br />System.out.println("The value is not too small."); <br />} <br />else{ <br />System.out.println("The value is too small."); <br />} <br />...... <br />//omit some code </td></tr></tbody></table><br />　　运行结果: <br /><br />　　The value is too small. <br /><br />　　结果分析: <br /><br />　　照理说应会出现除数为0的错误,但是我刚才说了,由于条件逻辑操作符是短路操作符,显然,value!=0不成立,立即就可作出判断应执行else后的语句,所以它就不再会运算判断1/value&lt;1000了.如果不懂请再看一 <br />例: <br /><br />　　 eg2: <br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>...... <br />//omit some code <br />double int1=0,int2=1,int3=1; <br />if(int1!=0 &amp; (int2=2)==1){} <br />System.out.println("int2="+int2); <br />if(int1!=0 &amp;&amp; (int3=2)==1){} <br />System.out.println("int3="+int3); <br />...... <br />//omit some code </td></tr></tbody></table><br />　　运行结果: <br /><br />　　　int2=2.0 <br />　　　int3=1.0 <br /><br />　　结果分析: <br /><br />　　我想不用我分析了,你应该懂了吧. <br /><br />　　3.实例变量与类变量 <br /><br />　　可以通过两种方法在类中存储数据───作为实例变量和类变量.实例变量是特定于对象的,如果你有两个对象(即一个类的两个实例),每一个对象中的实例变量<font color="#000000">独立</font>于另一个对象中的实例变量的;另一方面,两个对象的类变量均指向相同的数据,并因此面保存相同的值,换句话说,类变量被类中的所有对象共享.差点忘了,它们在形式上的区别,类变量在声明时比实例变量多一个static. <br /><br />　　eg: <br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>class data <br />{ <br />public int intdata=0;//显然,intdata在这儿是实例变量 <br />} <br />public class exam <br />{ <br />public static void main(String[] args) <br />{ <br />data a,b; <br />a=new data(); <br />b=new data(); <br />a.intdata=1; <br />System.out.println("b.indata="+b.intdata); <br />} <br />} </td></tr></tbody></table><br />　　运行结果: <br /><br />　　b.intdata=0 <br /><br />　　结果分析: <br /><br />　　可以看出,a.intdata的值虽然变了,但并没有影响b.intdata.但是如果在data类中声明intdata时,在其前面加上static就变成类变量了(即:public static int intdata=0;),则此时运行结果会变为: <br /><br />　　b.intdata=1 <br /><br />　　这次a.intdata值的改变可把b.intdata影响了,事实上,对象a和b的类变量均指向相同的数据,所有值一样,这就是类变量的作用。 <br /><br />4.实例方法,类方法,构造器方法 <br /><br />　　我们通常所说的方法系指实例方法,就像c语言中的函数一样,其具体方法我就不用说了,在这里我主要是用它来区分类方法和构造器方法.类方法与实例方法最大的区别是:在形式上类方法多一个static,在用法上, <br />不必创建对象就可直接调用类方法(而实例方法却一定要先创建对象,再通过对象调用)。<br /><br />　　eg: <br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>class add <br />{ <br />static int addem(int op1,int op2) <br />{ <br />return op1+op2; <br />} <br />} <br />public class xxf <br />{ <br />public static void main(String[] args) <br />{ <br />System.out.println("addem(2,2)="+add.addem(2,2)); <br />} //直接用类名作为对象调用类方法 <br />} </td></tr></tbody></table><br />　　注: 也可按通常的方法,即先创建对象,再调用方法,不过,这时static就无任何意义了。<br /><br />　　再说说构造器方法,它是用来初始化对象中的数据的一种方法,创建很容易,只需在类中加上一个与这个类同名的方法,不需要在前面加任何访问说明符或者返回类型,另外,构造器也一样可以向方法一样传递参数. <br /><br />　　eg: <br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>class data <br />{ <br />private String data1;//事先声明 <br /><br />data(String s) <br />{ <br />data1=s; /*通过接收数据来初始化变量.(注:不能在构造器内 <br />声明变量,事先在外就要声明.)*/ <br />} <br /><br />public String getdata() <br />{ <br />return data1; <br />} <br />} <br /><br />public class xxf <br />{ <br />public static void main(String[] args) <br />{ <br />System.out.println((new data("I love you")).getdata());/*通过传递参数调用构造器新建一 <br />个对象,再通过对象调用方法得到数据*/ <br />} <br />} <br /></td></tr></tbody></table><br />　　5.接口与类 <br /><br />　　类是对一类特定对象的规格说明,我们可以类定义创建对象,通过创建对象来组合所有属于该类的组件,而接口不能这样做.而接口实质上就是一个常量和抽象方法的集合,要使用一个接口,就需要在类中实现这个接口,然后作为类定义的一部分,编写接口中声明的每一个方法,接口中的方法永远是public,abstract,接口中的常量永远是public static和final,因此不需要为它们说明属性。<br /><br />　　因为在Java中不支持多重继承,但是,可以用接口来实现类似的功能,这是接口的重要作用之一。<br /><br />　　eg: <br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>interface anyone //定义一个接口 <br />{ <br />final double PI=3.1416; <br />void setNumber(int number); <br />int getNumber(); <br />} <br />interface anyother //定义另一个接口 <br />{ <br />void setString(String str); <br />String getString(); <br />} <br /><br />class xxf implement anyone,anyother //定义一个类,并使用两个接口 <br />{ <br />int number; <br />String str; <br />public xxf(){} <br />void setNumber(int number) <br />{ <br />this.number=number; <br />} <br />void setString(String str) <br />{ <br />this.str=str; <br />} <br />void int getNumber(){}//可以为一个空实现. <br />void String getString(){} <br />} <br />//在类中必须实现接口中声明的所有方法.(当然也可不必,但是要用到适配器类或用抽象类)</td></tr></tbody></table></span>
<img src ="http://www.blogjava.net/iKingQu/aggbug/36882.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-22 16:34 <a href="http://www.blogjava.net/iKingQu/articles/36882.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]Java的操作符</title><link>http://www.blogjava.net/iKingQu/articles/36881.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Wed, 22 Mar 2006 08:28:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/36881.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/36881.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/36881.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/36881.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/36881.html</trackback:ping><description><![CDATA[
		<strong>来源 </strong>：http://www.coderpub.com<br /><br /><p>根据操作对象的个数操作符可分为一元、二元或三元操作符。根据操作符的功能，又可分为算术、逻辑、关系等操作符。 </p><p><br />算术操作符 </p><p>一元： + - ++ -- <br />二元： + - * / % <br />值得注意的是 ++ 和-- 操作符， <br />如：int a，x=1，y=5； <br />a = ++x；b=y++； <br />此时a的值为2（先加1，后赋值），b的值为5（先赋值，后加1）。 <br />二元操作符两侧的操作对象数据类型不同时，先自动进行类型转换，再进行操作。 </p><p><br />赋值操作符与复合赋值操作符 <br />可将 变量 = 变量 op 表达式 <br />写成 变量 op = 表达式 <br />如：x+=20 与 x=x+20 结果一致，但更简洁。 <br />注意：= 与 = = 的不同。 </p><p><br />位操作符和移位操作符 </p><p>位操作符 <br />&amp;（按位与） |（按位或） ^（按位异或） <br />移位操作符 <br />E&lt;&lt;n 左移n位，空位补0，相当于E*2 <br />E&gt;&gt;n 右移n位，空位用原最高位的位值补足，相当于E/2 <br />E&gt;&gt;&gt;n 右移n位，空位补0 </p><p><br />关系操作符 <br />关系操作符共六个： <br />&gt;（大于） &gt;=（大于等于） &lt;（小于）&lt;=（小于等于） !=（不等于） = =（相等） <br />关系操作符的结果为boolean型数据（true或false）。 <br />注：= = 操作符只有在比较双方均完全一致时，其值为true，如比较的是两个对象，即使两个对象的内容相同，结果也为false，只有这两个对象为同一对象时才为true。 </p><p><br />逻辑操作符 <br />逻辑操作符的操作对象和结果均为boolean型，共六个： <br />！（逻辑非） &amp;&amp; （逻辑与） ||（逻辑或） <br />^（逻辑并或） &amp; （逻辑与） | （逻辑或） <br />按位与'&amp;'也可作为逻辑与使用，但未作优化，而'&amp;&amp;'操作符是经过优化的。对'|'操作符也类似。 </p><p><br />其他操作符 </p><p>条件操作符 E1?E2:E3 <br />表达式E1若成立，执行表达式E2，否则执行E3。 <br />逗号操作符 <br />","可用于分隔语句。 <br />如 int x,y; <br />for (x=0,y=0;x&lt;10;x++) {...}; </p><p><br />操作符的优先级和结合规则 <br />优先级： <br />一元 〉算术 〉移位 〉关系 〉按位 〉逻辑 〉三元 〉（复合）赋值 〉逗号 <br />结合规则： <br />除一元、三元和赋值操作符是自右至左结合外，其他均自左至右结合。</p><img src ="http://www.blogjava.net/iKingQu/aggbug/36881.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-22 16:28 <a href="http://www.blogjava.net/iKingQu/articles/36881.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]初学java的一个问题,java方法调用时,是传值还是传引用?</title><link>http://www.blogjava.net/iKingQu/articles/36765.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Tue, 21 Mar 2006 19:58:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/36765.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/36765.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/36765.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/36765.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/36765.html</trackback:ping><description><![CDATA[网上文章都说是传值,有文章如下说  <br />当你向一个方法传递一个对象时，Java没有把对象放入堆栈，它只是拷贝对象的引用然后将这个引用的拷贝放入堆栈。也就是说，根据定义，Java使用的是传值方式。  <br /> <br />可是我做试验,怎么觉得是传的引用呢  <br />代码如下  <br />Foo.java  <br />public  class  Foo  {  <br />           public  int  bar;  <br />}  <br /> <br />Test.java  <br />public  class  Test  {  <br />       public  static  void  main(String  []args)  {  <br />               Foo  f  =  new  Foo();  <br />               f.bar  =  5;  <br />               System.out.println("f.bar="  +  f.bar);  <br />               func(f);  <br />               System.out.println("f.bar="  +  f.bar);  <br />       }  <br /> <br />       public  static  void  func(Foo  p)  {  <br />               p.bar  =  6;  <br />       }  <br />}  <br /> <br />输出结果是  <br />f.bar=5  <br />f.bar=6  <br /> <br />对象在方法中被改变,这不是传引用的结果吗  <br />---------------------------------------------------------------  <br /> <br />基本对象传递的是值，这是毫无疑问的  <br />非基本对象传递的是引用，但这个引用本身是通过值传递来实现的  <br />例如：  <br />public  static  void  tripleSalary(Employee  x)  <br />{  <br />x.raiseSalary(100);  <br />}  <br />调用  <br />test=new  Employee(...);  <br />tripleSalary(test);  <br />将改变对象中的数据的值，因为此时test和x都指向相同的对象  <br />但是例如：  <br />public  static  void  swap(Employee  x，Employee  y)  <br />{  <br />Employee  temp=x;  <br />x=y;  <br />y=temp;  <br />}  <br />调用  <br />Employee  a=new  Employee(...);  <br />Employee  b=new  Employee(...);  <br />swap(a,b);  <br />是不会改变x,y指向的对象的，尽管a和x、b和y指向的是相同的对象，但a,b仅仅是x,y的拷贝  <br />这与c++中的引用a=&amp;x是不同的<br /><script language="JavaScript" src="http://www.csdn.net/common/footer_gb.js " type="text/javascript"></script><style><![CDATA[CFContent a:link {	color: #000;	text-decoration: none;}#CFContent a:visited {	color: #000;	text-decoration: none;}#CFContent a:hover {	color: #F00;	text-decoration: underline;}#CFContent a:active {	color: #000;	text-decoration: none;}	#CFBig {		width: 760px;		clear: both;		margin: auto;		font-family: Tahoma, sans-serif;		text-align: center;background-color: #FFF;	}		#CFBig #CFContent {		margin: auto;		width: 500px;		text-align: center;	}	#CFBig #CFContent p {		margin: 2px;font-size:9pt; 	}	#CFBig hr {		height: 1px;		color: #4682B4;	}	#CFBig #CFBiaoShi {		width: 40px;		float: right;	}	]]&gt;</style><img src ="http://www.blogjava.net/iKingQu/aggbug/36765.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-22 03:58 <a href="http://www.blogjava.net/iKingQu/articles/36765.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]写java程序最容易犯的21种错误 </title><link>http://www.blogjava.net/iKingQu/articles/36532.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Mon, 20 Mar 2006 17:00:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/36532.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/36532.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/36532.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/36532.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/36532.html</trackback:ping><description><![CDATA[
		<div class="postText">
				<p>1．Duplicated Code<br /><br />  代码重复几乎是最常见的异味了。他也是Refactoring 的主要目标之一。代码重复往往来自于copy-and-paste<br />的编程风格。与他相对应OAOO 是一个好系统的重要标志（请参见：<a href="http://www.erptao.org/download.php?op=viewsdownload&amp;sid=6"><font color="#002c99">http://www.erptao.org/download.php?op=viewsdownload&amp;sid=6</font></a>）。<br /><br /><br />2．Long method<br /><br />  它是传统结构化的“遗毒“。一个方法应当具有自我独立的意图，不要把几个意图放在一起，我的《大类和长方法》一文中有详细描述。<br /><br /><br />3．Large Class<br /><br />  大类就是你把太多的责任交给了一个类。这里的规则是One Class One Responsibility。<br /><br />4．Divergent Change<br /><br />   一个类里面的内容变化率不同。某些状态一个小时变一次，某些则几个月一年才变一次；某些状态因为这方面的原因发生变化，而另一些则因为其他方面的原因变一次。面向对象的抽象就是把相对不变的和相对变化相隔离。把问题变化的一方面和另一方面相隔离。这使得这些相对不变的可以重用。问题变化的每个方面都可以单独重用。这种相异变化的共存使得重用非常困难。<br /><br /><br />5．Shotgun Surgery<br /><br />  这正好和上面相反。对系统一个地方的改变涉及到其他许多地方的相关改变。这些变化率和变化内容相似的状态和行为通常应当放在同一个类中。<br /><br /><br />6．Feature Envy<br /><br />  对象的目的就是封装状态以及与这些状态紧密相关的行为。如果一个类的方法频繁用get 方法存取其他类的状态进行计算，那么你要考虑把行为移到涉及状态数目最多的那个类。<br /><br /><br />7．Data Clumps<br /><br />  某些数据通常像孩子一样成群玩耍：一起出现在很多类的成员变量中，一起出现在许多方法的参数中…..，这些数据或许应该自己独立形成对象。<br /><br /><br />8．Primitive Obsession<br /><br />  面向对象的新手通常习惯使用几个原始类型的数据来表示一个概念。譬如对于范围，他们会使用两个数字。对于Money，他们会用一个浮点数来表示。因为你没有使用对象来表达问题中存在的概念，这使得代码变的难以理解，解决问题的难度大大增加。<br />好的习惯是扩充语言所能提供原始类型，用小对象来表示范围、金额、转化率、邮政编码等等。<br /><br /><br />9．Switch Statement<br /><br />  基于常量的开关语句是OO 的大敌，你应当把他变为子类、state 或strategy。<br /><br /><br />10． Parallel Inheritance Hierarchies<br /><br />  并行的继承层次是shotgun surgery 的特殊情况。因为当你改变一个层次中的某一个类时，你必须同时改变另外一个层次的并行子类。<br /><br /><br />11． Lazy Class<br /><br />  一个干活不多的类。类的维护需要额外的开销，如果一个类承担了太少的责任，应当消除它。<br /><br /><br />12． Speculative Generality<br /><br />  一个类实现了从未用到的功能和通用性。通常这样的类或方法唯一的用户是testcase。不要犹豫，删除它。<br /><br /><br />13． Temporary Field<br /><br />  一个对象的属性可能只在某些情况下才有意义。这样的代码将难以理解。专门建立一个对象来持有这样的孤儿属性，把只和他相关的行为移到该类。最常见的是一个特定的算法需要某些只有该算法才有用的变量。<br /><br /><br />14． Message Chain<br /><br />  消息链发生于当一个客户向一个对象要求另一个对象，然后客户又向这另一对象要求另一个对象，再向这另一个对象要求另一个对象，如此如此。这时，你需要隐藏分派。<br /><br /><br />15． Middle Man<br /><br />  对象的基本特性之一就是封装，而你经常会通过分派去实现封装。但是这一步不能走得太远，如果你发现一个类接口的一大半方法都在做分派，你可能需要移去这个中间<br />人。<br /><br /><br />16． Inappropriate Intimacy<br /><br />  某些类相互之间太亲密，它们花费了太多的时间去砖研别人的私有部分。对人类而言，我们也许不应该太假正经，但我们应当让自己的类严格遵守禁欲主义。<br /><br /><br />17． Alternative Classes with Different Interfaces<br /><br />  做相同事情的方法有不同的函数signature，一致把它们往类层次上移，直至协议一致。<br /><br /><br />18． Incomplete Library Class<br /><br />   要建立一个好的类库非常困难。我们大量的程序工作都基于类库实现。然而，如此广泛而又相异的目标对库构建者提出了苛刻的要求。库构建者也不是万能的。有时候我们会发现库类无法实现我们需要的功能。而直接对库类的修改有非常困难。这时候就需要用各种手段进行Refactoring。<br /><br /><br />19． Data Class<br /><br />  对象包括状态和行为。如果一个类只有状态没有行为，那么肯定有什么地方出问题了。<br /><br /><br />20． Refused Bequest<br /><br />  超类传下来很多行为和状态，而子类只是用了其中的很小一部分。这通常意味着你的类层次有问题。<br /><br /><br />21． Comments<br /><br />  经常觉得要写很多注释表示你的代码难以理解。如果这种感觉太多，表示你需要Refactoring。 </p>
				<br />
				<br />
				<p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=558312</p>
		</div>
<img src ="http://www.blogjava.net/iKingQu/aggbug/36532.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-21 01:00 <a href="http://www.blogjava.net/iKingQu/articles/36532.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]关键字new和newInstance方法区别 </title><link>http://www.blogjava.net/iKingQu/articles/36530.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Mon, 20 Mar 2006 16:58:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/36530.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/36530.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/36530.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/36530.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/36530.html</trackback:ping><description><![CDATA[
		<div class="postText">在初始化一个类，生成一个实例的时候，newInstance()方法和new关键字除了一个是方法，一个是关键字外，最主要有什么区别？它们的区别在于创建对象的方式不一样，前者是使用类加载机制，后者是创建一个新类。那么为什么会有两种创建对象方式？这主要考虑到软件的可伸缩、可扩展和可重用等软件设计思想。 <br /><br />    Java中工厂模式经常使用newInstance()方法来创建对象，因此从为什么要使用工厂模式上可以找到具体答案。 例如：<br />    class c = Class.forName(“Example”);<br />    factory = (ExampleInterface)c.newInstance(); <br /><br />    其中ExampleInterface是Example的接口，可以写成如下形式： <br />    String className = "Example";<br />    class c = Class.forName(className);<br />    factory = (ExampleInterface)c.newInstance();<br /><br />    进一步可以写成如下形式：<br />    String className = readfromXMlConfig;//从xml 配置文件中获得字符串<br />    class c = Class.forName(className);<br />    factory = (ExampleInterface)c.newInstance();<br /><br />    上面代码已经不存在Example的类名称，它的优点是，无论Example类怎么变化，上述代码不变，甚至可以更换Example的兄弟类Example2 , Example3 , Example4……，只要他们继承ExampleInterface就可以。<br /><br />    从JVM的角度看，我们使用关键字new创建一个类的时候，这个类可以没有被加载。但是使用newInstance()方法的时候，就必须保证：1、这个类已经加载；2、这个类已经连接了。而完成上面两个步骤的正是Class的静态方法forName()所完成的，这个静态方法调用了启动类加载器，即加载java API的那个加载器。<br /><br />    现在可以看出，newInstance()实际上是把new这个方式分解为两步，即首先调用Class加载方法加载某个类，然后实例化。 这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性，提供给了一种降耦的手段。<br /><br />    最后用最简单的描述来区分new关键字和newInstance()方法的区别：<br />    newInstance: 弱类型。低效率。只能调用无参构造。 <br />    new: 强类型。相对高效。能调用任何public构造。<br /><br /><br /><p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=558946</p></div>
<img src ="http://www.blogjava.net/iKingQu/aggbug/36530.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-21 00:58 <a href="http://www.blogjava.net/iKingQu/articles/36530.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]package与import的区别与联系</title><link>http://www.blogjava.net/iKingQu/articles/36529.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Mon, 20 Mar 2006 16:57:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/36529.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/36529.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/36529.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/36529.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/36529.html</trackback:ping><description><![CDATA[
		<div class="postText">
				<p>我只是一个java菜鸟，对package与import的理解还不是很透彻，刚刚翻了一些资料查了一下，终于请出了，写出来给大家看看，不对的地方请批评指正！</p>
				<p>我们在写代码的时候，通常会这么写</p>
				<p>package com.companyname.classname;</p>
				<p>import java.lang.String;</p>
				<p>ok，在现实生活中，我们会有很多朋友，每个朋友都有自己的名字，刘德华、张学友、欧阳震华（我认识他他不认识我，哈哈～），我们互相称呼的时候，有时候会叫全名，比如“刘德华，明天请我吃饭啊”，或者“学友，下一场演唱会在那里开啊”。</p>
				<p>同理，package就是类的姓名。让我们看看上面的语句－“package com.companyname.classname;”，当然我们也可以写成“package companyname.classname;”。package中有“.”，那么在这里“com.companyname”或者“companyname”就是姓，或者可以这么理解，“com.companyname”是复姓，“companyname”是单姓。</p>
				<p>在JAVA中，我们可以随意定义package，这样子就不会发生冲突。</p>
				<p>那么import呢？刚才也说了，我们和朋友互相称呼的时候，可以呼其全名，也可以省去姓名。来看看这段代码：<br />java.lang.StringBuffer myBuffer = new java.lang.StringBuffer("213");在这里，我们就称StringBuffer这个类的全名java.lang.StringBuffer，但是每次都这么写是不是很累而且很麻烦啊，没错，你想到了，sun也想到了，该import闪亮登场了。我们可以在代码头部写上"import java.lang.String;"，那刚才的那段代码就可以写成<br />StringBuffer myBuffer = new StringBuffer("213");为什么呢？因为import已经告诉编译器StringBuffer 是姓java.lang.的。</p>
				<p>当然也存在刘德华，马德华、张德华，这个时候如果你只是说“德华，你过来一下”，那他们就不知道到底是叫谁了（在java中编译器就报错了）</p>
				<br />
				<br />
				<p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=561187</p>
		</div>
<img src ="http://www.blogjava.net/iKingQu/aggbug/36529.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-21 00:57 <a href="http://www.blogjava.net/iKingQu/articles/36529.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]初识JAVA内部类</title><link>http://www.blogjava.net/iKingQu/articles/35335.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Tue, 14 Mar 2006 18:34:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/35335.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/35335.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/35335.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/35335.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/35335.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">初识</SPAN><SPAN lang=EN-US>JAVA</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内部类</SPAN><SPAN lang=EN-US><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">提起</SPAN><SPAN lang=EN-US>Java</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内部类（</SPAN><SPAN lang=EN-US>Inner Class</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）可能很多人不太熟悉，实际上类似的概念在</SPAN><SPAN lang=EN-US>C++</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">里也有，那就是嵌套类（</SPAN><SPAN lang=EN-US>Nested Class</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">），关于这两者的区别与联系，在下文中会有对比。内部类从表面上看，就是在类中又定义了一个类（下文会看到，内部类可以在很多地方定义），而实际上并没有那么简单，乍看上去内部类似乎有些多余，它的用处对于初学者来说可能并不是那么显著，但是随着对它的深入了解，你会发现</SPAN><SPAN lang=EN-US>Java</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的设计者在内部类身上的确是用心良苦。学会使用内部类，是掌握</SPAN><SPAN lang=EN-US>Java</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">高级编程的一部分，它可以让你更优雅地设计你的程序结构。下面从以下几个方面来介绍：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">第一次见面</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public interface Contents {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>int value();</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public interface Destination {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>String readLabel();</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public class Goods {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>private class Content implements Contents {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>private int i = 11;</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public int value() { </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>return i; </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>protected class GDestination implements Destination {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>private String label;</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>private GDestination(String whereTo) {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>label = whereTo;</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public String readLabel() { </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>return label; </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public Destination dest(String s) {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>return new GDestination(s);</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public Contents cont() {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>return new Content();</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>class TestGoods {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public static void main(String[] args) {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>Goods p = new Goods();</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>Contents c = p.cont();</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>Destination d = p.dest("<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><st1:place w:st="on"><st1:City w:st="on">Beijing</st1:City></st1:place>");</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>} </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在这个例子里类</SPAN><SPAN lang=EN-US>Content</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US>GDestination</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">被定义在了类</SPAN><SPAN lang=EN-US>Goods</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内部，并且分别有着</SPAN><SPAN lang=EN-US>protected</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US>private</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">修饰符来控制访问级别。</SPAN><SPAN lang=EN-US>Content</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">代表着</SPAN><SPAN lang=EN-US>Goods</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的内容，而</SPAN><SPAN lang=EN-US>GDestination</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">代表着</SPAN><SPAN lang=EN-US>Goods</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的目的地。它们分别实现了两个接口</SPAN><SPAN lang=EN-US>Content</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US>Destination</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。在后面的</SPAN><SPAN lang=EN-US>main</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法里，直接用</SPAN><SPAN lang=EN-US> Contents c</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US>Destination d</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进行操作，你甚至连这两个内部类的名字都没有看见！这样，内部类的第一个好处就体现出来了——隐藏你不想让别人知道的操作，也即封装性。</SPAN> </P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">同时，我们也发现了在外部类作用范围之外得到内部类对象的第一个方法，那就是利用其外部类的方法创建并返回。上例中的</SPAN><SPAN lang=EN-US>cont()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US>dest()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法就是这么做的。那么还有没有别的方法呢？当然有，其语法格式如下：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>outerObject=new outerClass(Constructor Parameters);</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>outerClass.innerClass innerObject=outerObject.new InnerClass(Constructor Parameters);</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">注意在创建非静态内部类对象时，一定要先创建起相应的外部类对象。至于原因，也就引出了我们下一个话题——</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">非静态内部类对象有着指向其外部类对象的引用</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对刚才的例子稍作修改：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public class Goods {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>private valueRate=2;</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>private class Content implements Contents {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>private int i = 11*valueRate;</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public int value() { </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>return i; </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>protected class GDestination implements Destination {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>private String label;</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>private GDestination(String whereTo) {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>label = whereTo;</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public String readLabel() { </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>return label; </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public Destination dest(String s) {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>return new GDestination(s);</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public Contents cont() {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>return new Content();</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">修改的部分用蓝色显示了。在这里我们给</SPAN><SPAN lang=EN-US>Goods</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类增加了一个</SPAN><SPAN lang=EN-US>private</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">成员变量</SPAN><SPAN lang=EN-US>valueRate</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，意义是货物的价值系数，在内部类</SPAN><SPAN lang=EN-US>Content</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的方法</SPAN><SPAN lang=EN-US>value()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">计算价值时把它乘上。我们发现，</SPAN><SPAN lang=EN-US>value()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以访问</SPAN><SPAN lang=EN-US>valueRate</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，这也是内部类的第二个好处——一个内部类对象可以访问创建它的外部类对象的内容，甚至包括私有变量！这是一个非常有用的特性，为我们在设计时提供了更多的思路和捷径。要想实现这个功能，内部类对象就必须有指向外部类对象的引用。</SPAN><SPAN lang=EN-US>Java</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">编译器在创建内部类对象时，隐式的把其外部类对象的引用也传了进去并一直保存着。这样就使得内部类对象始终可以访问其外部类对象，同时这也是为什么在外部类作用范围之外向要创建内部类对象必须先创建其外部类对象的原因。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有人会问，如果内部类里的一个成员变量与外部类的一个成员变量同名，也即外部类的同名成员变量被屏蔽了，怎么办？没事，</SPAN><SPAN lang=EN-US>Java</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">里用如下格式表达外部类的引用：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>outerClass.this </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有了它，我们就不怕这种屏蔽的情况了。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">静态内部类</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和普通的类一样，内部类也可以有静态的。不过和非静态内部类相比，区别就在于静态内部类没有了指向外部的引用。这实际上和</SPAN><SPAN lang=EN-US>C++</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的嵌套类很相像了，</SPAN><SPAN lang=EN-US>Java</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内部类与</SPAN><SPAN lang=EN-US>C++</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">嵌套类最大的不同就在于是否有指向外部的引用这一点上，当然从设计的角度以及以它一些细节来讲还有区别。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">除此之外，在任何非静态内部类中，都不能有静态数据，静态方法或者又一个静态内部类（内部类的嵌套可以不止一层）。不过静态内部类中却可以拥有这一切。这也算是两者的第二个区别吧。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">局部内部类</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是的，</SPAN><SPAN lang=EN-US>Java</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内部类也可以是局部的，它可以定义在一个方法甚至一个代码块之内。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public class Goods1 {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public Destination dest(String s) {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>class GDestination implements Destination {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>private String label;</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>private GDestination(String whereTo) {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>label = whereTo;</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public String readLabel() { return label; }</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>return new GDestination(s);</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public static void main(String[] args) {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>Goods1 g= new Goods1();</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>Destination d = g.dest("<st1:place w:st="on"><st1:City w:st="on">Beijing</st1:City></st1:place>");</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">上面就是这样一个例子。在方法</SPAN><SPAN lang=EN-US>dest</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中我们定义了一个内部类，最后由这个方法返回这个内部类的对象。如果我们在用一个内部类的时候仅需要创建它的一个对象并创给外部，就可以这样做。当然，定义在方法中的内部类可以使设计多样化，用途绝不仅仅在这一点。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下面有一个更怪的例子：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public class Goods2{</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>private void internalTracking(boolean b) {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>if(b) {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>class TrackingSlip {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>private String id;</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>TrackingSlip(String s) {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>id = s;</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>String getSlip() { return id; }</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>TrackingSlip ts = new TrackingSlip("slip");</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>String s = ts.getSlip();</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>} </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public void track() { internalTracking(true); }</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public static void main(String[] args) {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>Goods2 g= new Goods2();</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>g.track();</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">你不能在</SPAN><SPAN lang=EN-US>if</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">之外创建这个内部类的对象，因为这已经超出了它的作用域。不过在编译的时候，内部类</SPAN><SPAN lang=EN-US>TrackingSlip</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和其他类一样同时被编译，只不过它由它自己的作用域，超出了这个范围就无效，除此之外它和其他内部类并没有区别。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">匿名内部类</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>java</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的匿名内部类的语法规则看上去有些古怪，不过如同匿名数组一样，当你只需要创建一个类的对象而且用不上它的名字时，使用内部类可以使代码看上去简洁清楚。它的语法规则是这样的：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>new interfacename(){......}; </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</SPAN><SPAN lang=EN-US> new superclassname(){......}; </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下面接着前面继续举例子：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public class Goods3 {</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public Contents cont(){</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>return new Contents(){</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>private int i = 11;</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public int value() { </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>return i; </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>};</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>} </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这里方法</SPAN><SPAN lang=EN-US>cont()</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用匿名内部类直接返回了一个实现了接口</SPAN><SPAN lang=EN-US>Contents</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的类的对象，看上去的确十分简洁。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</SPAN><SPAN lang=EN-US>java</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的事件处理的匿名适配器中，匿名内部类被大量的使用。例如在想关闭窗口时加上这样一句代码：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>frame.addWindowListener(new WindowAdapter(){</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>public void windowClosing(WindowEvent e){</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>System.exit(0); </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>}); </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有一点需要注意的是，匿名内部类由于没有名字，所以它没有构造函数（但是如果这个匿名内部类继承了一个只含有带参数构造函数的父类，创建它的时候必须带上这些参数，并在实现的过程中使用</SPAN><SPAN lang=EN-US>super</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">关键字调用相应的内容）。如果你想要初始化它的成员变量，有下面几种方法：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果是在一个方法的匿名内部类，可以利用这个方法传进你想要的参数，不过记住，这些参数必须被声明为</SPAN><SPAN lang=EN-US>final</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将匿名内部类改造成有名字的局部内部类，这样它就可以拥有构造函数了。</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在这个匿名内部类中使用初始化代码块。</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为什么需要内部类？</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>java</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内部类有什么好处？为什么需要内部类？</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">首先举一个简单的例子，如果你想实现一个接口，但是这个接口中的一个方法和你构想的这个类中的一个方法的名称，参数相同，你应该怎么办？这时候，你可以建一个内部类实现这个接口。由于内部类对外部类的所有内容都是可访问的，所以这样做可以完成所有你直接实现这个接口的功能。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不过你可能要质疑，更改一下方法的不就行了吗？</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的确，以此作为设计内部类的理由，实在没有说服力。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">真正的原因是这样的，</SPAN><SPAN lang=EN-US>java</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的内部类和接口加在一起，可以的解决常被</SPAN><SPAN lang=EN-US>C++</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">程序员抱怨</SPAN><SPAN lang=EN-US>java</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中存在的一个问题——没有多继承。实际上，</SPAN><SPAN lang=EN-US>C++</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的多继承设计起来很复杂，而</SPAN><SPAN lang=EN-US>java</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通过内部类加上接口，可以很好的实现多继承的效果。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">本文的目的只是向大家介绍一下内部类的概念以及使用方法，在后续文章里，将会针对本文中的内容举更多具体的例子，以及介绍如何使用内部类构建一个</SPAN><SPAN lang=EN-US>Applicaton Framework</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN></P><img src ="http://www.blogjava.net/iKingQu/aggbug/35335.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-15 02:34 <a href="http://www.blogjava.net/iKingQu/articles/35335.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]JDK5.0的11个主要新特征</title><link>http://www.blogjava.net/iKingQu/articles/33953.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Mon, 06 Mar 2006 16:09:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/33953.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/33953.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/33953.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/33953.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/33953.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: JDK5.0的11个主要新特征转自 kmlzkma 的 Blog  														1           泛型				(Generic)														1.1          说明																												增强了				java				的类型安全，可以在编译期间对容器内...&nbsp;&nbsp;<a href='http://www.blogjava.net/iKingQu/articles/33953.html'>阅读全文</a><img src ="http://www.blogjava.net/iKingQu/aggbug/33953.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-07 00:09 <a href="http://www.blogjava.net/iKingQu/articles/33953.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]Java入门与加深FAQ</title><link>http://www.blogjava.net/iKingQu/articles/33943.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Mon, 06 Mar 2006 15:13:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/33943.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/33943.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/33943.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/33943.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/33943.html</trackback:ping><description><![CDATA[<STRONG><FONT size=6>Java入门与加深FAQ<BR></FONT><BR><BR><FONT size=5>一、准备篇<BR><BR>1</FONT></STRONG><FONT size=5> 什么是Java、Java2、JDK？JDK后面的1.3、1.4.2版本号又是怎么回事？<BR>　答：Java是一种通用的，并发的，强类型的，面向对象的编程语言（摘自Java规范第二版) JDK是Sun公司分发的免费Java开发工具，正式名称为J2SDK(Java2 Software Develop Kit)。<BR><BR><STRONG>2</STRONG> 什么是JRE/J2RE？<BR>　答：J2RE是Java2 Runtime Environment，即Java运行环境，有时简称JRE。如果你只需要运行Java程序或Applet，下载并安装它即可。如果你要自行开发Java软件，请下载JDK。在JDK中附带有J2RE。<BR>注意:由于Microsoft对Java的支持不完全，请不要使用IE自带的虚拟机来运行Applet，务必安装一个J2RE或JDK。<BR><BR><STRONG>3</STRONG> 学习Java用什么工具比较好？<BR>　答：作者建议首先使用JDK+文本编辑器，这有助你理解下列几个基础概念：path，classpath，package并熟悉基本命令：javac和java。并且下载和你的JDK版本一致的API帮助。<BR><BR>　如果你不确定类或函数的用法，请先查阅API而不是发贴求助。当你熟悉Java之后，你可以考虑换一个IDE。很多人推荐JCreator，实际上JCreator的功能还 是很弱的。作者推荐eclipse，下载网</FONT><A href="http://www.eclipse.org/"><FONT size=5>http://www.eclipse.org</FONT></A><FONT size=5>因eclispe是免费的.<BR><BR><STRONG>4</STRONG> 学习Java有哪些好的参考书？<BR>　答：作者首先推荐Thinking in Java，中文名《Java编程思想》，有中文版。该书第一章介绍了很多面向对象的编程思想，作为新手应当认真阅读。除此以外，O´relly出版社和Wrox出版社的书也不错。作者本人不喜欢大陆作者的书。也许你觉得英文太难，但是网上大多数资料都是英文的。另外，你需要经常查阅API，而那也是英文的。<BR><BR><STRONG>5</STRONG> Java和C++哪个更好？<BR>　答：这个问题是一个很不恰当的问题。你应该问：Java和C++哪个更适用于我的项目？如果你不需要跨平台，不需要分布式，要强调程序的运行速度，C++更为适用。反之?你应当考虑Java。<BR><BR><STRONG>6</STRONG> 什么是J2SE/J2EE/J2ME？<BR>　答：J2SE就是一般的Java。<BR>　J2ME是针对嵌入式设备的，比如Java手机，它有自己的SDK。而J2EE使用J2SE的SDK。<BR>　J2EE规范更多的是对J2EE服务器的要求和开发人员的约束。详情见后继"J2EE FAQ"。<BR><BR><BR><STRONG>二、命令篇</STRONG><BR><BR><STRONG>7</STRONG> 我写了第一个Java程序，应该如何编译/运行？<BR>　答：首先请将程序保存为xxx.java文件，然后在dos窗口下使用javac xxx.java命令，你会发现该目录下多了一个xxx.class文件，再使用java xxx命令，你的java程序就开始运行了。<BR><BR><STRONG>8</STRONG> 我照你说的做了，但是出现什么"´javac´ 不是内部或外部命令，也不是可运行的程序或批处理文件。"。<BR>　答：你遇到了path问题。操作系统在一定的范围(path)内搜索javac.exe，但是没能找到。请编辑你的操作系统环境变量，新增一个JAVA_HOME变量，设为你JDK的安装目录，再编辑Path变量，加上一项 %JAVA_HOME%\bin。然后关掉并新开一个dos窗口，你就可以使用javac和java命令了。<BR><BR><STRONG>9</STRONG> 环境变量怎么设置？<BR>　答：请向身边会设的人咨询。<BR><BR><STRONG>10</STRONG> javac xxx.java顺利通过了，但是java xxx的时候显示什么“NoClassDefFoundError”。<BR>　答：你遇到了classpath问题。java命令在一定的范围(classpath)内搜索你要用的class文件，但是未能找到。首先请确认你没有错敲成java xxx.class，其实你并不需要设置该变量，但如果你设置了该变量又没有包含.（代表当前目录）的项，你就会遇到这个问题。请在你的CLASSPATH环境变量中加入一项. 或干脆删掉这个变量。如果你使用了并非JDK自带的标准包，比如javax.servlet.*包，也会遇到这个问题，请将相应的jar文件加入classpath。如果你在java源文件中定义了package，请参见15。<BR><BR><BR><STRONG>11</STRONG> 我在java xxx的时候显示"Exception in thread "main" java.lang.NoSuchMethodError: main"。<BR>　答：首先，在你的程序中每个java文件有且只能有一个public类，这个类的类名必须和文件名的大小写完全一样。其次，在你要运行的类中有且只能有一个public static void main(String[] args)方法，这个方法就是你的主程序。<BR><BR><STRONG>12</STRONG> package是什么意思？怎么用？<BR>　答：为了唯一标识每个类并分组，java使用了package的概念。每个类都有一个全名，例如String的全名是java.lang.String，其中java.lang是包名，String是短名。这样，如果你也定义了String，你可以把它放在mypackage中，通过使用全名mypackage.String和java.lang.String来区分这两个类。同时，将逻辑上相关的类放在同一个包中，可以使程序结构更为清楚。<BR><BR>　你要做的就是在java文件开头加一行"package mypackage;"。注意包没有嵌套或包含关系，A包和A.B包对java命令来说是并列的两个包。<BR><BR><STRONG>13</STRONG> 我没有声明任何package会怎么样？<BR>　答：你的类被认为放在默认包中。这时全名和短名是一致的。<BR><BR><STRONG>14</STRONG> 在一个类中怎么使用其他类？<BR>　答：如果你使用java.lang包中的类，不用做任何事。如果你使用其他包中的类，使用import package1.class1; 或 import package2.*;这里.*表示引入这个包中的所有类。然后在程序中你可以使用其他类的短名。如果短名有冲突，使用全名来区分。<BR><BR><STRONG>15</STRONG> 我用了package的时候显示"NoClassDefFoundError"，但是我把所有package去掉的时候能正常运行。<BR>　答：将你的java文件按包名存放。<BR>　比如你的工作目录是/work，你的类是package1.class1，那么将它存放为/work/package1/class1.java。如果没有声明包，那么直接放在/work下。在/work下执行javac package1/class1.java，再执行java package1.class1，你会发现一切正常。另外，你可以考虑开始使用IDE。<BR><BR><STRONG>16</STRONG> 我想把java编译成exe文件，该怎么做？<BR>　答：JDK只能将java源文件编译为class文件。class文件是一种跨平台的字节码，必须依赖平台相关的JRE来运行。Java以此来实现跨平台，有些开发工具可以将java文件编译为exe文件。作者反对这种做法，因为这样就取消了跨平台性。如果你确信你的软件只在Windows平台上运行，你可以考虑使用C++/C#来编程。<BR><BR><STRONG>17</STRONG> 我在编译的时候遇到什么"deprecated API"，是什么意思？<BR>　答：所谓deprecated是指已经?时，但是为了向前兼容起见仍然保留的方法，这些方法可能会在以后取消支持。你应当改用较新的方法。一般在API里面会说明你应当用什么方法来代替之。<BR><BR><BR><STRONG>三、I/O篇</STRONG><BR><BR><STRONG>18</STRONG> 我怎么给java程序加启动参数，就像dir /p/w那样？<BR>　答：还记得public static void main(String[] args)吗？这里的args就是你的启动参数。<BR>　在运行时你输入java package1.class1 -arg1 -arg2，args中就会有两个String，一个是arg1，另一个是arg2。<BR><BR><STRONG>19</STRONG> 我怎么从键盘输入一个int/double/字符串？<BR>　答：java的I/O操作比C++要复杂一点。如果要从键盘输入，样例代码如下：<BR>&nbsp;&nbsp;&nbsp;BufferedReader cin = new BufferedReader( new InputStreamReader( System.in ) )<BR>　;<BR>　String s = cin.readLine();<BR>　这样你就获得了一个字符串，如果你需要数字的话再加上：<BR>　int n = Integer.parseInt( s );<BR>　或者&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;double d = Double.parseDouble( s );<BR><BR><STRONG>20</STRONG> 我怎么输出一个int/double/字符串？<BR>　答：在程序开始写：<BR>　PrintWriter cout = new PrintWriter( System.out );<BR>　需要时写：<BR>　cout.print(n); <BR>　或者<BR>　cout.println("hello")<BR><BR>　等等。<BR><BR><STRONG>21</STRONG> 我发现有些书上直接用System.in和System.out输入输出，比你要简单得多。<BR>　答：java使用unicode，是双字节。而System.in和System.out是单字节的stream。如果你要输入输出双字节文字比如中文，请使用作者的做法。<BR><BR><STRONG>22</STRONG> 我怎么从文件输入一个int/double/字符串？<BR>　答：类似于从键盘输入，只不过换成<BR>　BufferedReader fin = new BufferedReader( new FileReader(" myFileName " ) );<BR>　PrintWriter fout = new PrintWriter( new FileWriter(" myFileName " ) );<BR>　另外如果你还没下载API，请开始下载并阅读java.io包中的内容。<BR><BR><STRONG>23</STRONG> 我想读写文件的指定位置，该怎么办？<BR>　答：你肯定没有认真看API。java.io.RandomAccessFile可以满足你的需要。<BR><BR><STRONG>24</STRONG> 怎么判断要读的文件已经到了尽头？<BR>　答：你肯定没有认真看API。在Reaer的read方法中明确说明返回-1表示流的结尾。<BR><BR><BR><STRONG>四、 关键字篇</STRONG><BR><BR><STRONG>25</STRONG> java里面怎么定义宏？<BR>　答：java不支持宏，因为宏代换不能保证类型安全。如果你需要定义常量，可以将它定义为某个类的static final成员。参见26和30。<BR><BR><STRONG>26</STRONG> java里面没法用const。<BR>　答：你可以用final关键字。例如 final int m = 9。被声明为final的变量不能被再次赋值。也可以用于声明方法或类，被声明为final的方法或类不能被继承。注意const是java的保留字以备扩充。<BR><BR><STRONG>27</STRONG> java里面也不能用goto。<BR>　答：甚至在面向过程的语言中你也可以完全不用goto。请检查你的程序流程是否合理。如果你需要从多层循环中迅速跳出，java增强了（和C++相比）break和continue的功能。<BR>　例如：<BR>　outer :<BR>　while( ... )<BR>　{<BR>　inner :<BR>　for( ... )<BR>　{<BR>　... break inner; ...<BR>　... continue outer; ...<BR>　}<BR>　}<BR><BR>　和const一样，goto也是java的保留字以备扩充。<BR><BR><STRONG>28</STRONG> java里面能不能重载操作符？<BR>　答：不能。String的+号是唯一一个内置的重载操作符。你可以通过定义接口和方法来实现类似功能。<BR><BR><STRONG>29</STRONG> 我new了一个对象，但是没法delete掉它。<BR>　答：java有自动内存回收机制，即所谓Garbarge Collector。你再也不用担心指针错误。<BR><BR><STRONG>30</STRONG> 我想知道为什么main方法必须被声明为public static？<BR>　答：声明为public是为了这个方法可以被外部调用，详情见面向对象篇37。<BR>　static是为了将某个成员变量/方法关联到类（class）而非实例（instance）。你不需要创建一个对象就可以直接使用这个类的static成员，在A类中调用B类的static成员可以使用B.staticMember的写法。注意一个类的static成员变量是唯一的，被所有该类对象所共享的。<BR><BR><STRONG>31</STRONG> throw和throws有什么不同？<BR>　答：throws用于声明一个方法会抛出哪些异常。而throw是在方法体中实际执行抛出异常的动作。如果你在方法中throw一个异常，却没有在方法声明中声明之，编译器会报错。注意Error和RuntimeException的子类是例外，无需特别声明。<BR><BR><STRONG>32</STRONG> 什么是异常？<BR>　答：异常最早在Ada语言中引入，用于在程序中动态处理错误并恢复。你可以在方法中拦截底层异常并处理之，也可以抛给更高层的模块去处理。你也可以抛出自己的异常指示发生了某些不正常情况。常见的拦截处理代码如下：<BR>　try<BR>　{<BR>　...... //以下是可能发生异常的代码<BR>　...... //异常被抛出，执行流程中断并转向拦截代码。<BR>　......<BR>　}<BR>　catch(Exception1 e) //如果Exception1是Exception2的子类并要做特别处理，应排在前面<BR>　{<BR>　//发生Exception1时被该段拦截<BR>　}<BR>　catch(Exception2 e)<BR>　{<BR>　//发生Exception2时被该段拦截<BR>　}<BR>　finally //这是可选的<BR>　{<BR>　//无论异常是否发生，均执行此段代码<BR>　}<BR><BR><STRONG>33</STRONG> final和finally有什么不同？<BR>　答：final请见26。finally用于异常机制，参见32。<BR><BR><BR><STRONG>五、 面向对象篇</STRONG><BR><BR><STRONG>34</STRONG> extends和implements有什么不同？<BR>　答：extends用于（单）继承一个类（class），而implements用于实现一个接口（interface）。interface的引入是为了部分地提供多继承的功能。<BR>在interface中只需声明方法头，而将方法体留给实现的class来做。这些实现的class的实例完全可以当作interface的实例来对待。有趣的是在interface之间也可以声明为extends（单继承）的关系。<BR><BR><STRONG>35</STRONG> java怎么实现多继承？<BR>　答：java不支持显式的多继承。因为在显式多继承的语言例如c++中，会出现子类被迫声明祖先虚基类构造函数的问题，而这是违反面向对象的封装性原则的。java提供了interface和implements关键字来部分地实现多继承。参见34。<BR><BR><STRONG>36</STRONG> abstract是什么？<BR>　答：被声明为abstract的方法无需给出方法体，留给子类来实现。而如果一个类中有abstract方法，那么这个类也必须声明为abstract。被声明为abstract的类无法实例化，尽管它可以定义构造方法供子类使用。<BR><BR><STRONG>37</STRONG> public,protected,private有什么不同？<BR>　答：这些关键字用于声明类和成员的可见性。<BR>　public成员可以被任何类访问，<BR>　protected成员限于自己和子类访问，<BR>　private成员限于自己访问。<BR>　Java还提供了第四种的默认可见性，一般称为package private，当没有任何public,protected,private修饰符时，成员是同一包内可见。类可以用public或默认来修饰。<BR><BR><STRONG>38</STRONG> Override和Overload有什么不同？<BR>　答：Override是指父类和子类之间方法的继承关系，这些方法有着相同的名称和参数类型。Overload是指同一个类中不同方法（可以在子类也可以在父类中定义）间的关系，这些方法有着相同的名称和不同的参数类型。<BR><BR><STRONG>39</STRONG> 我继承了一个方法，但现在我想调用在父类中定义的方法。<BR>　答：用super.xxx()可以在子类中调用父类方法。<BR><BR><STRONG>40</STRONG> 我想在子类的构造方法中调用父类的构造方法，该怎么办？<BR>　答：在子类构造方法的第一行调用super(...)即可。<BR><BR><STRONG>41</STRONG> 我在同一个类中定义了好几个构造方法并且想在一个构造方法中调用另一个。<BR>　答：在构造方法第一行调用this(...)。<BR><BR><STRONG>42</STRONG> 我没有定义构造方法会怎么样？<BR>　答：自动获得一个无参数的构造方法。<BR><BR><STRONG>43</STRONG> 我调用无参数的构造方法失败了。<BR>　答：如果你至少定义了一个构造方法，就不再有自动提供的无参数的构造方法了。你需要显式定义一个无参数的构造方法。<BR><BR><STRONG>44</STRONG> 我该怎么定义类似于C++中的析构方法（destructor）？<BR>　答：提供一个void finalize()方法。在Garbarge Collector回收该对象时会调用该方法。注意实际上你很难判断一个对象会在什么时候被回收。作者从未感到需要提供该方法。<BR><BR><STRONG>45</STRONG> 我想将一个父类对象转换成一个子类对象该怎么做？<BR>　答：强制类型转换。如<BR>　public void meth(A a)<BR>　{<BR>　B b = (B)a;<BR>　}<BR>　如果a实际上并不是B的实例，会抛出ClassCastException。所以请确保a确实是B的实例。<BR><BR><STRONG>46</STRONG> 其实我不确定a是不是B的实例，能不能分情况处理？<BR>　答：可以使用instanceof操作符。例如<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( a instanceof B )<BR>　{<BR>　B b = (B)a;<BR>　}<BR>　else<BR>　{<BR>　...<BR>　}<BR><BR><STRONG>47</STRONG> 我在方法里修改了一个对象的值，但是退出方法后我发现这个对象的值没变！<BR>　答：很可能你把传入参数重赋了一个新对象，例如下列代码就会造成这种错误：<BR>　public void fun1(A a) //a是局部参数，指向了一个外在对象。<BR>　{<BR>　a = new A(); //a指向了一个新对象，和外在对象脱钩了。如果你要让a作为传出变量，不要写这一句。<BR>　a.setAttr(attr);//修改了新对象的值，外在对象没有被修改。<BR>　}<BR>　基本类型也会出现这种情况。例如：<BR>　public void fun2(int a)<BR>　{<BR>　a = 10;//只作用于本方法，外面的变量不会变化。<BR>　}<BR><BR><STRONG>六、java.util篇</STRONG><BR><BR><STRONG>48</STRONG> java能动态分配数组吗？<BR>　答：可以。例如int n = 3; Language[] myLanguages = new Language[n];<BR><BR><STRONG>49</STRONG> 我怎么知道数组的长度？<BR>　答：用length属性。如上例中的 myLanguages.length 就为 3。<BR><BR><STRONG>50</STRONG> 我还想让数组的长度能自动改变，能够增加/删除元素。<BR>　答：用顺序表--java.util.List接口。你可以选择用ArrayList或是LinkedList，前者是数组实现，后者是链表实现。例如： <BR>　List list = new ArrayList();<BR>　或是 <BR>　List list = new LinkedList();<BR><BR><STRONG>51</STRONG> 什么是链表？为什么要有两种实现？<BR>　答：请补习数据结构。<BR><BR><STRONG>52</STRONG> 我想用队列/栈。<BR>　答：用java.util.LinkedList。<BR><BR><STRONG>53</STRONG> 我希望不要有重复的元素。<BR>　答：用集合--java.util.Set接口。例如：Set set = new HashSet()。<BR><BR><STRONG>54</STRONG> 我想遍历集合/Map。<BR>　答：用java.util.Iterator。参见API。<BR><BR><STRONG>55</STRONG> 我还要能够排序。<BR>　答：用java.util.TreeSet。例如：Set set = new TreeSet()。放进去的元素会自动排序。你需要为元素实现Comparable接口，还可能需要提供equals()方法，compareTo()方法，hashCode()方法。<BR><BR><STRONG>56</STRONG> 但是我想给数组排序。<BR>　答：java.util.Arrays类包含了sort等实用方法。<BR><BR><STRONG>57</STRONG> 我想按不同方法排序。<BR>　答：为每种方法定义一个实现了接口Comparator的类并和Arrays综合运用。<BR><BR><STRONG>58</STRONG> Map有什么用？<BR>　答：存储key-value的关键字-值对，你可以通过关键字来快速存取相应的值。<BR><BR><STRONG>59</STRONG> set方法没问题，但是get方法返回的是Object。<BR>　答：强制类型转换成你需要的类型。参见45。<BR><BR><STRONG>60</STRONG> 我要获得一个随机数。<BR>　答：使用java.util.Random类。<BR><BR><STRONG>61</STRONG> 我比较两个String总是false，但是它们明明都是"abc" ！<BR>　答：比较String一定要使用equals或equalsIgnoreCase方法，不要使用 == ！<BR>　==比较的是两个引用（变量）是否指向了同一个对象，而不是比较其内容。<BR><BR><STRONG>62</STRONG> 我想修改一个String但是在String类中没找到编辑方法。<BR>　答：使用StringBuffer类。<BR>　String str = "......."; //待处理的字符串<BR>　StringBuffer buffer = new StringBuffer(str); //使用该字符串初始化一个<BR>　StringBuf<BR>　fer<BR>　buffer.append("..."); //调用StringBuffer的相关API来编辑字符串<BR>　String str2 = buffer.toString(); //获得编辑后的字符串<BR>　另外，如果你需要将多个字符串连接起来，请尽量避免使用+号直接连接，而是使用StringBuffer.append()方法。<BR><BR><STRONG>63</STRONG> 我想处理日期/时间。<BR>　答：使用java.util.Date类。你可以使用java.text.SimpleDateFormat类来在String和Date间互相转换。<BR>　SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //规定日期格式<BR>　Date date = formatter.parse("2003-07-26 18:30:35"); //将符合格式的String转换为Date<BR>　String s = formatter.format(date); //将Date转换为符合格式的String<BR>　关于定义日期格式的详细信息请参见API。 <BR clear=all></FONT><BR><img src ="http://www.blogjava.net/iKingQu/aggbug/33943.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-06 23:13 <a href="http://www.blogjava.net/iKingQu/articles/33943.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]Java学习从入门到精通</title><link>http://www.blogjava.net/iKingQu/articles/33901.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Mon, 06 Mar 2006 11:14:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/33901.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/33901.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/33901.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/33901.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/33901.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Java						学习从入门到精通																								 																		作者：						robbin&amp;cammsia																										 																																 ...&nbsp;&nbsp;<a href='http://www.blogjava.net/iKingQu/articles/33901.html'>阅读全文</a><img src ="http://www.blogjava.net/iKingQu/aggbug/33901.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-06 19:14 <a href="http://www.blogjava.net/iKingQu/articles/33901.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]JavaBeans 程序开发基础教程</title><link>http://www.blogjava.net/iKingQu/articles/33725.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Sun, 05 Mar 2006 08:07:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/33725.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/33725.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/33725.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/33725.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/33725.html</trackback:ping><description><![CDATA[<P>JavaBeans的属性 </P>
<P>　　JavaBeans的属性与一般Java程序中所指的属性，或者说与所有面向对象的程序设计语言中对象的属性是一个概念，在程序中的具体体现就是类中的变量。在JavaBeans设计中，按照属性的不同作用又细分为四类：Simple, Index, Bound与Constrained属性。 </P>
<P>1. Simple属性 </P>
<P>　　一个简单属性表示一个伴随有一对get/set方法（C语言的过程或函数在Java程序中称为"方法"）的变量。属性名与和该属性相关的get/set方法名对应。例如：如果有setX和getX方法，则暗指有一个名为"X"的属性。如果有一个方法名为isX，则通常暗指"X"是一个布尔属性（即X的值为true或false）。例如在下面这个程序中： </P>
<P>public class alden1 extends Canvas { <BR>string ourString= "Hello"; //属性名为ourString，类型为字符串 <BR>public alden1(){ 　　　　//alden1()是alden1的构造函数，与C++中构造函数的意义相同 <BR>setBackground(Color.red); <BR>setForeground(Color.blue); <BR>} <BR>/* "set"属性*/ <BR>public void setString(String newString) { <BR>ourString=newString; <BR>} <BR>/* "get"属性 */ <BR>public String getString() { <BR>return ourString; <BR>} <BR>}</P>
<P><BR>2. Indexed属性 </P>
<P>一个Indexed属性表示一个数组值。使用与该属性对应的set/get方法可取得数组中的数值。该属性也可一次设置或取得整个数组的值。例： <BR>public class alden2 extends Canvas { <BR>int[] dataSet={1,2,3,4,5,6}; // dataSet是一个indexed属性 <BR>public alden2() { <BR>setBackground(Color.red); <BR>setForeground(Color.blue); <BR>} <BR>/* 设置整个数组　*/ <BR>public void setDataSet(int[] x){ <BR>dataSet=x; <BR>} <BR>/* 设置数组中的单个元素值 */ <BR>public void setDataSet(int index, int x){ <BR>dataSet[index]=x; <BR>} <BR>/* 取得整个数组值 */ <BR>public int[] getDataSet(){ <BR>return dataSet; <BR>} <BR>/* 取得数组中的指定元素值 */ <BR>public int getDataSet(int x){ <BR>return dataSet[x]; <BR>} <BR>}</P>
<P><BR>3. Bound属性 </P>
<P>　　一个Bound属性是指当该种属性的值发生变化时，要通知其它的对象。每次属性值改变时，这种属性就点火一个PropertyChange事件(在Java程序中，事件也是一个对象)。事件中封装了属性名、属性的原值、属性变化后的新值。这种事件是传递到其它的Beans，至于接收事件的Beans应做什么动作由其自己定义。当PushButton的background属性与Dialog的background属性bind时，若PushButton的background属性发生变化时，Dialog的background属性也发生同样的变化。 例： <BR>public class alden3 extends Canvas{ <BR>String ourString= "Hello"; <BR>//ourString是一个bound属性 <BR>private PropertyChangeSupport changes = new PropertyChangeSupport(this); <BR>/** 注：Java是纯面向对象的语言，如果要使用某种方法则必须指明是要使用哪个对象的方法，在下面的程序中要进行点火事件的操作，这种操作所使用的方法是在PropertyChangeSupport类中的。所以上面声明并实例化了一个changes对象，在下面将使用changes的firePropertyChange方法来点火ourString的属性改变事件。*/ </P>
<P>public void setString(string newString){ <BR>String oldString = ourString; <BR>ourString = newString; <BR>/* ourString的属性值已发生变化，于是接着点火属性改变事件 */ <BR>changes.firePropertyChange("ourString",oldString,newString); <BR>} <BR>public String getString(){ <BR>return ourString; <BR>} <BR>/** 以下代码是为开发工具所使用的。我们不能预知alden3将与哪些其它的Beans组合成为一个应用，无法预知若alden3的ourString属性发生变化时有哪些其它的组件与此变化有关，因而alden3这个Beans要预留出一些接口给开发工具，开发工具使用这些接口，把其它的JavaBeans对象与alden3挂接。*/ </P>
<P>public void addPropertyChangeListener(PropertyChangeLisener l){ <BR>changes.addPropertyChangeListener(l); <BR>} <BR>public void removePropertyChangeListener(PropertyChangeListener l){ <BR>changes.removePropertyChangeListener(l); <BR>}</P>
<P>　　通过上面的代码，开发工具调用changes的addPropertyChangeListener方法把其它JavaBeans注册入ourString属性的监听者队列l中，l是一个Vector数组，可存储任何Java对象。开发工具也可使用changes的removePropertyChangeListener方法，从l中注销指定的对象，使alden3的ourString属性的改变不再与这个对象有关。当然，当程序员手写代码编制程序时，也可直接调用这两个方法，把其它Java对象与alden3挂接。 </P>
<P>4. Constrained属性 </P>
<P>　　一个JavaBeans的constrained属性，是指当这个属性的值要发生变化时，与这个属性已建立了某种连接的其它Java对象可否决属性值的改变。constrained属性的监听者通过抛出PropertyVetoException来阻止该属性值的改变。例：下面程序中的constrained属性是PriceInCents。 <BR>public class JellyBeans extends Canvas{ <BR>private PropertyChangeSupport changes=new PropertyChangeSupport(this); <BR>private VetoableChangeSupport Vetos=new VetoableChangeSupport(this); <BR>/*与前述changes相同，可使用VetoableChangeSupport对象的实例Vetos中的方法，在特定条件下来阻止PriceInCents值的改变。*/ </P>
<P><BR>...... <BR>public void setPriceInCents(int newPriceInCents) throws PropertyVetoException { <BR>/*方法名中throws PropertyVetoException的作用是当有其它Java对象否决PriceInCents的改变时， <BR>要抛出例外。*/ <BR>/* 先保存原来的属性值*/ </P>
<P>int oldPriceInCents=ourPriceInCents; <BR>/**点火属性改变否决事件*/ <BR>vetos.fireVetoableChange("priceInCents",new Integer(OldPriceInCents), <BR>new Integer(newPriceInCents)); </P>
<P>/**若有其它对象否决priceInCents的改变，则程序抛出例外，不再继续执行下面的两条语句，方法结束。若无其它对象否决priceInCents的改变，则在下面的代码中把ourPriceIncents赋予新值，并点火属性改变事件*/ </P>
<P>ourPriceInCents=newPriceInCents; <BR>changes.firePropertyChange("priceInCents", <BR>new Integer(oldPriceInCents), <BR>new Integer(newPriceInCents)); <BR>} </P>
<P>/**与前述changes相同，也要为PriceInCents属性预留接口，使其它对象可注册入PriceInCents否决改变监听者队列中，或把该对象从中注销*/ </P>
<P>public void addVetoableChangeListener(VetoableChangeListener l) <BR>{ vetos.addVetoableChangeListener(l); <BR>} <BR>public void removeVetoableChangeListener(VetoableChangeListener l){ <BR>vetos.removeVetoableChangeListener(l); <BR>} <BR>...... <BR>}</P>
<P><BR>　　从上面的例子中可看到，一个constrained属性有两种监听者：属性变化监听者和否决属性改变的监听者。否决属性改变的监听者在自己的对象代码中有相应的控制语句，在监听到有constrained属性要发生变化时，在控制语句中判断是否应否决这个属性值的改变。 </P>
<P>　　总之，某个Beans的constrained属性值可否改变取决于其它的Beans或者是Java对象是否允许这种改变。允许与否的条件由其它的Beans或Java对象在自己的类中进行定义。 </P>
<P>JavaBeans的事件 </P>
<P>　　事件处理是JavaBeans体系结构的核心之一。通过事件处理机制，可让一些组件作为事件源，发出可被描述环境或其它组件接收的事件。这样，不同的组件就可在构造工具内组合在一起，组件之间通过事件的传递进行通信，构成一个应用。从概念上讲，事件是一种在"源对象"和"监听者对象"之间，某种状态发生变化的传递机制。事件有许多不同的用途，例如在Windows系统中常要处理的鼠标事件、窗口边界改变事件、键盘事件等。在Java和JavaBeans中则是定义了一个一般的、可扩充的事件机制，这种机制能够： </P>
<P>　　1.对事件类型和传递的模型的定义和扩充提供一个公共框架，并适合于广泛的应用。 </P>
<P>　　2.与Java语言和环境有较高的集成度。 </P>
<P>　　3.事件能被描述环境捕获和点火。 </P>
<P>　　4.能使其它构造工具采取某种技术在设计时直接控制事件，以及事件源和事件监听者之间的联系。 </P>
<P>　　5.事件机制本身不依赖于复杂的开发工具。</P>
<P>特别地，还应当： </P>
<P>　　1.能够发现指定的对象类可以生成的事件。 </P>
<P>　　2.能够发现指定的对象类可以观察（监听）到的事件。 </P>
<P>　　3.提供一个常规的注册机制，允许动态操纵事件源与事件监听者之间的关系。 </P>
<P>　　4.不需要其它的虚拟机和语言即可实现。 </P>
<P>　　5.事件源与监听者之间可进行高效的事件传递。 </P>
<P>　　6.能完成JavaBeans事件模型与相关的其它组件体系结构事件模型的中立映射。 </P>
<P>　　JavaBeans事件模型的主要构成有：事件从事件源到监听者的传递是通过对目标监听者对象的Java方法调用进行的。对每个明确的事件的发生，都相应地定义一个明确的Java方法。这些方法都集中定义在事件监听者（EventListener）接口中，这个接口要继承java.util.EventListener。实现了事件监听者接口中一些或全部方法的类就是事件监听者。 伴随着事件的发生，相应的状态通常都封装在事件状态对象中，该对象必须继承自java.util.EventObject。事件状态对象作为单参传递给应响应该事件的监听者方法中。 发出某种特定事件的事件源的标识是：遵从规定的设计格式为事件监听者定义注册方法，并接受对指定事件监听者接口实例的引用。 有时，事件监听者不能直接实现事件监听者接口，或者还有其它的额外动作时，就要在一个源与其它一个或多个监听者之间插入一个事件适配器类的实例，来建立它们之间的联系。 </P>
<P>事件状态对象（Event State Object） </P>
<P>　　与事件发生有关的状态信息一般都封装在一个事件状态对象中，这种对象是java.util.EventObject的子类。按设计习惯，这种事件状态对象类的名应以Event结尾。例如： <BR>public class MouseMovedExampleEvent extends java.util.EventObject </P>
<P>{ protected int x, y； <BR>/*　创建一个鼠标移动事件MouseMovedExampleEvent */ <BR>　 MouseMovedExampleEvent(java.awt.Component source, Point location) { <BR>super(source); <BR>x = location.x; <BR>y = location.y; <BR>} <BR>/* 获取鼠标位置*/ <BR>public Point getLocation() { <BR>return new Point(x, y); <BR>}} </P>
<P><BR>事件监听者接口（EventListener Interface）与事件监听者 </P>
<P>　　由于Java事件模型是基于方法调用，因而需要一个定义并组织事件操纵方法的方式。JavaBeans中，事件操纵方法都被定义在继承了java.util.EventListener类的EventListener接口中，按规定，EventListener接口的命名要以Listener结尾。任何一个类如果想操纵在EventListener接口中定义的方法都必须以实现这个接口方式进行。这个类也就是事件监听者。例如： <BR>/*先定义了一个鼠标移动事件对象*/ <BR>　　 public class MouseMovedExampleEvent <BR>extends java.util.EventObject { <BR>// 在此类中包含了与鼠标移动事件有关的状态信息 <BR>　　　　 ... <BR>　　 } <BR>　　 /*定义了鼠标移动事件的监听者接口*/ <BR>　　 interface MouseMovedExampleListener <BR>extends java.util.EventListener { <BR>/*在这个接口中定义了鼠标移动事件监听者所应支持的方法*/ <BR>void mouseMoved(MouseMovedExampleEvent mme); <BR>}</P>
<P><BR>　　在接口中只定义方法名，方法的参数和返回值类型。如：上面接口中的mouseMoved方法的具体实现是在下面的ArbitraryObject类中定义的。 <BR>class ArbitraryObject implements MouseMovedExampleListener { <BR>　　　 public void mouseMoved(MouseMovedExampleEvent mme) <BR>　 { ... } <BR>｝</P>
<P>　　ArbitraryObject就是MouseMovedExampleEvent事件的监听者。 </P>
<P><BR>事件监听者的注册与注销 </P>
<P>　　为了各种可能的事件监听者把自己注册入合适的事件源中，建立源与事件监听者间的事件流，事件源必须为事件监听者提供注册和注销的方法。在前面的bound属性介绍中已看到了这种使用过程，在实际中，事件监听者的注册和注销要使用标准的设计格式： <BR>public void add&lt; ListenerType&gt;(&lt;ListenerType&gt; listener)； <BR>public void remove&lt; ListenerType&gt;(&lt;ListenerType&gt; listener)；</P>
<P><BR>　　例如： </P>
<P>　　首先定义了一个事件监听者接口： <BR>public interface <BR>ModelChangedListener extends java.util.EventListener { <BR>void modelChanged(EventObject e); <BR>} </P>
<P><BR>　　接着定义事件源类： <BR>public abstract class Model { <BR>private Vector listeners = new Vector(); // 定义了一个储存事件监听者的数组 </P>
<P>/*上面设计格式中的&lt; ListenerType&gt;在此处即是下面的ModelChangedListener*/ </P>
<P>public synchronized void addModelChangedListener(ModelChangedListener mcl) <BR>　　 { listeners.addElement(mcl); }　//把监听者注册入listeners数组中 <BR>public synchronized void removeModelChangedListener(ModelChangedListener mcl) <BR>　　　　 { listeners.removeElement(mcl);　 //把监听者从listeners中注销 <BR>　　　　 ｝ <BR>/*以上两个方法的前面均冠以synchronized，是因为运行在多线程环境时，可能同时有几个对象同时要进行注册和注销操作，使用synchronized来确保它们之间的同步。开发工具或程序员使用这两个方法建立源与监听者之间的事件流*/ </P>
<P>protected void notifyModelChanged() { <BR>/**事件源使用本方法通知监听者发生了modelChanged事件*/ <BR>　　　 Vector l; <BR>　　　　 EventObject e = new EventObject(this); <BR>/* 首先要把监听者拷贝到l数组中，冻结EventListeners的状态以传递事件。这样来确保在事件传递到所有监听者之前，已接收了事件的目标监听者的对应方法暂不生效。*/ <BR>　　　　 synchronized(this) { <BR>　　　　　　 l = (Vector)listeners.clone(); <BR>　　　　 } <BR>　　　　 for (int i = 0; i &lt; l.size(); i++) { <BR>/* 依次通知注册在监听者队列中的每个监听者发生了modelChanged事件，并把事件状态对象e作为参数传递给监听者队列中的每个监听者*/ <BR>((ModelChangedListener)l.elementAt(i)).modelChanged(e); <BR>　　　　 } <BR>　　　 } <BR>　　　 } </P>
<P><BR>　　在程序中可见事件源Model类显式地调用了接口中的modelChanged方法，实际是把事件状态对象e作为参数，传递给了监听者类中的modelChanged方法。 </P>
<P>适配类 </P>
<P>　　适配类是Java事件模型中极其重要的一部分。在一些应用场合，事件从源到监听者之间的传递要通过适配类来"转发"。例如：当事件源发出一个事件，而有几个事件监听者对象都可接收该事件，但只有指定对象做出反应时，就要在事件源与事件监听者之间插入一个事件适配器类，由适配器类来指定事件应该是由哪些监听者来响应。 </P>
<P>　　适配类成为了事件监听者，事件源实际是把适配类作为监听者注册入监听者队列中，而真正的事件响应者并未在监听者队列中，事件响应者应做的动作由适配类决定。目前绝大多数的开发工具在生成代码时，事件处理都是通过适配类来进行的。 </P>
<P>JavaBeans用户化 </P>
<P>　　JavaBeans开发者可以给一个Beans添加用户化器（Customizer）、属性编辑器（PropertyEditor）和BeansInfo接口来描述一个Beans的内容，Beans的使用者可在构造环境中通过与Beans附带在一起的这些信息来用户化Beans的外观和应做的动作。一个Beans不必都有BeansCustomizer、PrpertyEditor和BeansInfo，根据实际情况，这些是可选的，当有些Beans较复杂时，就要提供这些信息，以Wizard的方式使Beans的使用者能够用户化一个Beans。有些简单的Beans可能这些信息都没有，则构造工具可使用自带的透视装置，透视出Beans的内容，并把信息显示到标准的属性表或事件表中供使用者用户化Beans，前几节提到的Beans的属性、方法和事件名要以一定的格式命名，主要的作用就是供开发工具对Beans进行透视。当然也是给程序员在手写程序中使用Beans提供方便，使他能观其名、知其意。 </P>
<P>用户化器接口（Customizer Interface） </P>
<P>　　当一个Beans有了自己的用户化器时，在构造工具内就可展现出自己的属性表。在定义用户化器时必须要实现java.Beanss.Customizer接口。例如，下面是一个"按钮"Beans的用户化一器： <BR>public class OurButtonCustomizer <BR>extends Panel implements Customizer { <BR>... ... <BR>/*当实现象OurButtonCustomizer这样的常规属性表时，一定要在其中实现addProperChangeListener <BR>和removePropertyChangeListener,这样，构造工具可用这些功能代码为属性事件添加监听者。*/ <BR>... ... <BR>private PropertyChangeSupport changes=new PropertyChangeSupport(this); <BR>public void addPropertyChangeListener(PropertyChangeListener l) { <BR>changes.addPropertyChangeListener(l); <BR>public void removePropertyChangeListener(PropertyChangeListener l) { <BR>changes.removePropertyChangeListener(l); <BR>} <BR>... ...</P>
<P><BR>属性编辑器接口（PropertyEditor Interface） </P>
<P>　　一个JavaBeans可提供PropertyEditor类，为指定的属性创建一个编辑器。这个类必须继承自java.Beanss.PropertyEditorSupport类。构造工具与手写代码的程序员不直接使用这个类，而是在下一小节的BeansInfo中实例化并调用这个类。例： <BR>public class MoleculeNameEditor extends java.Beanss.PropertyEditorSupport { <BR>public String[] getTags() { <BR>String resule[]={ <BR>"HyaluronicAcid","Benzene","buckmisterfullerine", <BR>"cyclohexane","ethane","water"}; <BR>return resule;} <BR>} </P>
<P>　　上例中是为Tags属性创建了属性编辑器，在构造工具内，可从下拉表格中选择MoleculeName的属性应是"HyaluronicAid"或是"water"。 </P>
<P>BeansInfo接口 </P>
<P>　　每个Beans类也可能有与之相关的BeansInfo类，在其中描述了这个Beans在构造工具内出现时的外观。BeansInfo中可定义属性、方法、事件，显示它们的名称，提供简单的帮助说明。 例如： <BR>public class MoleculeBeansInfo extends SimpleBeansInfo { <BR>public PropertyDescriptor[] getPropertyDescriptors() { <BR>try { <BR>PropertyDescriptor pd=new PropertyDescriptor("moleculeName",Molecule.class); <BR>/*通过pd引用了上一节的MoleculeNameEditor类,取得并返回moleculeName属性*/ <BR>pd.setPropertyEditorClass(MoleculeNameEditor.class); <BR>PropertyDescriptor result[]={pd}; <BR>return result; <BR>} catch(Exception ex) { <BR>System.err.println("MoleculeBeansInfo: unexpected exeption: "+ex); <BR>return null; <BR>} <BR>} <BR>} </P>
<P><BR>JavaBeans持久化 </P>
<P>　　当一个JavaBeans在构造工具内被用户化，并与其它Beans建立连接之后，它的所有状态都应当可被保存，下一次被load进构造工具内或在运行时，就应当是上一次修改完的信息。为了能做到这一点，要把Beans的某些字段的信息保存下来，在定义Beans时要使它实现java.io.Serializable接口。例如： <BR>public class Button <BR>implements java.io.Serializable { <BR>} </P>
<P><BR>　　实现了序列化接口的Beans中字段的信息将被自动保存。若不想保存某些字段的信息则可在这些字段前冠以transient或static关键字，transient和static变量的信息是不可被保存的。通常，一个Beans所有公开出来的属性都应当是被保存的，也可有选择地保存内部状态。 Beans开发者在修改软件时，可以添加字段，移走对其它类的引用，改变一个字段的private/protected/public状态，这些都不影响类的存储结构关系。然而，当从类中删除一个字段，改变一个变量在类体系中的位置，把某个字段改成transient/static，或原来是transient/static，现改为别的特性时，都将引起存储关系的变化。 </P>
<P>JavaBeans的存储格式 </P>
<P>　　JavaBeans组件被设计出来后，一般是以扩展名为jar的Zip格式文件存储，在jar中包含与JavaBeans有关的信息，并以MANIFEST文件指定其中的哪些类是JavaBeans。以jar文件存储的JavaBeans在网络中传送时极大地减少了数据的传输数量，并把JavaBeans运行时所需要的一些资源捆绑在一起，本章主要论述了JavaBeans的一些内部特性及其常规设计方法，参考的是JavaBeans规范1.0A版本。随着世界各大ISV对JavaBeans越来越多的支持，规范在一些细节上还在不断演化，但基本框架不会再有大的变动<BR></P><img src ="http://www.blogjava.net/iKingQu/aggbug/33725.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-05 16:07 <a href="http://www.blogjava.net/iKingQu/articles/33725.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]每个初学者都应该搞懂的问题</title><link>http://www.blogjava.net/iKingQu/articles/33724.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Sun, 05 Mar 2006 08:02:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/33724.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/33724.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/33724.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/33724.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/33724.html</trackback:ping><description><![CDATA[<P>对于这个系列里的问题，每个学Java的人都应该搞懂。当然，如果只是学Java玩玩就无所谓了。如果你认为自己已经超越初学者了，却不很懂这些问题，请将你自己重归初学者行列。内容均来自于CSDN的经典老贴。</P>
<P>问题一：我声明了什么！</P>
<P>String s = "Hello world!";</P>
<P>许多人都做过这样的事情，但是，我们到底声明了什么？回答通常是：一个String，内容是“Hello world!”。这样模糊的回答通常是概念不清的根源。如果要准确的回答，一半的人大概会回答错误。<BR>这个语句声明的是一个指向对象的引用，名为“s”，可以指向类型为String的任何对象，目前指向"Hello world!"这个String类型的对象。这就是真正发生的事情。我们并没有声明一个String对象，我们只是声明了一个只能指向String对象的引用变量。所以，如果在刚才那句语句后面，如果再运行一句：</P>
<P>String string = s;</P>
<P>我们是声明了另外一个只能指向String对象的引用，名为string，并没有第二个对象产生，string还是指向原来那个对象，也就是，和s指向同一个对象。</P>
<P>问题二："=="和equals方法究竟有什么区别？</P>
<P>==操作符专门用来比较变量的值是否相等。比较好理解的一点是：<BR>int a=10;<BR>int b=10;<BR>则a==b将是true。<BR>但不好理解的地方是：<BR>String a=new String("foo");<BR>String b=new String("foo");<BR>则a==b将返回false。</P>
<P>根据前一帖说过，对象变量其实是一个引用，它们的值是指向对象所在的内存地址，而不是对象本身。a和b都使用了new操作符，意味着将在内存中产生两个内容为"foo"的字符串，既然是“两个”，它们自然位于不同的内存地址。a和b的值其实是两个不同的内存地址的值，所以使用"=="操作符，结果会是false。诚然，a和b所指的对象，它们的内容都是"foo"，应该是“相等”，但是==操作符并不涉及到对象内容的比较。<BR>对象内容的比较，正是equals方法做的事。</P>
<P>看一下Object对象的equals方法是如何实现的：<BR>boolean equals(Object o){</P>
<P>return this==o;</P>
<P>}<BR>Object对象默认使用了==操作符。所以如果你自创的类没有覆盖equals方法，那你的类使用equals和使用==会得到同样的结果。同样也可以看出，Object的equals方法没有达到equals方法应该达到的目标：比较两个对象内容是否相等。因为答案应该由类的创建者决定，所以Object把这个任务留给了类的创建者。</P>
<P>看一下一个极端的类：<BR>Class Monster{<BR>private String content;<BR>...<BR>boolean equals(Object another){ return true;}</P>
<P>}<BR>我覆盖了equals方法。这个实现会导致无论Monster实例内容如何，它们之间的比较永远返回true。</P>
<P>所以当你是用equals方法判断对象的内容是否相等，请不要想当然。因为可能你认为相等，而这个类的作者不这样认为，而类的equals方法的实现是由他掌握的。如果你需要使用equals方法，或者使用任何基于散列码的集合（HashSet,HashMap,HashTable），请察看一下java doc以确认这个类的equals逻辑是如何实现的。</P>
<P>问题三：String到底变了没有？</P>
<P>没有。因为String被设计成不可变(immutable)类，所以它的所有对象都是不可变对象。请看下列代码：</P>
<P>String s = "Hello";<BR>s = s + " world!";</P>
<P>s所指向的对象是否改变了呢？从本系列第一篇的结论很容易导出这个结论。我们来看看发生了什么事情。在这段代码中，s原先指向一个String对象，内容是"Hello"，然后我们对s进行了+操作，那么s所指向的那个对象是否发生了改变呢？答案是没有。这时，s不指向原来那个对象了，而指向了另一个String对象，内容为"Hello world!"，原来那个对象还存在于内存之中，只是s这个引用变量不再指向它了。<BR>通过上面的说明，我们很容易导出另一个结论，如果经常对字符串进行各种各样的修改，或者说，不可预见的修改，那么使用String来代表字符串的话会引起很大的内存开销。因为String对象建立之后不能再改变，所以对于每一个不同的字符串，都需要一个String对象来表示。这时，应该考虑使用StringBuffer类，它允许修改，而不是每个不同的字符串都要生成一个新的对象。并且，这两种类的对象转换十分容易。<BR>同时，我们还可以知道，如果要使用内容相同的字符串，不必每次都new一个String。例如我们要在构造器中对一个名叫s的String引用变量进行初始化，把它设置为初始值，应当这样做：<BR>public class Demo {<BR>&nbsp; private String s;<BR>&nbsp; ...<BR>&nbsp; public Demo {<BR>&nbsp;&nbsp;&nbsp; s = "Initial Value";<BR>&nbsp; }<BR>&nbsp; ...<BR>}<BR>而非<BR>s = new String("Initial Value");<BR>后者每次都会调用构造器，生成新对象，性能低下且内存开销大，并且没有意义，因为String对象不可改变，所以对于内容相同的字符串，只要一个String对象来表示就可以了。也就说，多次调用上面的构造器创建多个对象，他们的String类型属性s都指向同一个对象。<BR>上面的结论还基于这样一个事实：对于字符串常量，如果内容相同，Java认为它们代表同一个String对象。而用关键字new调用构造器，总是会创建一个新的对象，无论内容是否相同。<BR>至于为什么要把String类设计成不可变类，是它的用途决定的。其实不只String，很多Java标准类库中的类都是不可变的。在开发一个系统的时候，我们有时候也需要设计不可变类，来传递一组相关的值，这也是面向对象思想的体现。不可变类有一些优点，比如因为它的对象是只读的，所以多线程并发访问也不会有任何问题。当然也有一些缺点，比如每个不同的状态都要一个对象来代表，可能会造成性能上的问题。所以Java标准类库还提供了一个可变版本，即StringBuffer。</P>
<P>问题四：final关键字到底修饰了什么？</P>
<P>final使得被修饰的变量"不变"，但是由于对象型变量的本质是“引用”，使得“不变”也有了两种含义：引用本身的不变，和引用指向的对象不变。</P>
<P>引用本身的不变：<BR>final StringBuffer a=new StringBuffer("immutable");<BR>final StringBuffer b=new StringBuffer("not immutable");<BR>a=b;//编译期错误</P>
<P>引用指向的对象不变：<BR>final StringBuffer a=new StringBuffer("immutable");<BR>a.append(" broken!"); //编译通过</P>
<P>可见，final只对引用的“值”(也即它所指向的那个对象的内存地址)有效，它迫使引用只能指向初始指向的那个对象，改变它的指向会导致编译期错误。至于它所指向的对象的变化，final是不负责的。这很类似==操作符：==操作符只负责引用的“值”相等，至于这个地址所指向的对象内容是否相等，==操作符是不管的。</P>
<P>理解final问题有很重要的含义。许多程序漏洞都基于此----final只能保证引用永远指向固定对象，不能保证那个对象的状态不变。在多线程的操作中,一个对象会被多个线程共享或修改，一个线程对对象无意识的修改可能会导致另一个使用此对象的线程崩溃。一个错误的解决方法就是在此对象新建的时候把它声明为final，意图使得它“永远不变”。其实那是徒劳的。</P>
<P>问题五：到底要怎么样初始化！</P>
<P>本问题讨论变量的初始化，所以先来看一下Java中有哪些种类的变量。<BR>1. 类的属性，或者叫值域<BR>2. 方法里的局部变量<BR>3. 方法的参数</P>
<P>对于第一种变量，Java虚拟机会自动进行初始化。如果给出了初始值，则初始化为该初始值。如果没有给出，则把它初始化为该类型变量的默认初始值。</P>
<P>int类型变量默认初始值为0<BR>float类型变量默认初始值为0.0f<BR>double类型变量默认初始值为0.0<BR>boolean类型变量默认初始值为false<BR>char类型变量默认初始值为0(ASCII码)<BR>long类型变量默认初始值为0<BR>所有对象引用类型变量默认初始值为null，即不指向任何对象。注意数组本身也是对象，所以没有初始化的数组引用在自动初始化后其值也是null。</P>
<P>对于两种不同的类属性，static属性与instance属性，初始化的时机是不同的。instance属性在创建实例的时候初始化，static属性在类加载，也就是第一次用到这个类的时候初始化，对于后来的实例的创建，不再次进行初始化。这个问题会在以后的系列中进行详细讨论。</P>
<P>对于第二种变量，必须明确地进行初始化。如果再没有初始化之前就试图使用它，编译器会抗议。如果初始化的语句在try块中或if块中，也必须要让它在第一次使用前一定能够得到赋值。也就是说，把初始化语句放在只有if块的条件判断语句中编译器也会抗议，因为执行的时候可能不符合if后面的判断条件，如此一来初始化语句就不会被执行了，这就违反了局部变量使用前必须初始化的规定。但如果在else块中也有初始化语句，就可以通过编译，因为无论如何，总有至少一条初始化语句会被执行，不会发生使用前未被初始化的事情。对于try-catch也是一样，如果只有在try块里才有初始化语句，编译部通过。如果在catch或finally里也有，则可以通过编译。总之，要保证局部变量在使用之前一定被初始化了。所以，一个好的做法是在声明他们的时候就初始化他们，如果不知道要出事化成什么值好，就用上面的默认值吧！</P>
<P>其实第三种变量和第二种本质上是一样的，都是方法中的局部变量。只不过作为参数，肯定是被初始化过的，传入的值就是初始值，所以不需要初始化。</P>
<P>问题六：instanceof是什么东东？</P>
<P>instanceof是Java的一个二元操作符，和==，&gt;，&lt;是同一类东东。由于它是由字母组成的，所以也是Java的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例，返回boolean类型的数据。举个例子：</P>
<P>String s = "I AM an Object!";<BR>boolean isObject = s instanceof Object;</P>
<P>我们声明了一个String对象引用，指向一个String对象，然后用instancof来测试它所指向的对象是否是Object类的一个实例，显然，这是真的，所以返回true，也就是isObject的值为True。<BR>instanceof有一些用处。比如我们写了一个处理账单的系统，其中有这样三个类：</P>
<P>public class Bill {//省略细节}<BR>public class PhoneBill extends Bill {//省略细节}<BR>public class GasBill extends Bill {//省略细节}</P>
<P>在处理程序里有一个方法，接受一个Bill类型的对象，计算金额。假设两种账单计算方法不同，而传入的Bill对象可能是两种中的任何一种，所以要用instanceof来判断：</P>
<P>public double calculate(Bill bill) {<BR>&nbsp; if (bill instanceof PhoneBill) {<BR>&nbsp;&nbsp;&nbsp; //计算电话账单<BR>&nbsp; }<BR>&nbsp; if (bill instanceof GasBill) {<BR>&nbsp;&nbsp;&nbsp; //计算燃气账单<BR>&nbsp; }<BR>&nbsp; ...<BR>}<BR>这样就可以用一个方法处理两种子类。</P>
<P>然而，这种做法通常被认为是没有好好利用面向对象中的多态性。其实上面的功能要求用方法重载完全可以实现，这是面向对象变成应有的做法，避免回到结构化编程模式。只要提供两个名字和返回值都相同，接受参数类型不同的方法就可以了：</P>
<P>public double calculate(PhoneBill bill) {<BR>&nbsp; //计算电话账单<BR>}</P>
<P>public double calculate(GasBill bill) {<BR>&nbsp; //计算燃气账单<BR>}</P>
<P>所以，使用instanceof在绝大多数情况下并不是推荐的做法，应当好好利用多态。</P><img src ="http://www.blogjava.net/iKingQu/aggbug/33724.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-05 16:02 <a href="http://www.blogjava.net/iKingQu/articles/33724.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]JDK环境变量配置</title><link>http://www.blogjava.net/iKingQu/articles/33701.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Sun, 05 Mar 2006 06:32:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/33701.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/33701.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/33701.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/33701.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/33701.html</trackback:ping><description><![CDATA[<H2>JDK环境变量配置 ：</H2>
<P>Windows下：<BR><BR>1：右键我的电脑 &gt; 属性 &gt; 高级 &gt; 环境变量 &gt;系统变量<BR>2：新建 变量名：JAVA_HOME 变量值：X:\j2sdk1.4.2_10<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 新建 变量名：CLASSPATH 变量值：.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar&nbsp; <BR>3：编辑 变量名：PATH&nbsp; 变量值添加：%JAVA_HOME%\bin;<BR><BR><BR></P>
<P>Linux下：<BR><BR>用vi编辑/etc下的profile<BR>在最后加入如下内容：<BR>export&nbsp; PATH=/usr/java/j2sdk1.4.2_10/bin:$PATH<BR>export&nbsp; CLASSPATH=.:/usr/java/j2sdk1.4.2_10/lib/tools.jar:/usr/java/j2sdk1.4.2_03/lib<BR>:$CLASSPATH<BR>存盘退出（注意，j2sdk1.4.2_10这里因jdk不同版本而异）<BR>要想使它立即生效，在命令行中键入：source /etc/profil</P><img src ="http://www.blogjava.net/iKingQu/aggbug/33701.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-05 14:32 <a href="http://www.blogjava.net/iKingQu/articles/33701.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]ClasssPath的默认值</title><link>http://www.blogjava.net/iKingQu/articles/33702.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Sun, 05 Mar 2006 06:32:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/33702.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/33702.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/33702.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/33702.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/33702.html</trackback:ping><description><![CDATA[<H2>ClasssPath的默认值</H2>
<P>在 JDK 1.2 中，有三个搜索路径用于查找类：<BR>1) java 搜索类的第一个位置是自举类路径。<BR>可通过调用 System.getProperty("sun.boot.class.path") 检查该路径的值。<BR>注意，其中前缀“sun.”显示至少到现在为止，该属性是特定于 Sun 公司的实现。<BR>2) java 查找类的第二个位置是扩展目录。<BR>可通过调用 System.getProperty("java.ext.dirs") 检查目录列表。<BR>3) java 查找类的第三个位置是应用程序类路径。<BR>可通过调用 System.getProperty("java.class.path") 检查该路径的值。<BR><BR>you can get:<BR><BR>1) java_base\jre\lib\rt.jar<BR>&nbsp;&nbsp; java_base\jre\lib\i18n.jar<BR>&nbsp;&nbsp; java_base\jre\classes<BR>2) java_base\jre\lib\ext </P><img src ="http://www.blogjava.net/iKingQu/aggbug/33702.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-05 14:32 <a href="http://www.blogjava.net/iKingQu/articles/33702.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>