﻿<?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-辰o(^o^)o的专栏[除非注释原创，其它文章基本来源于网络]-文章分类-J2se</title><link>http://www.blogjava.net/jackybu/category/447.html</link><description>&lt;a href="http://www.fastonlineusers.com"&gt;&lt;b&gt;&lt;font color=red&gt;共有&lt;script src=http://fastonlineusers.com/online.php?d=jackybu.blogjava.net&gt;&lt;/script&gt;人在同时阅读此Blog&lt;/font&gt;&lt;/b&gt;&lt;/a&gt;</description><language>zh-cn</language><lastBuildDate>Fri, 02 Mar 2007 03:08:06 GMT</lastBuildDate><pubDate>Fri, 02 Mar 2007 03:08:06 GMT</pubDate><ttl>60</ttl><item><title>Serializable java序列化</title><link>http://www.blogjava.net/jackybu/articles/15821.html</link><dc:creator>辰</dc:creator><author>辰</author><pubDate>Tue, 18 Oct 2005 07:07:00 GMT</pubDate><guid>http://www.blogjava.net/jackybu/articles/15821.html</guid><wfw:comment>http://www.blogjava.net/jackybu/comments/15821.html</wfw:comment><comments>http://www.blogjava.net/jackybu/articles/15821.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackybu/comments/commentRss/15821.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackybu/services/trackbacks/15821.html</trackback:ping><description><![CDATA[1、实现Serializable回导致发布的API难以更改，并且使得package-private和private
这两个本来封装的较好的咚咚也不能得到保障了
2、Serializable会为每个类生成一个序列号，生成依据是类名、类实现的接口名、
public和protected方法，所以只要你一不小心改了一个已经publish的API，并且没有自
己定义一个long类型的叫做serialVersionUID的field，哪怕只是添加一个getXX，就会
让你读原来的序列化到文件中的东西读不出来（不知道为什么要把方法名算进去？）
3、不用构造函数用Serializable就可以构造对象，看起来不大合理，这被称为
extralinguistic mechanism，所以当实现Serializable时应该注意维持构造函数中所维
持的那些不变状态
4、增加了发布新版本的类时的测试负担
5、1.4版本后，JavaBeans的持久化采用基于XML的机制，不再需要Serializable
6、设计用来被继承的类时，尽量不实现Serializable，用来被继承的interface也不要
继承Serializable。但是如果父类不实现Serializable接口，子类很难实现它，特别是
对于父类没有可以访问的不含参数的构造函数的时候。所以，一旦你决定不实现
Serializable接口并且类被用来继承的时候记得提供一个无参数的构造函数
7、内部类还是不要实现Serializable好了，除非是static的，(偶也觉得内部类不适合
用来干这类活的)
8、使用一个自定义的序列化方法  看看下面这个保存一个双向链表的例子：public class StringList implements Serializable{?private int size = 0;?private Entry head = null;??private static class Entry implements Serializable?{? String data;? Entry next;? Entry previous;?}?...//Remainder ommitted}

这样会导致链表的每个元素以及元素之间的关系（双向链表之间的连接）都保存下来，更好的方法是提供一个自定义的序列化如下：
//String List with a resonable custom serialized formclass StringList implements Serializable{? private transient int size = 0;?????? //!transient? private transient Entry head = null;? //!transient? ? //no longer serializable!? private static class Entry? {??? String data;??? Entry next;??? Entry previous;? }? ? //Appends the specified string to the list? public void add(String s) {/*...*/};? ? /**?? * Serialize this StringList instance ?? * @author yuchifang?? * @serialData The size of the list (the number of strings   * it contains) is emitted(int), in the proper sequence?? */? private void writeObject(ObjectOutputStream s)               throws IOException? {??? s.defaultWriteObject();??? s.writeInt(size);??? //Write out all elements in the proper order??? for (Entry e = head; e != null; e = e.next)????? s.writeObject(e.data);? }? ? private void readObject(ObjectInputStream s)               throws IOException, ClassNotFoundException? {??? int numElements = s.readInt();??? ??? //Read in all elements andd insert them in list??? for (int i = 0; i < numElements; i++)????? add((String)s.readObject());? }? //...remainder omitted}
9、不管你选择什么序列化形式，声明一个显式的UID：
private static final long serialVersionUID = randomLongValue;
10、不需要序列化的东西使用transient注掉它吧，别什么都留着
11、writeObject/readObject重载以完成更好的序列化
readResolve 与 writeReplace重载以完成更好的维护invariant controllers<img src ="http://www.blogjava.net/jackybu/aggbug/15821.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackybu/" target="_blank">辰</a> 2005-10-18 15:07 <a href="http://www.blogjava.net/jackybu/articles/15821.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>保留字synchronized的作用</title><link>http://www.blogjava.net/jackybu/articles/9783.html</link><dc:creator>辰</dc:creator><author>辰</author><pubDate>Thu, 11 Aug 2005 03:07:00 GMT</pubDate><guid>http://www.blogjava.net/jackybu/articles/9783.html</guid><wfw:comment>http://www.blogjava.net/jackybu/comments/9783.html</wfw:comment><comments>http://www.blogjava.net/jackybu/articles/9783.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackybu/comments/commentRss/9783.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackybu/services/trackbacks/9783.html</trackback:ping><description><![CDATA[Synchronized是用来保证同一时刻本段代码不会同时运行。在操作系统中这些代码被认为是临界段，如访问打印机，磁盘，信号量等，只可能有一段代码在使用这些临界资源。其他必须等待。这类问题在多cpu多线程的时候尤为要注意。<BR>Synchronized method(){}是用来保证同一时刻某方法不会被多个线程同时执行,以免冲突.<BR>Synchronized (object){}是用来保证在执行大括号中代码时,独占object这个对象,所以,<BR>如果当执行到这里时,如果object正被其他同步方法调用,则必须等候object被解锁,才能进入该程序块,而当进入该程序块时,将对object上锁,执行完以后解锁,以免在此期间,其他程序用到object.<BR>当某个方法被同步化，则内部的属性也被同步化。获得monitor的进程独占这些资源直到解锁。这样做保证某些变量被各个线程共享，并且变化是一致的<BR><img src ="http://www.blogjava.net/jackybu/aggbug/9783.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackybu/" target="_blank">辰</a> 2005-08-11 11:07 <a href="http://www.blogjava.net/jackybu/articles/9783.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>重载（Overloading），重置（Overriding）,重构（Refactoring） </title><link>http://www.blogjava.net/jackybu/articles/7531.html</link><dc:creator>辰</dc:creator><author>辰</author><pubDate>Tue, 12 Jul 2005 02:17:00 GMT</pubDate><guid>http://www.blogjava.net/jackybu/articles/7531.html</guid><wfw:comment>http://www.blogjava.net/jackybu/comments/7531.html</wfw:comment><comments>http://www.blogjava.net/jackybu/articles/7531.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackybu/comments/commentRss/7531.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackybu/services/trackbacks/7531.html</trackback:ping><description><![CDATA[重载和重置都是对方法而言的，而重构是对于构件或者类或者整个系统而言的。 
<P>重载和重置都是面向对象多态性的体现。重载是指一个方法可以有呈现出多种形态。多种形态是通过同名的方法可以有不同的参数类型顺序或者不同参数个数实现的。重置则是子类对从基类继承的方法的重写，也叫覆盖吧。这很容易理解，因为即使基类和子类再类似，基类的方法肯定有不适合子类的地方，这时候子类就需要对基类的方法重置。重置时方法参数的类型、数量和次序一定要和基类的方法一致，否则就成了重载。</P>
<P>&nbsp;&nbsp;&nbsp; 重构一般有软件重构和代码重构。软件重构是指在不改变软件的功能和外部可见性的前提下，对软件进行改造，其目的是为了改善软件的结构，提高清晰性、可扩展性和可重用性。代码重构就是在不改变代码外部情况的对源代码的修改。重构是代码维护中很重要，但不增加新的行为。重构用于提高代码的可读性和改变代码的结构和设计，这样在将来更容易维护。如果在现有结构下给一个构件或者增加一个新的行为很困难或者根本不可能，这时候就需要重构这个构件或者类，其目的是为了增加新行为更容易。</P><img src ="http://www.blogjava.net/jackybu/aggbug/7531.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackybu/" target="_blank">辰</a> 2005-07-12 10:17 <a href="http://www.blogjava.net/jackybu/articles/7531.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java中对文件的操作</title><link>http://www.blogjava.net/jackybu/articles/2510.html</link><dc:creator>辰</dc:creator><author>辰</author><pubDate>Mon, 28 Mar 2005 01:55:00 GMT</pubDate><guid>http://www.blogjava.net/jackybu/articles/2510.html</guid><wfw:comment>http://www.blogjava.net/jackybu/comments/2510.html</wfw:comment><comments>http://www.blogjava.net/jackybu/articles/2510.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackybu/comments/commentRss/2510.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackybu/services/trackbacks/2510.html</trackback:ping><description><![CDATA[<STRONG><FONT face=宋体>&nbsp;java中提供了io类库，可以轻松的用java实现对文件的各种操作。下面就来说一下如何用java来实现这些操作。</FONT></STRONG>
<P align=left><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"><STRONG>&nbsp;&nbsp; 1。新建目录</STRONG></SPAN></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"></SPAN></STRONG><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">&lt;%@ page contentType="text/html;charset=gb2312"%&gt;<BR>&lt;%<BR>String filePath="c:/aaa/";<BR>filePath=filePath.toString();//中文转换<BR>java.io.File myFilePath=new java.io.File(filePath);<BR>if(!myFilePath.exists())<BR>myFilePath.mkdir();<BR>%&gt;</SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">&nbsp; 2。新建文件</SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">&lt;%@ page contentType="text/html;charset=gb2312"%&gt;<BR>&lt;%@ page import="java.io.*" %&gt;<BR>&lt;%<BR>String filePath="c:/哈哈.txt";<BR>filePath=filePath.toString();<BR>File myFilePath=new File(filePath);<BR>if(!myFilePath.exists())<BR>myFilePath.createNewFile();<BR>FileWriter resultFile=new FileWriter(myFilePath);<BR>PrintWriter myFile=new PrintWriter(resultFile);<BR>String strContent = "中文测试".toString();<BR>myFile.println(strContent);<BR>resultFile.close();<BR>%&gt;</SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">&nbsp;3。删除文件</SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">&lt;%@ page contentType="text/html;charset=gb2312"%&gt;<BR>&lt;%<BR>String filePath="c:/支出证明单.xls";<BR>filePath=filePath.toString();<BR>java.io.File myDelFile=new java.io.File(filePath);<BR>myDelFile.delete();<BR>%&gt;</SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">&nbsp;4。文件拷贝</SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">&lt;%@ page contentType="text/html; charset=gb2312" %&gt;<BR>&lt;%@ page import="java.io.*" %&gt;<BR>&lt;%<BR>int bytesum=0;<BR>int byteread=0;&nbsp;<BR><U><FONT color=#0000ff><A href="file://读/">file://读</A></FONT></U>到流中<BR>InputStream inStream=new FileInputStream("c:/aaa.doc");<BR>FileOutputStream fs=new FileOutputStream( "d:/aaa.doc");</SPAN></STRONG><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">byte[]&nbsp; buffer =new&nbsp; byte[1444];<BR>int length;<BR>while ((byteread=inStream.read(buffer))!=-1)<BR>&nbsp;{<BR>&nbsp;&nbsp;&nbsp;out.println("&lt;DT&gt;&lt;B&gt;"+byteread+"&lt;/B&gt;&lt;/DT&gt;");<BR>&nbsp;&nbsp;&nbsp;bytesum+=byteread;<BR>&nbsp;&nbsp;&nbsp;System.out.println(bytesum);<BR>&nbsp;&nbsp;&nbsp;fs.write(buffer,0,byteread);<BR>&nbsp;}&nbsp;<BR>inStream.close(); <BR>%&gt;</SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">&nbsp;5。整个文件夹拷贝</SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">&lt;%@ page contentType="text/html;charset=gb2312"%&gt;<BR>&lt;%@ page import="java.io.*" %&gt;<BR>&lt;%String url1="C:/aaa";<BR>&nbsp; String url2="d:/java/";<BR>&nbsp; (new File(url2)).mkdirs();<BR>&nbsp;File[] file=(new File(url1)).listFiles();<BR>&nbsp;for(int i=0;i&lt;file.length;i++){<BR>&nbsp; if(file[i].isFile()){<BR>&nbsp;&nbsp; file[i].toString();<BR>&nbsp;&nbsp; FileInputStream input=new FileInputStream(file[i]);<BR>&nbsp;&nbsp; FileOutputStream output=new FileOutputStream(url2+"/"+(file[i].getName()).toString());<BR>&nbsp;&nbsp; byte[] b=new byte[1024*5];<BR>&nbsp;&nbsp;&nbsp; int len;<BR>&nbsp;&nbsp;&nbsp; while((len=input.read(b))!=-1){<BR>&nbsp;&nbsp;&nbsp; output.write(b,0,len);<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; output.flush();<BR>&nbsp;&nbsp;&nbsp; output.close();<BR>&nbsp;&nbsp;&nbsp; input.close();<BR>&nbsp; }<BR>&nbsp;}<BR>%&gt; </SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">&nbsp;6。文件下载</SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">&lt;%@ page contentType="text/html; charset=gb2312" %&gt;<BR>&lt;%@ page import="java.io.*" %&gt;<BR>&lt;%<BR>&nbsp; String fileName = "zsc104.swf".toString();<BR><A href="file://读/">//读</A>到流中<BR>InputStream inStream=new FileInputStream("c:/zsc104.swf");<BR><A href="file://设/">//设</A>置输出的格式 <BR>&nbsp; response.reset(); <BR>&nbsp; response.setContentType("bin");<BR>&nbsp; response.addHeader("Content-Disposition","attachment; filename=\"" + fileName + "\"");<BR><A href="file://循/">//循</A>环取出流中的数据 <BR>&nbsp; byte[] b = new byte[100]; <BR>&nbsp; int len; <BR>&nbsp; while((len=inStream.read(b)) &gt;0) <BR>&nbsp; response.getOutputStream().write(b,0,len); &nbsp;<BR>&nbsp; inStream.close(); <BR>%&gt;</SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">&nbsp;7。数据库字段中的文件下载</SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">&lt;%@ page contentType="text/html; charset=gb2312" %&gt;<BR>&lt;%@ page import="java.sql.*"%&gt;<BR>&lt;%@ page import="java.lang.*" %&gt;<BR>&lt;%@ page import="java.io.*" %&gt;<BR>&lt;%@ page import="com.jspsmart.upload.*" %&gt;<BR>&lt;%@ page import="DBstep.iDBManager2000.*"%&gt;<BR>&lt;%<BR>int bytesum=0;<BR>int byteread=0;<BR><A href="file://打/">//打</A>开数据库<BR>ResultSet result=null;<BR>String Sql=null;<BR>PreparedStatement prestmt=null;&nbsp;<BR>DBstep.iDBManager2000 DbaObj=new DBstep.iDBManager2000();<BR>DbaObj.OpenConnection();<BR><A href="file://取/">//取</A>得数据库中的数据<BR>Sql="select&nbsp; *&nbsp; from&nbsp; t_local_zhongzhuan ";<BR>result=DbaObj.ExecuteQuery(Sql);<BR>result.next();</SPAN></STRONG><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"></SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"><A href="file://将/">file://将</A>数据库中的数据读到流中 <BR>InputStream inStream=result.getBinaryStream("content"); <BR>FileOutputStream fs=new FileOutputStream( "c:/dffdsafd.doc");</SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"></SPAN></STRONG><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">byte[]&nbsp; buffer =new&nbsp; byte[1444];<BR>int length;<BR>while ((byteread=inStream.read(buffer))!=-1)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println("&lt;DT&gt;&lt;B&gt;"+byteread+"&lt;/B&gt;&lt;/DT&gt;");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bytesum+=byteread;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(bytesum);<BR>&nbsp;&nbsp;&nbsp;&nbsp; fs.write(buffer,0,byteread);<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>%&gt;</SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">&nbsp;8。把网页保存成文件</SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">&lt;%@ page import="java.text.*"%&gt;<BR>&lt;%@ page import="java.util.*"%&gt;<BR>&lt;%@ page import="java.io.*"%&gt;<BR>&lt;%@ page import="java.net.*"%&gt;<BR>&lt;%<BR>&nbsp;URL stdURL = null;<BR>&nbsp;BufferedReader stdIn = null;<BR>&nbsp;PrintWriter stdOut = null;<BR>&nbsp;try {<BR>&nbsp;&nbsp;stdURL = new URL("http://www.163.com");<BR>&nbsp;}<BR>&nbsp;catch (MalformedURLException e) {<BR>&nbsp;&nbsp; throw e;<BR>&nbsp;}</SPAN></STRONG><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"></SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">try {<BR>&nbsp;&nbsp; stdIn = new BufferedReader(new InputStreamReader(stdURL.openStream()));<BR>&nbsp;&nbsp; stdOut = new PrintWriter(new BufferedWriter(new FileWriter("c:/163.html")));<BR>&nbsp;}<BR>&nbsp;catch (IOException e) {<BR>&nbsp;}</SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">&nbsp;/***把URL指定的页面以流的形式读出，写成指定的文件***/<BR>&nbsp;try {<BR>&nbsp;&nbsp; String strHtml = "";<BR>&nbsp;&nbsp; while((strHtml = stdIn.readLine())!=null) {<BR>&nbsp;&nbsp;&nbsp;stdOut.println(strHtml);<BR>&nbsp;&nbsp; }<BR>&nbsp;}<BR>&nbsp;catch (IOException e) {<BR>&nbsp;&nbsp; throw e;<BR>&nbsp;}<BR>&nbsp;finally {<BR>&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp; if(stdIn != null)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stdIn.close();<BR>&nbsp;&nbsp;&nbsp;&nbsp; if(stdOut != null)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stdOut.close();<BR>&nbsp;&nbsp; }<BR>&nbsp;&nbsp; catch (Exception e) {<BR>&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(e);<BR>&nbsp;&nbsp; }<BR>&nbsp;}<BR>%&gt;</SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">&nbsp;9。直接下载网上的文件</SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">&lt;%@ page import="java.io.*"%&gt;<BR>&lt;%@ page import="java.net.*"%&gt;<BR>&lt;%<BR>int bytesum=0;<BR>int byteread=0;</SPAN></STRONG><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"></SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">URL url = new URL("http://pimg.163.com/sms/micheal/logo.gif");<BR>&nbsp;URLConnection conn = url.openConnection();<BR>&nbsp;InputStream inStream = conn.getInputStream();<BR>&nbsp;FileOutputStream fs=new FileOutputStream( "c:/abc.gif");</SPAN></STRONG></P>
<P align=left><STRONG><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">&nbsp; byte[]&nbsp; buffer =new&nbsp; byte[1444];<BR>&nbsp;&nbsp; int length;<BR>&nbsp;&nbsp;&nbsp; while ((byteread=inStream.read(buffer))!=-1)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.println("&lt;DT&gt;&lt;B&gt;"+byteread+"&lt;/B&gt;&lt;/DT&gt;");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bytesum+=byteread;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(bytesum);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fs.write(buffer,0,byteread);<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>%&gt;<BR><BR></P>
<P align=left><FONT face=仿宋_GB2312 size=4>10。按行读文件<BR>&lt;%@ page contentType="text/html; charset=gb2312" %&gt;<BR>&lt;%@ page import="java.io.*" %&gt;<BR>&lt;%<BR>FileReader&nbsp;&nbsp;myFileReader=new FileReader("c:/哈哈.txt");<BR>BufferedReader myBufferedReader=new BufferedReader(myFileReader);<BR>String myString=null;<BR>String resultString=new String();<BR>while((myString=myBufferedReader.readLine())!=null)<BR>&nbsp;&nbsp;{&nbsp;&nbsp;resultString=resultString+myString+"&lt;br&gt;"; <BR>&nbsp;&nbsp; }<BR>out.println(resultString); <BR>myFileReader.close();<BR>%&gt; </FONT></P>
<P align=left><FONT face=仿宋_GB2312 size=4>11。 数据库里字段文件直接下载到客户端<BR>&lt;%@ page import="java.sql.*"%&gt;<BR>&lt;%@ page import="java.lang.*" %&gt;<BR>&lt;%@ page import="java.io.*" %&gt;<BR>&lt;%@ page import="com.jspsmart.upload.*" %&gt;<BR>&lt;%@ page import="DBstep.iDBManager2000.*"%&gt;<BR>&lt;%<BR>&nbsp;&nbsp;String fileName = "bb.doc".toString();<BR>&nbsp;&nbsp;//打开数据库<BR>&nbsp;&nbsp;ResultSet result=null;<BR>&nbsp;&nbsp;String Sql=null;<BR>&nbsp;&nbsp;PreparedStatement prestmt=null; <BR>&nbsp;&nbsp;DBstep.iDBManager2000 DbaObj=new DBstep.iDBManager2000();<BR>&nbsp;&nbsp;DbaObj.OpenConnection();<BR>//取得数据库中的数据<BR>Sql="select&nbsp;&nbsp;*&nbsp;&nbsp;from&nbsp;&nbsp;marklist order by markdate desc";<BR>result=DbaObj.ExecuteQuery(Sql);<BR>result.next();<BR>//将数据库中的数据读到流中<BR>&nbsp;&nbsp;InputStream in =result.getBinaryStream("markbody"); <BR>//设置输出的格式 <BR>&nbsp;&nbsp;response.reset(); <BR>&nbsp;&nbsp;response.setContentType("application/Msword");<BR>&nbsp;&nbsp;response.addHeader("Content-Disposition","attachment; filename=\"" + fileName + "\"");<BR>//循环取出流中的数据 <BR>&nbsp;&nbsp;byte[] b = new byte[1024]; <BR>&nbsp;&nbsp;int len; <BR>&nbsp;&nbsp;while((len=in.read(b)) &gt;0)<BR>&nbsp;&nbsp;response.getOutputStream().write(b,0,len);<BR>&nbsp;&nbsp;in.close(); <BR>%&gt;<BR></P>
<DD>12。文件夹遍历<BR>&lt;%@ page contentType="text/html; charset=gb2312" %&gt;<BR>&lt;%@ page import="java.io.*" %&gt;<BR>&lt;%<BR>String url1="C:/aaa";<BR>File&nbsp;&nbsp;f=(new File(url1));<BR>if(f.isDirectory()){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File [] fe = f.listFiles();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; go_on:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0;i&lt;fe.length;i++){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (fe[i].isDirectory()){&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;File [] fe1 = fe[i].listFiles();<BR>&nbsp;&nbsp;&nbsp;&nbsp;for (int j = 0;j&lt;fe1.length;j++){<BR>&nbsp;&nbsp;&nbsp;&nbsp;if (fe1[j].isDirectory())<BR>&nbsp;&nbsp;&nbsp;&nbsp;continue go_on;<BR>&nbsp;&nbsp;&nbsp;&nbsp;out.println(fe1[j].toString());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; else out.println(fe[i].toString());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>%&gt; 
<DD>13。通过字符编码移动文件 
<DD>&lt;%@ page contentType="text/html; charset=gb2312" %&gt;<BR>&lt;%@ page import="java.io.*" %&gt;<BR>&lt;%<BR>String ret=new String();<BR>try<BR>{<BR>&nbsp;&nbsp;byte[] bytes=new byte[102400];<BR>&nbsp;&nbsp;InputStream in=new FileInputStream("c:/aaa.doc");<BR>&nbsp;&nbsp;in.read(bytes);<BR>&nbsp;&nbsp;ret=new sun.misc.BASE64Encoder().encode(bytes); //具体的编码方法<BR>&nbsp;&nbsp;in.close();<BR>}<BR>catch(FileNotFoundException e)<BR>{<BR>&nbsp;&nbsp;e.printStackTrace();<BR>}<BR>catch(java.io.IOException ex)<BR>{<BR>&nbsp;&nbsp;ex.printStackTrace();<BR>}<BR>out.println(ret);<BR><BR>byte[] bytes = new sun.misc.BASE64Decoder().decodeBuffer(ret);&nbsp;&nbsp;&nbsp;&nbsp;<BR>java.io.ByteArrayInputStream&nbsp;&nbsp;inStream=new java.io.ByteArrayInputStream(bytes);<BR>byte[]&nbsp;&nbsp;buffer =new&nbsp;&nbsp;byte[1444];<BR>FileOutputStream fs=new FileOutputStream( "d:/aaa.doc");<BR>int bytesum=0;<BR>int byteread=0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>while ((byteread=inStream.read(buffer))!=-1)<BR>&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp; bytesum+=byteread; <BR>&nbsp;&nbsp;&nbsp;&nbsp; fs.write(buffer,0,byteread);<BR>&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;<BR>%&gt; 
<P>14。把文件编码成base64字符串<BR>&lt;%<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String ret=new String();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[] bytes=new byte[1024];<BR>&nbsp;&nbsp;&nbsp;&nbsp; String aa="aaaa";<BR>&nbsp;&nbsp;&nbsp;&nbsp; bytes=aa.getBytes();<BR>&nbsp;&nbsp;&nbsp;&nbsp; ret=new sun.misc.BASE64Encoder().encode(bytes); //具体的编码方法<BR>&nbsp;&nbsp;bytes = new sun.misc.BASE64Decoder().decodeBuffer(ret);&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;aa=new String(bytes);<BR>&nbsp;&nbsp;out.println(aa);<BR>%&gt; </P></FONT></DD></SPAN></STRONG><img src ="http://www.blogjava.net/jackybu/aggbug/2510.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackybu/" target="_blank">辰</a> 2005-03-28 09:55 <a href="http://www.blogjava.net/jackybu/articles/2510.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Java設計模式]學習心得作者：板橋里人</title><link>http://www.blogjava.net/jackybu/articles/2509.html</link><dc:creator>辰</dc:creator><author>辰</author><pubDate>Mon, 28 Mar 2005 01:52:00 GMT</pubDate><guid>http://www.blogjava.net/jackybu/articles/2509.html</guid><wfw:comment>http://www.blogjava.net/jackybu/comments/2509.html</wfw:comment><comments>http://www.blogjava.net/jackybu/articles/2509.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackybu/comments/commentRss/2509.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackybu/services/trackbacks/2509.html</trackback:ping><description><![CDATA[<TABLE style="BORDER-COLLAPSE: collapse" borderColor=#111111 cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width="50%" colSpan=2><SPAN style="FONT-FAMILY: Arial">整個設計模式貫穿一個原理</SPAN><FONT face=Arial><SPAN lang=EN-US>:</SPAN></FONT><SPAN style="FONT-FAMILY: Arial">面對介面編程，而不是面對實現</SPAN><FONT face=Arial><SPAN lang=EN-US>，</SPAN></FONT><SPAN style="FONT-FAMILY: Arial">（面向物件編程應該改爲面向介面編程）</SPAN><FONT face=Arial><SPAN lang=EN-US>。</SPAN></FONT><SPAN style="FONT-FAMILY: Arial">目標原則是</SPAN><FONT face=Arial><SPAN lang=EN-US>:</SPAN></FONT><SPAN style="FONT-FAMILY: Arial">降低耦合</SPAN><FONT face=Arial><SPAN lang=EN-US>，</SPAN></FONT><SPAN style="FONT-FAMILY: Arial">增強靈活性</SPAN><FONT face=Arial><SPAN lang=EN-US>。 </SPAN></FONT></TD></TR>
<TR>
<TD width="50%" colSpan=2>　</TD></TR>
<TR>
<TD width="50%" colSpan=2>
<P style="TEXT-ALIGN: center" align=center><B><SPAN style="FONT-SIZE: 16pt; FONT-FAMILY: 標楷體; text-shadow: auto">創建模式</SPAN></B></P></TD></TR>
<TR>
<TD width="8%">　</TD>
<TD width="42%">
<P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=left><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_Factory.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>设计模式之Factory(工厂方法和抽象工厂)</FONT></SPAN></A></SPAN></P>
<P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=left>使用工厂模式就象使用new一样频繁.</P></TD></TR>
<TR>
<TD width="8%">　</TD>
<TD width="42%">　</TD></TR>
<TR>
<TD width="8%">　</TD>
<TD width="42%">
<P class=MsoNormal><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_Prototype.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT size=3><FONT face=Arial>Prototype(</FONT><SPAN style="FONT-FAMILY: Arial">原型</SPAN><FONT face=Arial>)</FONT></FONT></A><FONT face=Arial size=3><BR></FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>用原型實例指定創建物件的種類，並且通過拷貝這些原型創建新的物件。</FONT></SPAN></P></TD></TR>
<TR>
<TD width="8%">　</TD>
<TD width="42%">　</TD></TR>
<TR>
<TD width="8%">　</TD>
<TD width="42%">
<P class=MsoNormal><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_Builder.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT face=Arial size=3>Builder</FONT></A><FONT face=Arial size=3><BR></FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>汽車由車輪</FONT></SPAN><FONT face=Arial size=3> </FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>方向盤</FONT></SPAN><FONT face=Arial size=3> </FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>發動機很多部件組成，同時，將這些部件組裝成汽車也是一件複雜的工作，</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>Builder</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>模式就是將這兩種情況分開進行。</FONT></SPAN></P></TD></TR>
<TR>
<TD width="8%">　</TD>
<TD width="42%">　</TD></TR>
<TR>
<TD width="8%">　</TD>
<TD width="42%">
<P class=MsoNormal><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_Singleton.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT size=3><FONT face=Arial>Singleton(</FONT><SPAN style="FONT-FAMILY: Arial">單態</SPAN><FONT face=Arial>)</FONT></FONT></A><FONT face=Arial size=3><BR></FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>保證一個類只有一個實例</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>,</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>並提供一個訪問它的全局訪問點</FONT></SPAN><FONT face=Arial size=3> </FONT></P></TD></TR>
<TR>
<TD width="8%">　</TD>
<TD width="42%">　</TD></TR>
<TR>
<TD width="50%" colSpan=2>
<P align=center><B><SPAN style="FONT-SIZE: 16pt; FONT-FAMILY: 標楷體; text-shadow: auto">結構模式</SPAN></B></P></TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%"><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_Facade.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT face=Arial size=3>Facade</FONT></A><FONT face=Arial size=3><BR></FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>可擴展的使用</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>JDBC</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>針對不同的資料庫編程</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>,Facade</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>提供了一種靈活的實現</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>。</FONT></SPAN></TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">　</TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%"><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_proxy.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT face=Arial size=3>Proxy</FONT></A><FONT face=Arial size=3><BR></FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>以</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>Jive</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>爲例</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>,</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>剖析代理模式在用戶級別授權機制上的應用</FONT></SPAN></TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">　</TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%"><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_adapter.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT face=Arial size=3>Adapter</FONT></A><FONT face=Arial size=3><BR></FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>使用類再生的兩個方式</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>:</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>組合</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>(new)</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>和繼承</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>(extends),</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>這個已經在</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>"thinking in java"</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>中提到過</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>。</FONT></SPAN></TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">　</TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">
<P class=MsoNormal><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_Composite.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT face=Arial size=3>Composite</FONT></A><FONT face=Arial size=3><BR></FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>就是將類用樹形結構組合成一個單位</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>。</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>你向別人介紹你是某單位，你是單位元元中的一個元素，別人和你做買賣，相當於和單位做買賣。文章中還對</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>Jive</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>再進行了剖析。</FONT></SPAN></P></TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">　</TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">
<P class=MsoNormal><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_Decorator.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT face=Arial size=3>Decorator</FONT></A><FONT face=Arial size=3><BR>Decorator</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>是個油漆工</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>,</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>給你的東東的外表刷上美麗的顔色</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>。</SPAN></FONT></P></TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">　</TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">
<P class=MsoNormal><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_Bridge.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT face=Arial size=3>Bridge</FONT></A><FONT face=Arial size=3><BR></FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>將</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>"</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>牛郎織女</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>"</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>分開</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>(</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>本應在一起</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>,</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>分開他們</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>,</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>形成兩個介面</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>),</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>在他們之間搭建一個橋</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>(</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>動態的結合</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>)</FONT></SPAN></P></TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">　</TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">
<P class=MsoNormal><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_Flyweight.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT face=Arial size=3>Flyweight</FONT></A><FONT face=Arial size=3><BR></FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>提供</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>Java</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>運行性能</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>,</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>降低小而大量重復的類的開銷</FONT></SPAN><SPAN lang=EN-US><FONT face=Arial size=3>。</FONT></SPAN></P></TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">　</TD></TR>
<TR>
<TD width="50%" colSpan=2>
<P style="TEXT-ALIGN: center" align=center><B><SPAN style="FONT-SIZE: 16pt; FONT-FAMILY: 標楷體; text-shadow: auto">行爲模式</SPAN></B></P></TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">
<P class=MsoNormal><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_Template.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT face=Arial size=3>Template</FONT></A><FONT face=Arial size=3><BR></FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>實際上向你介紹了爲什麽要使用</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>Java </SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>抽象類</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>,</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>該模式原理簡單</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>,</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>使用很普遍</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>。</SPAN></FONT></P></TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">　</TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">
<P class=MsoNormal><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_Memento.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT face=Arial size=3>Memento</FONT></A><FONT face=Arial size=3><BR></FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>很簡單一個模式</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>,</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>就是在記憶體中保留原來資料的拷貝</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>。 </SPAN></FONT></P></TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">　</TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">
<P class=MsoNormal><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_Observer.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT face=Arial size=3>Observer</FONT></A><FONT face=Arial size=3><BR></FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>介紹如何使用</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>Java API</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>提供的現成</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>Observer</SPAN></FONT></P></TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">　</TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">
<P class=MsoNormal><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_CoR.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT face=Arial size=3>Chain of Responsibility</FONT></A><FONT face=Arial size=3><BR></FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>各司其職的類串成一串</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>,</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>好象擊鼓傳花</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>,</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>當然如果自己能完成</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>,</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>就不要推委給下一個</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>。</SPAN></FONT></P></TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">　</TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">
<P class=MsoNormal><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_command.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT face=Arial size=3>Command</FONT></A><FONT face=Arial size=3><BR></FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>什麽是將行爲封裝</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>,Command</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>是最好的說明</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>。</SPAN></FONT></P></TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">　</TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">
<P class=MsoNormal><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_state.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT face=Arial size=3>State</FONT></A><FONT face=Arial size=3><BR></FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>狀態是編程中經常碰到的實例</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>,</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>將狀態物件化</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>,</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設立狀態變換器</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>,</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>便可在狀態中輕鬆切換</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>。</SPAN></FONT></P></TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">　</TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">
<P class=MsoNormal><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_strategy.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT face=Arial size=3>Strategy</FONT></A><FONT face=Arial size=3><BR></FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>不同演算法各自封裝</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>,</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>用戶端可隨意挑選需要的演算法</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>。</SPAN></FONT></P></TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">　</TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">
<P class=MsoNormal><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_Mediator.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT face=Arial size=3>Mediator</FONT></A><FONT face=Arial size=3><BR>Mediator</FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>很象十字路口的紅綠燈</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>,</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>每個車輛只需和紅綠燈交互就可以</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>。</SPAN></FONT></P></TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">　</TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">
<P class=MsoNormal><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_Interpreter.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT face=Arial size=3>Interpreter</FONT></A><FONT face=Arial size=3><BR></FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>主要用來對語言的分析</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>,</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>應用機會不多</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>。</SPAN></FONT></P></TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">　</TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">
<P class=MsoNormal><SPAN lang=EN-US><A href="http://nullhue.myrice.com/javahtml/desingpattern/javapattern/info_1/Jdon_Visitor.htm"><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT face=Arial size=3>Visitor</FONT></A><FONT face=Arial size=3><BR></FONT></SPAN><SPAN style="FONT-FAMILY: Arial"><FONT size=3>訪問者在進行訪問時</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>,</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>完成一系列實質性操作</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>,</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>而且還可以擴展</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>。</SPAN></FONT></P></TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">　</TD></TR>
<TR>
<TD width="7%">　</TD>
<TD width="43%">
<P class=MsoNormal><SPAN style="FONT-FAMILY: Arial"><FONT size=3>設計模式之</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>Iterator<BR></SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>這個模式已經被用來遍曆</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>Collection</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>中物件</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>。</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>使用頻率很高</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>。</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>在</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>Java</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>中無需專門闡述</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>,</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>在大多數場合也無需自己製造一個</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>Iterator,</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>只要將物件裝入</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>Collection</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>中，我們就直接可以使用</FONT></SPAN><FONT face=Arial size=3><SPAN lang=EN-US>Iterator</SPAN></FONT><SPAN style="FONT-FAMILY: Arial"><FONT size=3>模式。</FONT></SPAN></P></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/jackybu/aggbug/2509.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackybu/" target="_blank">辰</a> 2005-03-28 09:52 <a href="http://www.blogjava.net/jackybu/articles/2509.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java类成员初始化顺序</title><link>http://www.blogjava.net/jackybu/articles/1738.html</link><dc:creator>辰</dc:creator><author>辰</author><pubDate>Sat, 05 Mar 2005 10:38:00 GMT</pubDate><guid>http://www.blogjava.net/jackybu/articles/1738.html</guid><wfw:comment>http://www.blogjava.net/jackybu/comments/1738.html</wfw:comment><comments>http://www.blogjava.net/jackybu/articles/1738.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackybu/comments/commentRss/1738.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackybu/services/trackbacks/1738.html</trackback:ping><description><![CDATA[基本原则：<BR>静态优先，具体顺序如下：<BR><BR>1、static字段<BR>2、statici初始化块<BR>3、static方法<BR>4、实例字段<BR>5、实例初始化块<BR>6、构造方法<BR>7、实例方法<BR><img src ="http://www.blogjava.net/jackybu/aggbug/1738.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackybu/" target="_blank">辰</a> 2005-03-05 18:38 <a href="http://www.blogjava.net/jackybu/articles/1738.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>谈谈 Java 中 this 的使用</title><link>http://www.blogjava.net/jackybu/articles/1732.html</link><dc:creator>辰</dc:creator><author>辰</author><pubDate>Sat, 05 Mar 2005 10:16:00 GMT</pubDate><guid>http://www.blogjava.net/jackybu/articles/1732.html</guid><wfw:comment>http://www.blogjava.net/jackybu/comments/1732.html</wfw:comment><comments>http://www.blogjava.net/jackybu/articles/1732.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackybu/comments/commentRss/1732.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackybu/services/trackbacks/1732.html</trackback:ping><description><![CDATA[1. this是指当前对象自己。 <BR>当在一个类中要明确指出使用对象自己的的变量或函数时就应该加上this引用。如下面这<BR>个例子中: <BR><BR>public class A { <BR><BR>String s = "Hello"; <BR><BR>public A(String s) { <BR>System.out.println("s = " + s); <BR>System.out.println("1 -&gt; this.s = " + this.s); <BR>this.s = s; <BR>System.out.println("2 -&gt; this.s = " + this.s); <BR>} <BR><BR>public static void main(String[] args) { <BR>new A("HelloWorld!"); <BR>} <BR>} <BR><BR>运行结果： <BR><BR>s = HelloWorld! <BR>1 -&gt; this.s = Hello <BR>2 -&gt; this.s = HelloWorld! <BR><BR>在这个例子中，构造函数A中，参数s与类A的变量s同名，这时如果直接对s进行操作则是对<BR>参数s进行操作。若要对类A的变量s进行操作就应该用this进行引用。运行结果的第一行就<BR>是直接对参数s进行打印结果；后面两行分别是对对象A的变量s进行操作前后的打印结果。<BR> <BR><BR>2. 把this作为参数传递 <BR>当你要把自己作为参数传递给别的对象时，也可以用this。如： <BR><BR>public class A { <BR>public A() { <BR>new B(this).print(); <BR>} <BR><BR>public void print() { <BR>System.out.println("Hello from A!"); <BR>} <BR>} <BR><BR>public class B { <BR>A a; <BR>public B(A a) { <BR>this.a = a; <BR>} <BR><BR>public void print() { <BR>a.print(); <BR>System.out.println("Hello from B!"); <BR>} <BR>} <BR><BR>运行结果： <BR>Hello from A! <BR>Hello from B! <BR><BR>在这个例子中，对象A的构造函数中，用new B(this)把对象A自己作为参数传递给了对象B<BR>的构造函数。 <BR><BR>3. 注意匿名类和内部类中的中的this。 <BR>有时候，我们会用到一些内部类和匿名类。当在匿名类中用this时，这个this则指的是匿<BR>名类或内部类本身。这时如果我们要使用外部类的方法和变量的话，则应该加上外部类的<BR>类名。如下面这个例子： <BR><BR>public class A { <BR>int i = 1; <BR><BR>public A() { <BR>Thread thread = new Thread() { <BR>public void run() { <BR>for(;;) { <BR>A.this.run(); <BR>try { <BR>sleep(1000); <BR>} catch(InterruptedException ie) { <BR>} <BR>} <BR>} <BR>}; <BR>thread.start(); <BR>} <BR><BR>public void run() { <BR>System.out.println("i = " + i); <BR>i++; <BR>} <BR><BR>public static void main(String[] args) throws Exception { <BR>new A(); <BR>} <BR><BR>} <BR><BR>在上面这个例子中, thread 是一个匿名类对象，在它的定义中，它的 run 函数里用到了<BR>外部类的 run 函数。这时由于函数同名，直接调用就不行了。这时有两种办法，一种就是<BR>把外部的 run 函数换一个名字，但这种办法对于一个开发到中途的应用来说是不可取的。<BR>那么就可以用这个例子中的办法用外部类的类名加上 this 引用来说明要调用的是外部类<BR>的方法 run<BR><img src ="http://www.blogjava.net/jackybu/aggbug/1732.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackybu/" target="_blank">辰</a> 2005-03-05 18:16 <a href="http://www.blogjava.net/jackybu/articles/1732.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java的基础问题（三） </title><link>http://www.blogjava.net/jackybu/articles/1727.html</link><dc:creator>辰</dc:creator><author>辰</author><pubDate>Sat, 05 Mar 2005 10:07:00 GMT</pubDate><guid>http://www.blogjava.net/jackybu/articles/1727.html</guid><wfw:comment>http://www.blogjava.net/jackybu/comments/1727.html</wfw:comment><comments>http://www.blogjava.net/jackybu/articles/1727.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackybu/comments/commentRss/1727.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackybu/services/trackbacks/1727.html</trackback:ping><description><![CDATA[问题1<BR>我声明了什么！<BR><BR>String s = "Hello world!";<BR><BR>许多人都做过这样的事情，但是，我们到底声明了什么？回答通常是：一个String，内容<BR>是“Hello world!”。这样模糊的回答通常是概念不清的根源。如果要准确的回答，一半<BR>的人大概会回答错误。<BR>这个语句声明的是一个指向对象的引用，名为“s”，可以指向类型为String的任何对象，<BR>目前指向"Hello world!"这个String类型的对象。这就是真正发生的事情。我们并没有声<BR>明一个String对象，我们只是声明了一个只能指向String对象的引用变量。所以，如果在<BR>刚才那句语句后面，如果再运行一句：<BR><BR>String string = s;<BR><BR>我们是声明了另外一个只能指向String对象的引用，名为string，并没有第二个对象产生<BR>，string还是指向原来那个对象，也就是，和s指向同一个对象。<BR>String s1 = "This is cool!"; // 生成一个字符串对象[OBJ_1]，将其引用赋值给s1<BR>String s2 = "This is cool!"; // 将同样的对象[OBJ_1]的引用赋值给s2<BR>String s3 = new String("This is cool!"); // 新建一个字符串对象[OBJ_2]，其引用赋<BR>值给s3;<BR>s1 = s2; // 将s2保存的[OBJ_1]的引用赋值给s1，没有实际效果<BR>s3 = "This is cool!"; // 将[OBJ_1]的引用赋值给s3，s3原先引用的[OBJ_2]不再被引用<BR><BR><BR>这样的代码共有产生2个String实例，有1对象可以被GC。<BR><BR>问题2，"=="和equals方法究竟有什么区别？<BR><BR>==操作符专门用来比较变量的值是否相等。比较好理解的一点是：<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。<BR><BR>根据前一帖说过，对象变量其实是一个引用，它们的值是指向对象所在的内存地址，而不<BR>是对象本身。a和b都使用了new操作符，意味着将在内存中产生两个内容为"foo"的字符串<BR>，既然是“两个”，它们自然位于不同的内存地址。a和b的值其实是两个不同的内存地址<BR>的值，所以使用"=="操作符，结果会是false。诚然，a和b所指的对象，它们的内容都是"<BR>foo"，应该是“相等”，但是==操作符并不涉及到对象内容的比较。<BR>对象内容的比较，正是equals方法做的事。<BR><BR>看一下Object对象的equals方法是如何实现的：<BR>boolean equals(Object o){<BR><BR>return this==o;<BR><BR>}<BR>Object对象默认使用了==操作符。所以如果你自创的类没有覆盖equals方法，那你的类使<BR>用equals和使用==会得到同样的结果。同样也可以看出，Object的equals方法没有达到eq<BR>uals方法应该达到的目标：比较两个对象内容是否相等。因为答案应该由类的创建者决定<BR>，所以Object把这个任务留给了类的创建者。<BR><BR>看一下一个极端的类：<BR>Class Monster{<BR>private String content;<BR>...<BR>boolean equals(Object another){ return true;}<BR><BR>}<BR>我覆盖了equals方法。这个实现会导致无论Monster实例内容如何，它们之间的比较永远返<BR>回true。<BR><BR>所以当你是用equals方法判断对象的内容是否相等，请不要想当然。因为可能你认为相等<BR>，而这个类的作者不这样认为，而类的equals方法的实现是由他掌握的。如果你需要使用<BR>equals方法，或者使用任何基于散列码的集合（HashSet,HashMap,HashTable），请察看一<BR>下 java doc以确认这个类的equals逻辑是如何实现的。<BR><BR>问题3<BR>String到底变了没有<BR><BR>没有。因为String被设计成不可变(immutable)类，所以它的所有对象都是不可变对象。请<BR>看下列代码：<BR><BR>String s = "Hello";<BR>s = s + " world!";<BR><BR>s所指向的对象是否改变了呢？从本系列第一篇的结论很容易导出这个结论。我们来看看发<BR>生了什么事情。在这段代码中，s原先指向一个String对象，内容是"Hello"，然后我们对<BR>s进行了+操作，那么s所指向的那个对象是否发生了改变呢？答案是没有。这时，s不指向<BR>原来那个对象了，而指向了另一个String对象，内容为"Hello world!"，原来那个对象还<BR>存在于内存之中，只是s这个引用变量不再指向它了。<BR>通过上面的说明，我们很容易导出另一个结论，如果经常对字符串进行各种各样的修改，<BR>或者说，不可预见的修改，那么使用String来代表字符串的话会引起很大的内存开销。因<BR>为String对象建立之后不能再改变，所以对于每一个不同的字符串，都需要一个String对<BR>象来表示。这时，应该考虑使用StringBuffer 类，它允许修改，而不是每个不同的字符串<BR>都要生成一个新的对象。并且，这两种类的对象转换十分容易。<BR>同时，我们还可以知道，如果要使用内容相同的字符串，不必每次都new一个String。例如<BR>我们要在构造器中对一个名叫s的String引用变量进行初始化，把它设置为初始值，应当这<BR>样做：<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>后者每次都会调用构造器，生成新对象，性能低下且内存开销大，并且没有意义，因为St<BR>ring对象不可改变，所以对于内容相同的字符串，只要一个String对象来表示就可以了。<BR>也就说，多次调用上面的构造器创建多个对象，他们的String类型属性s都指向同一个对象<BR>。<BR>上面的结论还基于这样一个事实：对于字符串常量，如果内容相同，Java认为它们代表同<BR>一个String对象。而用关键字new调用构造器，总是会创建一个新的对象，无论内容是否相<BR>同。<BR>至于为什么要把String类设计成不可变类，是它的用途决定的。其实不只String，很多Ja<BR>va标准类库中的类都是不可变的。在开发一个系统的时候，我们有时候也需要设计不可变<BR>类，来传递一组相关的值，这也是面向对象思想的体现。不可变类有一些优点，比如因为<BR>它的对象是只读的，所以多线程并发访问也不会有任何问题。当然也有一些缺点，比如每<BR>个不同的状态都要一个对象来代表，可能会造成性能上的问题。所以Java标准类库还提供<BR>了一个可变版本，即 StringBuffer。<BR><BR>问题4，final关键字到底修饰了什么？<BR>final使得被修饰的变量"不变"，但是由于对象型变量的本质是“引用”，使得“不变”也<BR>有了两种含义：引用本身的不变，和引用指向的对象不变。<BR><BR>引用本身的不变：<BR>final StringBuffer a=new StringBuffer("immutable");<BR>final StringBuffer b=new StringBuffer("not immutable");<BR>a=b;//编译期错误<BR><BR>引用指向的对象不变：<BR>final StringBuffer a=new StringBuffer("immutable");<BR>a.append(" broken!"); //编译通过<BR><BR>可见，final只对引用的“值”(也即它所指向的那个对象的内存地址)有效，它迫使引用只<BR>能指向初始指向的那个对象，改变它的指向会导致编译期错误。至于它所指向的对象的变<BR>化，final是不负责的。这很类似==操作符：==操作符只负责引用的“值”相等，至于这个<BR>地址所指向的对象内容是否相等， ==操作符是不管的。<BR><BR>理解final问题有很重要的含义。许多程序漏洞都基于此----final只能保证引用永远指向<BR>固定对象，不能保证那个对象的状态不变。在多线程的操作中,一个对象会被多个线程共享<BR>或修改，一个线程对对象无意识的修改可能会导致另一个使用此对象的线程崩溃。一个错<BR>误的解决方法就是在此对象新建的时候把它声明为final，意图使得它“永远不变”。其实<BR>那是徒劳的。<BR><BR>问题5<BR>到底要怎么样初始化！<BR><BR>本问题讨论变量的初始化，所以先来看一下Java中有哪些种类的变量。<BR>1. 类的属性，或者叫值域<BR>2. 方法里的局部变量<BR>3. 方法的参数<BR><BR>对于第一种变量，Java虚拟机会自动进行初始化。如果给出了初始值，则初始化为该初始<BR>值。如果没有给出，则把它初始化为该类型变量的默认初始值。<BR><BR>int类型变量默认初始值为0<BR>float类型变量默认初始值为0.0f<BR>double类型变量默认初始值为0.0<BR>boolean类型变量默认初始值为false<BR>char类型变量默认初始值为0(ASCII码)<BR>long类型变量默认初始值为0<BR>byte类型变量默认初始值为0<BR>short类型变量默认初始值为0<BR>所有对象引用类型变量默认初始值为null，即不指向任何对象。注意数组本身也是对象，<BR>所以没有初始化的数组引用在自动初始化后其值也是null。<BR><BR>对于两种不同的类属性，static属性与instance属性，初始化的时机是不同的。instance<BR>属性在创建实例的时候初始化， static属性在类加载，也就是第一次用到这个类的时候初<BR>始化，对于后来的实例的创建，不再次进行初始化。这个问题会在以后的系列中进行详细<BR>讨论。<BR><BR>对于第二种变量，必须明确地进行初始化。如果再没有初始化之前就试图使用它，编译器<BR>会抗议。如果初始化的语句在try块中或if块中，也必须要让它在第一次使用前一定能够得<BR>到赋值。也就是说，把初始化语句放在只有if块的条件判断语句中编译器也会抗议，因为<BR>执行的时候可能不符合if后面的判断条件，如此一来初始化语句就不会被执行了，这就违<BR>反了局部变量使用前必须初始化的规定。但如果在else块中也有初始化语句，就可以通过<BR>编译，因为无论如何，总有至少一条初始化语句会被执行，不会发生使用前未被初始化的<BR>事情。对于try-catch也是一样，如果只有在try块里才有初始化语句，编译部通过。如果<BR>在catch或finally里也有，则可以通过编译。总之，要保证局部变量在使用之前一定被初<BR>始化了。所以，一个好的做法是在声明他们的时候就初始化他们，如果不知道要出事化成<BR>什么值好，就用上面的默认值吧！<BR><BR>其实第三种变量和第二种本质上是一样的，都是方法中的局部变量。只不过作为参数，肯<BR>定是被初始化过的，传入的值就是初始值，所以不需要初始化。<BR><BR>问题6<BR>instanceof是什么东东？<BR><BR>instanceof是Java的一个二元操作符，和==，&gt;，&lt;是同一类东东。由于它是由字母组成的<BR>，所以也是Java的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例，<BR>返回boolean类型的数据。举个例子：<BR><BR>String s = "I AM an Object!";<BR>boolean isObject = s instanceof Object;<BR><BR>我们声明了一个String对象引用，指向一个String对象，然后用instancof来测试它所指向<BR>的对象是否是Object类的一个实例，显然，这是真的，所以返回true，也就是isObject的<BR>值为True。<BR>instanceof有一些用处。比如我们写了一个处理账单的系统，其中有这样三个类：<BR><BR>public class Bill {//省略细节}<BR>public class PhoneBill extends Bill {//省略细节}<BR>public class GasBill extends Bill {//省略细节}<BR><BR>在处理程序里有一个方法，接受一个Bill类型的对象，计算金额。假设两种账单计算方法<BR>不同，而传入的Bill对象可能是两种中的任何一种，所以要用instanceof来判断：<BR><BR>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>这样就可以用一个方法处理两种子类。<BR><BR>然而，这种做法通常被认为是没有好好利用面向对象中的多态性。其实上面的功能要求用<BR>方法重载完全可以实现，这是面向对象变成应有的做法，避免回到结构化编程模式。只要<BR>提供两个名字和返回值都相同，接受参数类型不同的方法就可以了：<BR><BR>public double calculate(PhoneBill bill) {<BR>&nbsp; //计算电话账单<BR>}<BR><BR>public double calculate(GasBill bill) {<BR>&nbsp; //计算燃气账单<BR>}<BR><BR>所以，使用instanceof在绝大多数情况下并不是推荐的做法，应当好好利用多态。<BR><BR>参考：<A href="http://community.csdn.net/Expert/topic/3364/3364544.xml?temp=8.037966E-0" target=_blank>http://community.csdn.net/Expert/topic/3364/3364544.xml?temp=8.037966E-0</A><BR>2<BR><img src ="http://www.blogjava.net/jackybu/aggbug/1727.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackybu/" target="_blank">辰</a> 2005-03-05 18:07 <a href="http://www.blogjava.net/jackybu/articles/1727.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java的基础问题（四）</title><link>http://www.blogjava.net/jackybu/articles/1728.html</link><dc:creator>辰</dc:creator><author>辰</author><pubDate>Sat, 05 Mar 2005 10:07:00 GMT</pubDate><guid>http://www.blogjava.net/jackybu/articles/1728.html</guid><wfw:comment>http://www.blogjava.net/jackybu/comments/1728.html</wfw:comment><comments>http://www.blogjava.net/jackybu/articles/1728.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackybu/comments/commentRss/1728.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackybu/services/trackbacks/1728.html</trackback:ping><description><![CDATA[１.String类和StringBuffer类 <BR><BR>它们都是处理字符串的类,但是它们有一个最大的区别,那就是,String对象是存储你不能改<BR>动的文本字符 <BR>串,相反,如果你希望改动,则应使用StringBuffer类作为替换. <BR>eg1: <BR>...... <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 <BR>运行结果: <BR>You are fired! <BR>You are hired! <BR>结果分析: <BR>从结果,明显可知,s1的值并没有被改变,而第一行结果只是屏幕内容的替换. <BR>eg2: <BR>...... <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 <BR>运行结果: <BR>Hello to Java! <BR>结果分析: <BR>显然,s2的值已改变. <BR><BR>２.位逻辑与条件逻辑 <BR><BR>首先声明, 为了与位逻辑更好区分开来,我把通常所说的逻辑取了个别名叫做条件逻辑. <BR><BR>它们都有各自的操作符,位逻辑操作符有:&amp;(与运算),^(异或运算),|(或运算);条件逻辑操<BR>作符有:&amp;&amp;(并 <BR>且),||(或者). <BR>位逻辑运算通常是针对两个数而言,实行位操作;而条件逻辑运算是针对两个条件表达式而<BR>言,实行条件操 <BR>作.其实,位逻辑操作符一样可以实现条件操作,但是此时有一个重要的区别:用位操作符时<BR>,不管操作符两边的 <BR>条件表达式成不成立,它都要通通进行运算判断,而条件逻辑操作符不一样了,如果通过左侧<BR>的操作数就可以进 <BR>行它们需要的判断,那么它就不会再计算右侧的操作数了,这种情况叫短路.废话少说!且看<BR>下例. <BR>eg1: <BR>...... <BR>//omit some code <BR>double 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 <BR>运行结果: <BR>The value is too small. <BR>结果分析: <BR>照理说应会出现除数为0的错误,但是我刚才说了,由于条件逻辑操作符是短路操作符,显然<BR>,value!=0不 <BR>成立,立即就可作出判断应执行else后的语句,所以它就不再会运算判断1/value&lt;1000了.如<BR>果不懂请再看一 <BR>例: <BR>eg2: <BR>...... <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 <BR>运行结果: <BR>int2=2.0 <BR>int3=1.0 <BR>结果分析: <BR>我想不用我分析了,你应该懂了吧. <BR><BR>３.实例变量与类变量 <BR><BR>可以通过两种方法在类中存储数据───作为实例变量和类变量.实例变量是特定于对象的<BR>,如果你有两个对 <BR>象(即一个类的两个实例),每一个对象中的实例变量独立于另一个对象中的实例变量的;另<BR>一方面,两个对象的 <BR>类变量均指向相同的数据,并因此面保存相同的值,换句话说,类变量被类中的所有对象共享<BR>.差点忘了,它们在 <BR>形式上的区别,类变量在声明时比实例变量多一个static. <BR>eg: <BR>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>} <BR>运行结果: <BR>b.intdata=0 <BR>结果分析: <BR>可以看出,a.intdata的值虽然变了,但并没有影响b.intdata.但是如果在data类中声明int<BR>data时,在其前 <BR>面加上static就变成类变量了(即:public static int intdata=0;),则此时运行结果会变<BR>为: <BR>b.intdata=1 <BR>这次a.intdata值的改变可把b.intdata影响了,事实上,对象a和b的类变量均指向相同的数<BR>据,所有值一 <BR>样,这就是类变量的作用. <BR><BR>４.实例方法,类方法,构造器方法 <BR><BR>我们通常所说的方法系指实例方法,就像c语言中的函数一样,其具体方法我就不用说了,在<BR>这里我主要是 <BR>用它来区分类方法和构造器方法.类方法与实例方法最大的区别是:在形式上类方法多一个<BR>static,在用法上, <BR>不必创建对象就可直接调用类方法(而实例方法却一定要先创建对象,再通过对象调用). <BR><BR>eg: <BR>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>} <BR><BR>注: 也可按通常的方法,即先创建对象,再调用方法,不过,这时static就无任何意义了. <BR><BR>再说说构造器方法,它是用来初始化对象中的数据的一种方法,创建很容易,只需在类中加上<BR>一个与这个类 <BR>同名的方法,不需要在前面加任何访问说明符或者返回类型,另外,构造器也一样可以向方法<BR>一样传递参数. <BR>eg: <BR>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>} <BR><BR>５.接口与类 <BR><BR>类是对一类特定对象的规格说明,我们可以类定义创建对象,通过创建对象来组合所有属于<BR>该类的组件,而 <BR>接口不能这样做.而接口实质上就是一个常量和抽象方法的集合,要使用一个接口,就需要在<BR>类中实现这个接 <BR>口,然后作为类定义的一部分,编写接口中声明的每一个方法,接口中的方法永远是public,<BR>abstract,接口中的 <BR>常量永远是public static和final,因此不需要为它们说明属性. <BR>因为在Java中不支持多重继承,但是,可以用接口来实现类似的功能,这是接口的重要作用之<BR>一. <BR>eg: <BR>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>//在类中必须实现接口中声明的所有方法.(当然也可不必,但是要用到适配器类或用抽象类<BR><img src ="http://www.blogjava.net/jackybu/aggbug/1728.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackybu/" target="_blank">辰</a> 2005-03-05 18:07 <a href="http://www.blogjava.net/jackybu/articles/1728.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java的基础问题（二）</title><link>http://www.blogjava.net/jackybu/articles/1724.html</link><dc:creator>辰</dc:creator><author>辰</author><pubDate>Sat, 05 Mar 2005 10:04:00 GMT</pubDate><guid>http://www.blogjava.net/jackybu/articles/1724.html</guid><wfw:comment>http://www.blogjava.net/jackybu/comments/1724.html</wfw:comment><comments>http://www.blogjava.net/jackybu/articles/1724.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackybu/comments/commentRss/1724.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackybu/services/trackbacks/1724.html</trackback:ping><description><![CDATA[目录：<BR><BR>一、准备篇<BR>Q1.1&nbsp; 什么是J2EE？它和普通的Java有什么不同？<BR>Q1.2&nbsp; J2EE好学吗？<BR>Q1.3 J2EE有什么用？<BR>Q1.4 学J2EE有前途吗？<BR>Q1.5 据说J2EE的性能不如.NET好，是真的吗？<BR>Q1.6 听你说了这么多，我想学着玩玩。<BR>Q1.7 学习J2EE该怎么开始？<BR>Q1.8 我下了一个J2EE服务器但是不会配置。<BR>Q1.9 我发现你没有提到Tomcat。<BR><BR>二、 Servlet/JSP篇<BR>Q2.1 什么是Servlet？<BR>Q2.2 我怎么获得Http请求里的参数？<BR>Q2.3 我怎么返回结果？<BR>Q2.4 sendRedirect()和forward()有什么不同？<BR>Q2.5 我写了一个Servlet程序，怎么运行它？<BR>Q2.6 EAR和WAR有什么不同？<BR>Q2.7 EAR格式是怎样的？<BR>Q2.8 WAR格式是怎样的？<BR>Q2.9 我的普通HTML文件/JSP文件应当放在哪里？<BR>Q2.10 我访问不到servlet，甚至连HTML文件都访问不到！<BR>Q2.11 我能访问HTML但是访问不到servlet。<BR>Q2.12&nbsp; 什么是JSP？它和Servlet有什么区别？<BR>Q2.13&nbsp; 我的JSP显示的汉字是乱码。<BR>Q2.14&nbsp; 为什么使用gb18030而不是gb2312？<BR>Q2.15&nbsp; 在JSP里面怎么引用Java Bean。<BR>Q2.16&nbsp; 我想在servlet间传递数据。<BR>Q2.17&nbsp; 怎么调用cookie？<BR>Q2.18&nbsp; 怎么在JSP里面实现文件下载？<BR>Q2.19&nbsp; 怎么实现文件上传？<BR>Q2.20&nbsp; 我想让页面自动刷新，比如聊天室。<BR>Q2.21&nbsp; 我想让用户登录以后才能访问页面。<BR>Q2.22&nbsp; 我想要能注册用户。<BR>Q2.23&nbsp; 怎么在JSP中访问数据库？<BR>Q2.24&nbsp; 什么是JSTL？<BR><BR>一、准备篇<BR><BR>Q1.1&nbsp; 什么是J2EE？它和普通的Java有什么不同？<BR>答：J2EE全称为Java2 Platform, Enterprise Edition。<BR>“J2EE平台本质上是一个分布式的服务器应用程序设计环境——一个Java环境，它提供了<BR>：<BR>·宿主应用的一个运行基础框架环境。<BR>·一套用来创建应用的Java扩展API。”（引自《J2EE服务器端高级编程》）<BR><BR>Q1.2&nbsp; J2EE好学吗？<BR>答：J2EE是很多技术的集合体，并且还在成长中。<BR>你会遇到很多专有名词：比如(X)HTML，Servlet/JSP，JDBC，JMS，JNDI，EJB，XML，Web<BR> Service……。<BR>尤其是XML和Web Service正在快速成长。幸运的是，你不需要等到学会所有技术后再开始<BR>编程。<BR>大体上J2EE可以分成3个主要应用方式：Servlet/JSP，EJB，Web Service 和一些支撑技术<BR>例如JDBC和JNDI。<BR>你可以一个一个的学。<BR><BR>Q1.3 J2EE有什么用？<BR>答：用来建设大型的分布式企业级应用程序。或者用更时髦的名词说就是“电子商务”应<BR>用程序。<BR>这些企业可能大到拥有中心数据库服务器，Web服务器集群和遍布全国的办公终端，也可能<BR>小到只不过想做一个网站。但是你肯定听过“杀鸡焉用牛刀”的古训。<BR><BR>Q1.4 学J2EE有前途吗？<BR>答：在这一市场目前只有一种技术可以和J2EE竞争，那就是Microsoft的.NET。<BR>相对来说.NET要“新”一些而J2EE要“老”一些。这也意味着.NET更易用一点而J2EE更成<BR>熟一点。<BR>但是.NET只能用于Windows平台（Microsoft声称要开发C#在Linux上的虚拟机但是尚未兑现<BR>该诺言）。<BR>在过去几年，.NET的市场份额并不理想。不过Microsoft还有Longhorn这一杀手锏，鹿死谁<BR>手还很难说。<BR><BR>Q1.5 据说J2EE的性能不如.NET好，是真的吗？<BR>答：在Sun公司提供的样例程序Pet Store上，Microsoft声称不如相同的.NET程序好。<BR>而Sun公司反驳说这一程序不能真正体现J2EE的性能，并且指责Microsoft在数据库上做了<BR>优化。<BR>作者没有学习过.NET因而不能妄下断言。<BR>无论如何，大型分布式程序中的性能瓶颈通常首先来自于错误的设计。<BR><BR>Q1.6 听你说了这么多，我想学着玩玩。<BR>答：除非你想靠它当饭吃或者作为技术储备，否则请不要浪费你的时间。<BR>Flash要好玩得多。计算机游戏就更加好玩了。<BR><BR>Q1.7 学习J2EE该怎么开始？<BR>答：首先，下载一个免费的J2EE服务器。其次，去java.sun.com下载J2EE的API。第三，找<BR>一本好的参考书。最后，找一个顺手的IDE。<BR>J2EE服务器。你可以用Sun的J2EE SDK（免费），或者Weblogic（性能最好，但是太大，而<BR>且作者不推荐盗版行为），<BR>或者JBoss（免费，就是文档太少），或者JRun（开发版免费，作者用这个）。<BR>参考书作者感觉Wrox的《J2EE服务器端高级编程》不错，但是太老（作者手头的是2001年<BR>中文版）。<BR>（似乎很多人不喜欢这本书......所以你得自己判断它是否适合你。）<BR>你还需要去下载一些最新的技术资料（当然肯定是英文的）。<BR>IDE如果你的机器配置够好（内存至少512M以上，256M或以下请勿考虑），可以用IBM的WS<BR>AD，不然就继续用Eclipse或者其他。<BR>你也可以经常去水木清华的Java版逛逛，但是在发贴前先看看精华区里有没有你要的答案<BR>。<BR><BR>Q1.8 我下了一个J2EE服务器但是不会配置。<BR>答：请认真阅读随机指导文档，不同的服务器的配置都不一样，作者爱莫能助。<BR><BR>Q1.9 我发现你没有提到Tomcat。<BR>答：Tomcat只是一个Web服务器，更准确地说主要只是一个Web Container。<BR>如果你想要学习EJB的话，Tomcat无法满足你的需要。<BR><BR>二、 Servlet/JSP篇<BR><BR>Q2.1 什么是Servlet？<BR>答：一个Servlet是一个Java类。它处理Http(s)请求并作出响应，包括返回一个HTML页面<BR>或转交给其他URL处理。<BR>Servlet必须运行在一个Web Container例如Tomcat中。<BR>Servlet必须是javax.servlet.http.HttpServlet的子类，<BR>你可以继承doGet()或者doPost()方法，两者分别对应于Http(s)中的Get请求和Post请求。<BR><BR><BR>Q2.2 我怎么获得Http请求里的参数？<BR>答：HttpRequest的getParameter()方法。例如：String paramValue = request.getPara<BR>meter("paramName");<BR><BR>Q2.3 我怎么返回结果？<BR>答：你可以利用相关API打开一个输出流，并向流中直接写入一个HTML页面。<BR>但是作者完全不赞成这样做。一方面这样做会很罗嗦。<BR>另一方面从Model-View-Controller模式（在《J2EE核心模式》中被归为Front Controlle<BR>r模式）的观点来看，<BR>你应当提供一些HTML或者JSP作为视图（view），而Servlet则根据请求参数决定转到哪一<BR>个视图。<BR>你可以利用response.sendRedirect(...)方法或request.getDispatcher(...).forward()<BR>方法来实现。<BR><BR>Q2.4 sendRedirect()和forward()有什么不同？<BR>答：sendRedirect()是向浏览器发送一个redirect通知，浏览器向新的URL发送一个新的请<BR>求。<BR>而forward是在服务器端直接将请求转到新的URL，对于浏览器是透明的。<BR>换而言之，sendRedirect()应当将共享数据放在session中，forward应当将共享数据放在<BR>request中（当然你也可以放在session中，但放在request中可以有效减小session中的数<BR>据量，从而改善性能）。<BR>前者浏览器的地址栏显示的是新的URL，后者浏览器的地址栏显示的是Servlet的URL。<BR>因而当刷新目标URL时，两者会造成一些差别。<BR><BR>Q2.5 我写了一个Servlet程序，怎么运行它？<BR>答：开发J2EE程序有一个部署（deploy）的概念，实际上是开发——部署——运行的三部<BR>曲。<BR>大多数服务器支持Hot deploy。你只需要在相应的Application目录（具体路径依赖于服务<BR>器）下面<BR>建立一个符合WAR或EAR格式（参见Q2.7，Q2.8）的目录，启动服务器，就可以通过浏览器<BR>访问了。<BR>特别的，你的Servlet的class文件应当放在/WEB-INF/classes目录中。<BR>注意J2EE SDK不支持Hot deploy，你需要通过它的deploy tool来部署。<BR>Tomcat只支持WAR格式。<BR><BR>Q2.6 EAR和WAR有什么不同？<BR>答：EAR是一个完整的J2EE应用程序，包括Web部分和EJB部分。<BR>WAR只是其中的Web部分。<BR><BR>Q2.7 EAR格式是怎样的？<BR>答：一个EAR可以包含任意多个WAR或EJB JAR，并且包含一个META-INF的目录。<BR>在/META-INF中包含了一个application.xml，其中描述了这个EAR包含哪些模块，以及安全<BR>性配置。<BR>细节请看参考书。<BR><BR>Q2.8 WAR格式是怎样的？<BR>答：一个WAR包含一个WEB-INF的目录，这个目录下包含classes目录，lib目录和web.xml。<BR><BR>/WEB-INF/classes存放按package组织的class文件，/WEB-INF/lib目录存放jar文件，<BR>web.xml描述了很多东西，请读参考书。<BR><BR>Q2.9 我的普通HTML文件/JSP文件应当放在哪里？<BR>答：放在除了/WEB-INF以外的其他地方。<BR><BR>感谢antegg网友对于安全性的提醒：<BR>如果你想直接用<A href="http://url/***.jsp的方式来访问，就要像上面说得那样放。" target=_blank><FONT color=#002c99>http://url/***.jsp的方式来访问，就要像上面说得那样放。</FONT></A><BR>但是这样的做法是不安全的，安全的做法是把所有的JSP页面放在/WEB-INF目录下面，并且<BR><BR>通过WEB-CONTAINER来访问。<BR><BR>作者意见:<BR>我更喜欢用filter来做安全性检查。<BR>在MVC模式中，JSP只是一个视图而已，一般无需特别担忧安全性。和普通的html放在一起<BR>也利于维护。<BR><BR>Q2.10 我访问不到servlet，甚至连HTML文件都访问不到！<BR>答：<BR>第一你没启动服务器。<BR>第二你敲错了端口。<BR>第三你没有正确配置context-path。<BR>第四你的服务器不支持auto reload或者你关闭了这一选项，你得重启服务器或重新部署W<BR>AR。<BR>第五确认你没有把HTML放在/WEB-INF目录下，那是访问不到的。<BR><BR>Q2.11 我能访问HTML但是访问不到servlet。<BR>答：请检查你的web.xml文件。确保你正确定义了&lt;servlet&gt;和&lt;servlet-mapping&gt;元素。<BR><BR>前者标识了一个servlet，后者将一个相对于context-path的URL映射到一个servlet。<BR>在Tomcat中你可以通过/context-path/servlet/package/servletname的形式访问servlet<BR>，<BR>但是这只是Tomcat的便捷访问方式，并不是正式规范。<BR>细节请看参考书。<BR><BR>Q2.12&nbsp; 什么是JSP？它和Servlet有什么区别？<BR>答：你可以将JSP当做一个可扩充的HTML来对待。<BR>虽然在本质上JSP文件会被服务器自动翻译为相应的Servlet来执行。<BR>可以说Servlet是面向Java程序员而JSP是面向HTML程序员的，除此之外两者功能完全等价<BR>。<BR><BR>Q2.13&nbsp; 我的JSP显示的汉字是乱码。<BR>答：在你的JSP开头加上一行 &lt;%@ page contentType="text/html; charset=gb18030"%&gt;<BR><BR>如果你已经声明了page我想你知道该怎么修改。<BR><BR>Q2.14&nbsp; 为什么使用gb18030而不是gb2312？<BR>答：gb18030是继gb2312之后的下一代汉字编码标准，最终将过渡到Unicode。<BR><BR>Q2.15&nbsp; 在JSP里面怎么引用Java Bean。<BR>答：首先，确认你要引用的类在/WEB-INF/classes下或在/WEB-INF/lib的某个jar内。<BR>其次，在JSP里加一行 &lt;jsp:useBean id="..." scope="..." class="..."/&gt;<BR>具体解释请看参考书。<BR><BR>Q2.16&nbsp; 我想在servlet间传递数据。<BR>答：利用session。在Servlet/JSP中，你可以在4个地方保存数据。<BR>1) page，本页面。<BR>2) session，用来存放客户相关的信息，比如购物车，对应接口为javax.servlet.http.H<BR>ttpSession。<BR>session机制实际上是cookie和URL Rewriting的抽象，服务器会自动使用cookie或URL Re<BR>writing来实现。<BR>3) request，可以在forward()时传递信息，对应接口为javax.servlet.http.HttpReques<BR>t。<BR>4) application，或称context，存放全局信息，对应接口为javax.servlet.ServletCont<BR>ext。<BR><BR>Q2.17&nbsp; 怎么调用cookie？<BR>答：作者建议使用session，你总是会遇到某些禁用cookie的用户。这时session会自动使<BR>用URL重写来实现。<BR><BR>Q2.18&nbsp; 怎么在JSP里面实现文件下载？<BR>答：实际上这是一个HTML的问题。答案是一个超链接&lt;a&gt;。<BR><BR>Q2.19&nbsp; 怎么实现文件上传？<BR>答：客户端是HTML问题，在form中设置method为post，enctype为multi-part/form-data，<BR>加一个&lt;input type="file"&gt;。<BR>而在接收的servlet中只是一个I/O问题，你可以使用jakarta的file-upload库。<BR><BR>Q2.20&nbsp; 我想让页面自动刷新，比如聊天室。<BR>答：这是一个HTML问题，在&lt;head&gt;部分中加一条&lt;meta http-equiv="refresh" content="<BR>5" url="..."&gt;。<BR>这是所谓的Client-pull，客户端刷新技术。<BR>相对的还有Server-push，服务器端刷新技术，但是这一技术由于要占用服务器端资源而会<BR>在大量访问时出现瓶颈现象，参见<A href="http://216.239.33.104/search?q=cache:autUfoakirY" target=_blank><FONT color=#002c99>http://216.239.33.104/search?q=cache:autUfoakirY</FONT></A><BR>J:www.kfunigraz.ac.at/edvndwww/books/books/javaenterprise/servlet/ch06_03.htm+<BR>server-push+servlet&amp;hl=zh-CN&amp;ie=UTF-8<BR><BR>Q2.21&nbsp; 我想让用户登录以后才能访问页面。<BR>答：使用声明式安全措施。<BR>你只需要在web.xml中定义安全角色（Role），并定义受保护的URL集合只能由特定Role访<BR>问。<BR>大多数服务器支持基于数据库的用户映射，你只要在相应数据库中建立两张表并配置服务<BR>器就可以了。<BR>注意J2EE SDK不支持基于数据库的用户映射。<BR>细节请看参考书和服务器文档。<BR>不过在商业环境中，J2EE所提供的声明式安全措施仍然偏弱。一般商业程序会使用数据库<BR>存储user-role-privilege模型来达到安全性要求，细节请询问你的构架设计师。<BR><BR>Q2.22&nbsp; 我想要能注册用户。<BR>答：参看Q2.21。在接受注册请求的Servlet中执行写入数据库操作即可。<BR><BR>Q2.23&nbsp; 怎么在JSP中访问数据库？<BR>答：标准做法是使用DAO模式，定义一个Java bean来访问数据库并在JSP中使用。<BR>然而，当你的数据库模式很简单时，你可以使用JSTL中的&lt;sql:query&gt;标签来快速访问。<BR><BR>在一般的J2EE项目中，JSP处于表示层（展现层），需要先后通过业务层和集成层才会访问<BR>到数据库，所以这个问题确实只会在很小的程序中才会遇到。<BR><BR>Q2.24&nbsp; 什么是JSTL？<BR>答：JSTL是Jsp Standard Tag Library的缩写。这是一组通用标签并将成为JSP 2.0的一部<BR>分。<BR>其中包含赋值&lt;c:set&gt;，分支&lt;c:if&gt;，循环&lt;c:forEach&gt;，查询数据库&lt;sql:query&gt;，更新数<BR>据库&lt;sql:update&gt;<BR>等。目前你需要像添加自定义标签库一样来添加JSTL，但是可以预计JSP 2.0会将JSTL作为<BR>组成部分。<BR>标签库可以在<A href="http://jakarta.apache.org/" target=_blank><FONT color=#002c99>http://jakarta.apache.org</FONT></A>下载。注意JSTL需要在支持JSP 1.2或更高版本<BR>的容器下运行。<BR>帮助文件可以阅读sun的JSTL正式规范。<BR><img src ="http://www.blogjava.net/jackybu/aggbug/1724.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackybu/" target="_blank">辰</a> 2005-03-05 18:04 <a href="http://www.blogjava.net/jackybu/articles/1724.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java的基础问题（一）</title><link>http://www.blogjava.net/jackybu/articles/1722.html</link><dc:creator>辰</dc:creator><author>辰</author><pubDate>Sat, 05 Mar 2005 10:03:00 GMT</pubDate><guid>http://www.blogjava.net/jackybu/articles/1722.html</guid><wfw:comment>http://www.blogjava.net/jackybu/comments/1722.html</wfw:comment><comments>http://www.blogjava.net/jackybu/articles/1722.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackybu/comments/commentRss/1722.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackybu/services/trackbacks/1722.html</trackback:ping><description><![CDATA[目录：<BR>Q1.1 什么是Java、Java2、JDK？JDK后面的1.3、1.4版本号又是怎么回事？<BR>Q1.2 什么是JRE/J2RE？<BR>Q1.3 学习Java用什么工具比较好？<BR>Q1.4&nbsp; 学习Java有哪些好的参考书？<BR>Q1.5&nbsp; Java和C++哪个更好？<BR>Q1.6&nbsp; 什么是J2SE/J2EE/J2ME？<BR>Q2.1&nbsp; 我写了第一个Java程序，应该如何编译/运行？<BR>Q2.2&nbsp; 我照你说的做了，但是出现什么“'javac' 不是内部或外部命令，也不是可运行的<BR>程序或批处理文件。”。<BR>Q2.3&nbsp; 环境变量怎么设置？<BR>Q2.4&nbsp; 我在javac xxx.java的时候显示什么“unreported exception java.io.IOExcepti<BR>on;”。<BR>Q2.5&nbsp; javac xxx.java顺利通过了，但是java xxx的时候显示什么“NoClassDefFoundErr<BR>or”。<BR>Q2.6&nbsp; 我在java xxx的时候显示“Exception in thread "main" java.lang.NoSuchMetho<BR>dError: main”。<BR>Q2.7&nbsp; 在java xxx的时候显示“Exception in thread "main" java.lang.NullPointerEx<BR>ception”。<BR>Q2.8 package是什么意思？怎么用？<BR>Q2.9 我没有声明任何package会怎么样？<BR>Q2.10 在一个类中怎么使用其他类？<BR>Q2.11 我用了package的时候显示"NoClassDefFoundError"，但是我把所有package去掉的<BR>时候能正常运行。<BR>Q2.12 我想把java编译成exe文件，该怎么做？<BR>Q2.13 我在编译的时候遇到什么"deprecated API"，是什么意思？<BR>Q3.1 我怎么给java程序加启动参数，就像dir /p/w那样？<BR>Q3.2 我怎么从键盘输入一个int/double/字符串？<BR>Q3.3 我怎么输出一个int/double/字符串？<BR>Q3.4 我发现有些书上直接用System.in输入，比你要简单得多。<BR>Q3.5 我怎么从文件输入一个int/double/字符串？<BR>Q3.6 我想读写文件的指定位置，该怎么办？<BR>Q3.7 怎么判断要读的文件已经到了尽头？<BR>Q4.1&nbsp; java里面怎么定义宏？<BR>Q4.2&nbsp; java里面没法用const。<BR>Q4.3&nbsp; java里面也不能用goto。<BR>Q4.4&nbsp; java里面能不能重载操作符？<BR>Q4.5&nbsp; 我new了一个对象，但是没法delete掉它。<BR>Q4.6&nbsp; 我想知道为什么main方法必须被声明为public static？为什么在main方法中不能调<BR>用非static成员？<BR>Q4.7&nbsp; throw和throws有什么不同？<BR>Q4.8&nbsp; 什么是异常？<BR>Q4.9&nbsp; final和finally有什么不同？<BR>Q5.1&nbsp; extends和implements有什么不同？<BR>Q5.2&nbsp; java怎么实现多继承？<BR>Q5.3 abstract是什么？<BR>Q5.4 public,protected,private有什么不同？<BR>Q5.5 Override和Overload有什么不同？<BR>Q5.6 我继承了一个方法，但现在我想调用在父类中定义的方法。<BR>Q5.7 我想在子类的构造方法中调用父类的构造方法，该怎么办？<BR>Q5.8 我在同一个类中定义了好几个构造方法并且想在一个构造方法中调用另一个。<BR>Q5.9 我没有定义构造方法会怎么样？<BR>Q5.10 我调用无参数的构造方法失败了。<BR>Q5.11 我该怎么定义类似于C++中的析构方法（destructor）？<BR>Q5.12 我想将一个父类对象转换成一个子类对象该怎么做？<BR>Q5.13 其实我不确定a是不是B的实例，能不能分情况处理？<BR>Q5.14 我在方法里修改了一个对象的值，但是退出方法后我发现这个对象的值没变！<BR>Q6.1 java能动态分配数组吗？<BR>Q6.2 我怎么知道数组的长度？<BR>Q6.3 我还想让数组的长度能自动改变，能够增加/删除元素。<BR>Q6.4 什么是链表？为什么要有ArrayList和LinkedList两种List？<BR>Q6.5 我想用队列/栈。<BR>Q6.6 我希望不要有重复的元素。<BR>Q6.7 我想遍历集合/Map。<BR>Q6.8 我还要能够排序。<BR>Q6.9 但是我想给数组排序。<BR>Q6.10 我想按不同方式排序。<BR>Q6.11 Map有什么用？<BR>Q6.12 set方法没问题，但是get方法返回的是Object。<BR>Q6.13 ArrayList和Vector有什么不同？HashMap和Hashtable有什么不同？<BR>Q6.14 我要获得一个随机数。<BR>Q6.15 我比较两个String总是false，但是它们明明都是"abc" ！<BR>Q6.16 我想修改一个String但是在String类中没找到编辑方法。<BR>Q6.17 我想处理日期/时间。<BR><BR>一、准备篇<BR><BR>Q1.1 什么是Java、Java2、JDK？JDK后面的1.3、1.4版本号又是怎么回事？<BR>答：Java是一种通用的，并发的，强类型的，面向对象的编程语言（摘自Java规范第二版<BR>）。<BR>JDK是Sun公司分发的免费Java开发工具包，正式名称为J2SDK(Java2 Software Develop K<BR>it)。<BR>包括基本的java工具包和标准类库。<BR>到目前(2003年7月)为止，Java有3个主要版本，即1.0，1.1，2.0；<BR>JDK有1.0，1.1，1.2，1.3，1.4五个版本。<BR>从JDK1.2起，Sun公司觉得Java改变足够大而将java语言版本号提升为2.0。<BR>不同的JDK主要在于提供的类库不同。作为学习你可以下载最新的JDK1.4.2。<BR>真正开发时则应考虑向前兼容，比如1.3。下载请去<A href="http://java.sun.com/" target=_blank>http://java.sun.com</A>。<BR>JDK1.5预计将在2004年推出，届时其中将包含若干崭新的特性。<BR><BR>Q1.2 什么是JRE/J2RE？<BR>答：J2RE是Java2 Runtime Environment，即Java运行环境，有时简称JRE。<BR>如果你只需要运行Java程序或Applet，下载并安装它即可。<BR>如果你要自行开发Java软件，请下载JDK。在JDK中附带有JRE。<BR>注意由于Microsoft对Java的支持不完全，请不要使用IE自带的虚拟机来运行Applet，务必<BR>安装一个JRE或JDK。<BR><BR>Q1.3 学习Java用什么工具比较好？<BR>答：作者建议首先使用JDK+文本编辑器，这有助你理解下列几个基础概念：path，classp<BR>ath，package <BR>并熟悉基本命令：javac和java。并且下载和你的JDK版本一致的API帮助。<BR>如果你不确定类或函数的用法，请先查阅API而不是发贴求助。<BR>当你熟悉Java之后，你可以考虑开始使用一个IDE。<BR>作者推荐eclipse，下载网址<A href="http://www.eclipse.org/" target=_blank>http://www.eclipse.org</A>。因为eclispe是免费的，插件化的<BR>。<BR>eclispe的主要缺点是缺乏一个可视化的桌面程序开发工具，<BR>幸运的是IBM在2003年11月已经将部分代码捐给eclipse组织，可以预计这个缺点很快就会<BR>得到弥补。<BR>无论如何，请不要使用Microsoft的VJ++！众所周知Microsoft从来就没有认真支持过Java<BR>。<BR>最后但并非最不重要，要有一本好的参考书，并且英文要过关。<BR><BR>Q1.4&nbsp; 学习Java有哪些好的参考书？<BR>答：作者首先推荐Thinking in Java，中文名《Java编程思想》，有中文版。<BR>目前的最新版本是第三版。<BR>在<A href="http://64.78.49.204/" target=_blank>http://64.78.49.204</A>可以免费下载英文版。<BR>该书第一章介绍了很多面向对象的编程思想，作为新手应当认真阅读。<BR>除此以外，O'relly出版社和Wrox出版社的书也不错。作者本人不喜欢大陆作者的书。<BR>也许你觉得英文太难，但是网上大多数资料都是英文的。另外，你需要经常查阅API，而那<BR>也是英文的。<BR><BR>Q1.5&nbsp; Java和C++哪个更好？<BR>答：这个问题是一个很不恰当的问题。你应该问：Java和C++哪个更适用于我的项目？<BR>Java的优点和缺点一样明显。<BR>跨平台是Java的主要优点，但代价是运行速度的下降。<BR>VC和Windows平台有良好的集成和足够快的速度，但是也只能局限在Windows平台上。<BR>和C++相比，Java学起来更快，开发人员不会碰到很多容易出错的特性。<BR>但是VB程序员甚至只需要拼装模块就可以了。<BR><BR>Q1.6&nbsp; 什么是J2SE/J2EE/J2ME？<BR>答：J2SE就是一般的Java。<BR>J2ME是针对嵌入式设备的，比如支持Java的手机，它有自己的JRE和SDK。<BR>J2EE是一组用于企业级程序开发的规范和类库，它使用J2SE的JRE。<BR><BR>二、命令篇<BR><BR>Q2.1&nbsp; 我写了第一个Java程序，应该如何编译/运行？<BR>答：首先请将程序保存为xxx.java文件，注意你可能需要修改文件后缀名。<BR>然后在dos窗口下使用javac xxx.java命令，你会发现该目录下多了一个xxx.class文件，<BR><BR>再使用java xxx命令，你的java程序就开始运行了。<BR><BR>Q2.2&nbsp; 我照你说的做了，但是出现什么“'javac' 不是内部或外部命令，也不是可运行的<BR>程序或批处理文件。”。<BR>答：你遇到了path问题。操作系统在一定的范围(path)内搜索javac.exe，但是没能找到。<BR><BR>请编辑你的操作系统环境变量，新增一个JAVA_HOME变量，设为你JDK的安装目录，<BR>再编辑Path变量，加上一项 %JAVA_HOME%\bin。<BR>然后保存并新开一个dos窗口，你就可以使用javac和java命令了。<BR><BR>Q2.3&nbsp; 环境变量怎么设置？<BR>答：请向身边会设的人咨询。<BR><BR>Q2.4&nbsp; 我在javac xxx.java的时候显示什么“unreported exception java.io.IOExcepti<BR>on;”。<BR>答：参见Q4.8以了解java中的异常机制。<BR><BR>Q2.5&nbsp; javac xxx.java顺利通过了，但是java xxx的时候显示什么“NoClassDefFoundErr<BR>or”。<BR>答：1. 你遇到了classpath问题。java命令在一定的范围(classpath)内搜索你直接或间接<BR>使用的class文件，但是未能找到。<BR>首先请确认你没有错敲成java xxx.class，<BR>其次，检查你的CLASSPATH环境变量，其实你并不需要设置该变量，<BR>但如果你设置了该变量又没有包含.（代表当前目录）的项，<BR>你就会遇到这个问题。请在你的CLASSPATH环境变量中加入一项. 或干脆删掉这个变量。<BR><BR>2. 如果你使用了并非JDK自带的标准包，比如javax.servlet.*包，也会遇到这个问题，请<BR>将相应的jar文件加入classpath。<BR>3. 如果你在java源文件中定义了package，请参见Q2.11。<BR><BR><BR>Q2.6&nbsp; 我在java xxx的时候显示“Exception in thread "main" java.lang.NoSuchMetho<BR>dError: main”。<BR>答：首先，在你的程序中每个java文件有且只能有一个public类，<BR>这个类的类名必须和文件名的大小写完全一样。<BR>其次，在你要运行的类中有且只能有一个public static void main(String[] args)方法<BR>，<BR>这个方法就是你的主程序。<BR><BR><BR>Q2.7&nbsp; 在java xxx的时候显示“Exception in thread "main" java.lang.NullPointerEx<BR>ception”。<BR>答：在程序中你试图在值为null的对象变量上调用方法，请检查你的程序确保你的对象被恰当的初始化。<BR>参见Q4.8以了解java中的异常机制。<BR><BR><BR>Q2.8 package是什么意思？怎么用？<BR>答：为了唯一标识每个类并分组，java使用了package的概念。<BR>每个类都有一个全名，例如String的全名是java.lang.String，其中java.lang是包名，S<BR>tring是短名。按照java命名惯例，包名是全部小写的，而类名的第一个字母是大写的。<BR>这样，如果你自行定义了同样名字的类String，你可以把它放在mypackage中，<BR>通过使用全名mypackage.String和java.lang.String来区分这两个类。<BR>同时，将逻辑上相关的类放在同一个包中，可以使程序结构更为清楚。<BR>为了定义包，你要做的就是在java文件开头加一行“package mypackage;”。<BR>注意包没有嵌套或包含关系，mypackage包和mypackage.mysubpackage包对JRE来说是并列的两个包（虽然开发者可<BR>能暗示包含关系）。<BR><BR>Q2.9 我没有声明任何package会怎么样？<BR>答：你的类被认为放在默认包中。这时全名和短名是一致的。<BR><BR>Q2.10 在一个类中怎么使用其他类？<BR>答：如果你使用java.lang包或者默认包中的类，不用做任何事。<BR>如果你的类位于mypackage包中，并且要调用同一包中的其他类，也不用做任何事。<BR>如果你使用其他包中的类，在package声明之后，类声明之前使用import otherpackage1.Class<BR>1; 或 import otherpackage2.*;&nbsp; <BR>这里.*表示引入这个包中的所有类。然后在程序中你可以使用其他类的短名。<BR>如果短名间有重名冲突，必须使用全名来区分。<BR>注意在使用其他包中的类时，你只能使用public的类和接口，参见Q5.4。<BR><BR>Q2.11 我用了package的时候显示"NoClassDefFoundError"，但是我把所有package去掉的<BR>时候能正常运行。<BR>答：将你的java文件按包名组织存放。<BR>比如你的工作目录是/work，你的类是package1.Class1，那么将它存放为/work/package1<BR>/Class1.java。<BR>如果没有声明包，那么直接放在/work下。<BR>在/work下执行javac package1/class1.java，再执行java package1.class1，你会发现一<BR>切正常。<BR>另外，如果你的类的个数已经多到了你需要使用包来组织的话，你可以考虑开始使用IDE。<BR><BR>Q2.12 我想把java编译成exe文件，该怎么做？<BR>答：JDK只能将java源文件编译为class文件。<BR>class文件是一种跨平台的字节码，必须依赖平台相关的JRE来运行。Java以此来实现跨平<BR>台性。<BR>有些开发工具可以将java文件编译为exe文件。作者反对这种做法，因为这样就取消了跨平<BR>台性。<BR>如果你确信你的软件只在Windows平台上运行，你可以考虑使用C++/C#来编程。<BR><BR>Q2.13 我在编译的时候遇到什么"deprecated API"，是什么意思？<BR>答：所谓deprecated是指已经过时，但是为了向前兼容起见仍然保留的方法。<BR>这些方法可能会在以后取消支持。你应当改用较新的方法。<BR>在API里面会说明你应当用什么方法来代替之。<BR><BR>三、I/O篇<BR><BR>Q3.1 我怎么给java程序加启动参数，就像dir /p/w那样？<BR>答：还记得public static void main(String[] args)吗？这里的args就是你的启动参数<BR>。<BR>在运行时你输入java package1.class1 arg1 arg2，args中就会有两个String，第一个是<BR>arg1，第二个是arg2。<BR><BR>Q3.2 我怎么从键盘输入一个int/double/字符串？<BR>答：java的I/O操作比C++要复杂一点。如果要从键盘输入，样例代码如下：<BR>BufferedReader cin = new BufferedReader( new InputStreamReader( System.in ) );<BR><BR>String s = cin.readLine();<BR>这样你就获得了一个字符串，如果你需要数字的话再使用：<BR>int n = Integer.parseInt( s ); 或者 double d = Double.parseDouble( s );<BR>来将字符串"534"转换成int或double。<BR><BR>Q3.3 我怎么输出一个int/double/字符串？<BR>答：使用System.out.println(n)或者System.out.println("Hello")等等。<BR><BR>Q3.4 我发现有些书上直接用System.in输入，比你要简单得多。<BR>答：java使用unicode，是双字节。而System.in是单字节的stream。<BR>如果你要输入双字节文字比如中文，请使用作者的做法。<BR><BR>Q3.5 我怎么从文件输入/输出一个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>Q3.6 我想读写文件的指定位置，该怎么办？<BR>答：java.io.RandomAccessFile可以满足你的需要。<BR><BR>Q3.7 怎么判断要读的文件已经到了尽头？<BR>答：在Reader的read方法中明确说明返回-1表示流的结尾。<BR><BR>四、 关键字篇<BR><BR>Q4.1&nbsp; java里面怎么定义宏？<BR>答：java不支持宏，因为宏代换不能保证类型安全。<BR>如果你需要定义常量，可以将它定义为某个类的static final成员。参见Q4.2和Q4.6。<BR><BR><BR>Q4.2&nbsp; java里面没法用const。<BR>答：你可以用final关键字。例如 final int m = 9。被声明为final的变量不能被再次赋<BR>值。唯一的例外是所谓blank final，如下例所示：<BR>public class MyClass1 {<BR>&nbsp;&nbsp;&nbsp; private final int a = 3;<BR>&nbsp;&nbsp;&nbsp; private final int b; // blank final<BR><BR>&nbsp;&nbsp;&nbsp; public MyClass1() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a = 5; // 不合法，final变量不能被再次赋值。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b = 4; // 合法，这是b第一次被赋值。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b = 6; // 不合法，b不能被再次赋值。<BR>&nbsp;&nbsp;&nbsp; }<BR>}<BR>final也可以用于声明方法或类，被声明为final的方法或类不能被继承。<BR>注意const是java的保留字以备扩充。<BR><BR>Q4.3&nbsp; java里面也不能用goto。<BR>答：甚至在面向过程的语言中你也可以完全不用goto。请检查你的程序流程是否合理。<BR><BR>如果你需要从多层循环中迅速跳出，java增强了（和C++相比）break和continue的功能，<BR>支持label。<BR>例如：<BR>outer : <BR>while( ... )<BR>{<BR>	inner :<BR>	for( ... )<BR>	{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...&nbsp;&nbsp; break inner; ...<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ... continue outer; ...<BR>	}<BR>}<BR>和const一样，goto也是java的保留字以备扩充。<BR><BR>Q4.4&nbsp; java里面能不能重载操作符？<BR>答：不能。String的+号是唯一一个内置的重载操作符。你可以通过定义接口和方法来实现<BR>类似功能。<BR><BR>Q4.5&nbsp; 我new了一个对象，但是没法delete掉它。<BR>答：java有自动内存回收机制，即所谓Garbarge Collection。你不需要删除对象。你再也<BR>不用担心指针错误，内存溢出了。<BR><BR>Q4.6&nbsp; 我想知道为什么main方法必须被声明为public static？为什么在main方法中不能调<BR>用非static成员？<BR>答：声明为public是为了这个方法可以被外部调用，详情见Q5.4。<BR>static是为了将某个成员变量/方法关联到类（class）而非实例（instance）。<BR>你不需要创建一个对象就可以直接使用这个类的static成员，因而在static成员中不能调<BR>用非static成员，因为后者是关联到对象实例（instance）的。<BR>在A类中调用B类的static成员可以使用B.staticMember的写法。<BR>注意一个类的static成员变量是唯一的，被所有该类对象所共享的，在多线程程序设计中尤其要谨慎小心。<BR>类的static成员是在类第一次被JRE装载的时候初始化的。<BR>你可以使用如下方法来使用非static成员：<BR>public class A<BR>{<BR>&nbsp;&nbsp;&nbsp; private void someMethod() //非static成员<BR>&nbsp;&nbsp;&nbsp; {}<BR>&nbsp;&nbsp;&nbsp; public static void main(String args)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A a = new A();&nbsp; //创建一个对象实例<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a.someMethod();&nbsp; //现在你可以使用非static方法了<BR>&nbsp;&nbsp;&nbsp; }<BR>}<BR><BR><BR>Q4.7&nbsp; throw和throws有什么不同？<BR>答：throws用于方法声明中，声明一个方法会抛出哪些异常。而throw是在方法体中实际执行抛出异常的<BR>动作。<BR>如果你在方法中throw一个异常，却没有在方法声明中声明之，编译器会报错。<BR>注意Error和RuntimeException的子类是例外，无需特别声明。<BR><BR>Q4.8&nbsp; 什么是异常？<BR>答：异常最早在Ada语言中引入，用于在程序中动态处理错误并恢复。<BR>你可以在方法中拦截底层异常并处理之，也可以抛给更高层的模块去处理。<BR>你也可以抛出自己的异常指示发生了某些不正常情况。常见的拦截处理代码如下：<BR>try<BR>{<BR>	......//以下是可能发生异常的代码<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...... //异常被你或低层API抛出，执行流程中断并转向拦截代码。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...... <BR>}<BR>catch(Exception1 e) //如果Exception1是Exception2的子类并要做特别处理，应排在前<BR>面<BR>{<BR>&nbsp; //发生Exception1时被该段拦截<BR>}<BR>catch(Exception2 e)<BR>{<BR>&nbsp; //发生Exception2时被该段拦截<BR>}<BR>finally //这是可选的<BR>{<BR>&nbsp;&nbsp; //无论异常是否发生，均执行此段代码<BR>&nbsp;&nbsp; //即使在catch段中又向外抛出了新的exception，finally段也会得到执行。<BR>}<BR><BR>Q4.9&nbsp; final和finally有什么不同？<BR>答：final请见Q4.2。finally用于异常机制，参见Q4.8。<BR><BR>五、 面向对象篇<BR><BR>Q5.1&nbsp; extends和implements有什么不同？<BR>答：对于class而言，extends用于（单）继承一个类（class），而implements用于实现一个接口（interf<BR>ace）。<BR>interface的引入是为了部分地提供多继承的功能。<BR>在interface中只需声明方法头，而将方法体留给实现的class来做。<BR>这些实现的class的实例完全可以当作interface的实例来对待。<BR>在interface之间也可以声明为extends（多继承）的关系。<BR>注意一个interface可以extends多个其他interface。<BR><BR>Q5.2&nbsp; java怎么实现多继承？<BR>答：java不支持显式的多继承。<BR>因为在显式多继承的语言例如c++中，会出现子类被迫声明祖先虚基类构造函数的问题，<BR><BR>而这是违反面向对象的封装性原则的。<BR>java提供了interface和implements关键字来部分地实现多继承。参见Q5.1。<BR><BR>Q5.3 abstract是什么？<BR>答：被声明为abstract的方法无需给出方法体，留给子类来实现。<BR>而如果一个类中有abstract方法，那么这个类也必须声明为abstract。<BR>被声明为abstract的类无法实例化，尽管它可以定义构造方法供子类使用。<BR><BR>Q5.4 public,protected,private有什么不同？<BR>答：这些关键字用于声明类和成员的可见性。<BR>public成员可以被任何类访问，<BR>protected成员限于自己和子类访问，<BR>private成员限于自己访问。<BR>Java还提供了第四种的默认可见性，一般称为package private，当没有任何public,protected,private修饰符时，成员<BR>是同一包内可见。<BR>类可以用public或默认来修饰。<BR><BR>Q5.5 Override和Overload有什么不同？<BR>答：Override是指父类和子类之间方法的继承关系，这些方法有着相同的名称和参数类型<BR>。<BR>Overload是指同一个类中不同方法（可以在子类也可以在父类中定义）间的关系，<BR>这些方法有着相同的名称和不同的参数类型。<BR><BR><BR>Q5.6 我继承了一个方法，但现在我想调用在父类中定义的方法。<BR>答：用super.xxx()可以在子类中调用父类方法。<BR><BR>Q5.7 我想在子类的构造方法中调用父类的构造方法，该怎么办？<BR>答：在子类构造方法的第一行调用super(...)即可。<BR><BR>Q5.8 我在同一个类中定义了好几个构造方法并且想在一个构造方法中调用另一个。<BR>答：在构造方法第一行调用this(...)。<BR><BR>Q5.9 我没有定义构造方法会怎么样？<BR>答：自动获得一个无参数的构造方法。<BR><BR>Q5.10 我调用无参数的构造方法失败了。<BR>答：如果你至少定义了一个构造方法，就不再有自动提供的无参数的构造方法了。<BR>你需要另外显式定义一个无参数的构造方法。<BR>另外一种可能是你的构造方法或者类不是public的，参见Q5.4了解java中的可见性。<BR><BR>Q5.11 我该怎么定义类似于C++中的析构方法（destructor）？<BR>答：提供一个void finalize()方法。在Garbarge Collector回收该对象时会调用该方法。<BR><BR>注意实际上你很难判断一个对象会在什么时候被回收。作者从未感到需要用到该方法。<BR><BR><BR>Q5.12 我想将一个父类对象转换成一个子类对象该怎么做？<BR>答：强制类型转换。如<BR>public void meth(A a)<BR>{<BR>	B b = (B)a;<BR>}<BR>如果a实际上并不是B的实例，会抛出ClassCastException。所以请确保a确实是B的实例。<BR><BR><BR>Q5.13 其实我不确定a是不是B的实例，能不能分情况处理？<BR>答：可以使用instanceof操作符。例如<BR>if( a instanceof B )<BR>{<BR>	B b = (B)a;<BR>}<BR>else<BR>{<BR>	...<BR>}<BR><BR>Q5.14 我在方法里修改了一个对象的值，但是退出方法后我发现这个对象的值没变！<BR>答：很可能你把传入参数重赋了一个新对象，例如下列代码就会造成这种错误：<BR>public void fun1(A a) //a是局部参数，指向了一个外在对象。<BR>{<BR>	a = new A(); //a指向了一个新对象，和外在对象脱钩了。如果你要让a作为传出变量，<BR>不要写这一句。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a.setAttr(attr);//修改了新对象的值，外在对象没有被修改。<BR>}<BR>基本类型也会出现这种情况。例如：<BR>public void fun2(int a)<BR>{<BR>	a = 10;//只作用于本方法，外面的变量不会变化。<BR>}<BR><BR>六、java.util篇<BR><BR>Q6.1 java能动态分配数组吗？<BR>答：可以。例如int n = 3; Language[] myLanguages = new Language[n];<BR><BR>Q6.2 我怎么知道数组的长度？<BR>答：用length属性。如上例中的&nbsp; myLanguages.length 就为 3。<BR><BR>Q6.3 我还想让数组的长度能自动改变，能够增加/删除元素。<BR>答：用顺序表--java.util.List接口。<BR>你可以选择用ArrayList或是LinkedList，前者是数组实现，后者是链表实现。<BR>例如：&nbsp; List list = new ArrayList(); 或是 List list = new LinkedList();&nbsp; 。<BR><BR>Q6.4 什么是链表？为什么要有ArrayList和LinkedList两种List？<BR>答：请补习数据结构。<BR><BR>Q6.5 我想用队列/栈。<BR>答：用java.util.LinkedList。<BR><BR>Q6.6 我希望不要有重复的元素。<BR>答：用集合--java.util.Set接口。例如：Set set = new HashSet()。<BR><BR>Q6.7 我想遍历集合/Map。<BR>答：用java.util.Iterator。参见API。<BR><BR>Q6.8 我还要能够排序。<BR>答：用java.util.TreeSet。例如：Set set = new TreeSet()。放进去的元素会自动排序<BR>。<BR>你需要为元素实现Comparable接口，还可能需要提供equals()方法，compareTo()方法，h<BR>ashCode()方法。<BR><BR>Q6.9 但是我想给数组排序。<BR>答：java.util.Arrays类包含了sort等实用方法。<BR><BR>Q6.10 我想按不同方式排序。<BR>答：为每种方式定义一个实现了接口Comparator的排序类并和Arrays或TreeSet综合运用。<BR><BR><BR>Q6.11 Map有什么用？<BR>答：存储key-value的关键字-值对，你可以通过关键字来快速存取相应的值。<BR><BR>Q6.12 set方法没问题，但是get方法返回的是Object。<BR>答：强制类型转换成你需要的类型。参见Q5.12。<BR><BR>Q6.13 ArrayList和Vector有什么不同？HashMap和Hashtable有什么不同？<BR>答：ArrayList和HashMap是多线程不安全的，在多个线程中访问同一个ArrayList对象可能<BR>会引起冲突并导致错误。<BR>而Vector和Hashtable是多线程安全的，即使在多个线程中同时访问同一个Vector对象也不<BR>会引起差错。<BR>看起来我们更应该使用Vector和Hashtable，但是实际上Vector和Hashtable的性能太差，<BR>所以如果你不在多线程中使用的话，还是应该用ArrayList和HashMap。<BR><BR>Q6.14 我要获得一个随机数。<BR>答：使用java.util.Random类。<BR><BR>Q6.15 我比较两个String总是false，但是它们明明都是"abc" ！<BR>答：比较String一定要使用equals或equalsIgnoreCase方法，不要使用 == ！<BR>==比较的是两个引用（变量）是否指向了同一个对象，而不是比较其内容。<BR><BR>Q6.16 我想修改一个String但是在String类中没找到编辑方法。<BR>答：使用StringBuffer类。<BR>String str = "......."; //待处理的字符串<BR>StringBuffer buffer = new StringBuffer(str); //使用该字符串初始化一个StringBuf<BR>fer<BR>buffer.append("..."); //调用StringBuffer的相关API来编辑字符串<BR>String str2 = buffer.toString(); //获得编辑后的字符串。<BR>另外，如果你需要将多个字符串连接起来，请尽量避免使用+号直接连接，而是使用Strin<BR>gBuffer.append()方法。<BR><BR>Q6.17 我想处理日期/时间。<BR>答：使用java.util.Date类。你可以使用java.text.SimpleDateFormat类来在String和Da<BR>te间互相转换。<BR>SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //规<BR>定日期格式<BR>Date date = formatter.parse("2003-07-26 18:30:35"); //将符合格式的String转换为<BR>Date<BR>String s = formatter.format(date); //将Date转换为符合格式的String<BR>关于定义日期格式的详细信息请参见API。<BR><img src ="http://www.blogjava.net/jackybu/aggbug/1722.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackybu/" target="_blank">辰</a> 2005-03-05 18:03 <a href="http://www.blogjava.net/jackybu/articles/1722.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[学习笔记]Java Web Start </title><link>http://www.blogjava.net/jackybu/articles/1717.html</link><dc:creator>辰</dc:creator><author>辰</author><pubDate>Sat, 05 Mar 2005 06:29:00 GMT</pubDate><guid>http://www.blogjava.net/jackybu/articles/1717.html</guid><wfw:comment>http://www.blogjava.net/jackybu/comments/1717.html</wfw:comment><comments>http://www.blogjava.net/jackybu/articles/1717.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackybu/comments/commentRss/1717.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackybu/services/trackbacks/1717.html</trackback:ping><description><![CDATA[<P class=MsoNormal><SPAN lang=EN-US style="FONT-FAMILY: 宋体">******************************************************* </SPAN></P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">作者：陈刚，程序员，广西省桂林人，广西师范大学数学系<SPAN lang=EN-US>97届毕业。</SPAN></SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US style="FONT-FAMILY: 宋体">blog：<A href="http://blog.csdn.net/glchengang">http://blog.csdn.net/glchengang</A></SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US style="FONT-FAMILY: 宋体">Email：<A href="mailto:glchengang@yeah.net">glchengang@yeah.net</A> &nbsp;</SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US style="FONT-FAMILY: 宋体">*******************************************************&nbsp; </SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P class=MsoNormal><SPAN style="COLOR: red; FONT-FAMILY: 宋体">谁可以提供一个稍微大一些的</SPAN><SPAN lang=EN-US style="COLOR: red">FTP</SPAN><SPAN style="COLOR: red; FONT-FAMILY: 宋体">空间，有些文章的源代码无处可放</SPAN><SPAN style="COLOR: red"> </SPAN></P>
<H1 style="MARGIN: 15.6pt 0cm"><SPAN lang=EN-US>Java Web Start</SPAN><SPAN style="FONT-FAMILY: 黑体">简介</SPAN></H1>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">最近由于工作关系，老大嘱咐我看一下</SPAN><SPAN lang=EN-US>Java Web Start</SPAN><SPAN style="FONT-FAMILY: 宋体">。以前安装</SPAN><SPAN lang=EN-US>JDK</SPAN><SPAN style="FONT-FAMILY: 宋体">时，会在“开始”菜单加一个快捷菜单“</SPAN><SPAN lang=EN-US>Java Web Start</SPAN><SPAN style="FONT-FAMILY: 宋体">”，也不知是做什么用的，我一般都是删除。今天从网上查了一下资料，不看不知道，一看吓一跳，觉得这</SPAN><SPAN lang=EN-US>JWS</SPAN><SPAN style="FONT-FAMILY: 宋体">（</SPAN><SPAN lang=EN-US>Java Web Start</SPAN><SPAN style="FONT-FAMILY: 宋体">简称）很象传说中的“服务器端小程序下载运行”。而且</SPAN><SPAN lang=EN-US>JWS</SPAN><SPAN style="FONT-FAMILY: 宋体">很早就有了，我看有些文章资料已经是</SPAN><SPAN lang=EN-US>2002</SPAN><SPAN style="FONT-FAMILY: 宋体">年发的，自己竟然全然不知它的存在，实在是愚昧呀。</SPAN></P>
<H3><SPAN lang=EN-US>1.&nbsp; JWS有什么用</SPAN></H3>
<P class=MsoNormal><SPAN lang=EN-US>B/S</SPAN><SPAN style="FONT-FAMILY: 宋体">风行的一个很大原因就是它有部署方便的优势，这是</SPAN><SPAN lang=EN-US>C/S</SPAN><SPAN style="FONT-FAMILY: 宋体">的</SPAN><SPAN lang=EN-US>Application</SPAN><SPAN style="FONT-FAMILY: 宋体">所无法比拟的。现在，</SPAN><SPAN lang=EN-US>JWS</SPAN><SPAN style="FONT-FAMILY: 宋体">让用户可以下载服务器端的</SPAN><SPAN lang=EN-US>Java Application</SPAN><SPAN style="FONT-FAMILY: 宋体">到本机运行，并且没有安装、配置等繁琐的操作。</SPAN><SPAN lang=EN-US>SUN</SPAN><SPAN style="FONT-FAMILY: 宋体">网站上有</SPAN><SPAN lang=EN-US>Demo</SPAN><SPAN style="FONT-FAMILY: 宋体">，大家可以体验一下效果：</SPAN><SPAN lang=EN-US><A href="http://java.sun.com/products/javawebstart/demos.html">http://java.sun.com/products/javawebstart/demos.html</A>&nbsp; </SPAN><SPAN style="FONT-FAMILY: 宋体">。</SPAN></P>
<H3><SPAN lang=EN-US>2.&nbsp; JWS的运行原理</SPAN></H3>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">浏览器的运行</SPAN><SPAN lang=EN-US>Java Applica ton</SPAN><SPAN style="FONT-FAMILY: 宋体">的链接指向的不是程序本身，而是一个</SPAN><SPAN lang=EN-US>*.jnlp</SPAN><SPAN style="FONT-FAMILY: 宋体">文件，这个文件包含了</SPAN><SPAN lang=EN-US>Java Application</SPAN><SPAN style="FONT-FAMILY: 宋体">的一些配置信息。然后</SPAN><SPAN lang=EN-US>JWS</SPAN><SPAN style="FONT-FAMILY: 宋体">解读这个文件的信息，将服务器端的</SPAN><SPAN lang=EN-US>Java Application</SPAN><SPAN style="FONT-FAMILY: 宋体">下载到本机上，并运行。</SPAN></P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">当然第一次运行程序时，由于要下载所以速度会稍微慢一些，不过第二次运行时，</SPAN><SPAN lang=EN-US>JWS</SPAN><SPAN style="FONT-FAMILY: 宋体">会自动去服务器上检查是否有新的程序版本发布，如果没有就会直接运行本机已经下载的程序，这就和运行本机</SPAN><SPAN lang=EN-US>Java Application</SPAN><SPAN style="FONT-FAMILY: 宋体">没什么区别了。运行程序之初，</SPAN><SPAN lang=EN-US>JWS</SPAN><SPAN style="FONT-FAMILY: 宋体">还会提示你是否创建一个相应的快捷菜单。</SPAN></P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">程序下载到本机的默认位置是：“</SPAN><SPAN lang=EN-US>C:\Documents and Settings\admin\Application Data\Sun\Java\Deployment\javaws\cache\indirect\indirect12423.ind</SPAN><SPAN style="FONT-FAMILY: 宋体">”，你可以在本机的“</SPAN><SPAN lang=EN-US>JWS</SPAN><SPAN style="FONT-FAMILY: 宋体">应用程序管理器”的里重新设置此存放目录。</SPAN></P>
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US><IMG height=427 alt="" src="http://blog.csdn.net/images/blog_csdn_net/glchengang/102036/o_20050302image001.jpg" width=555 border=0></SPAN></P>
<P class=MsoNormal style="TEXT-ALIGN: center" align=center><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P class=MsoNormal><SPAN lang=EN-US>JWS</SPAN><SPAN style="FONT-FAMILY: 宋体">无疑要比</SPAN><SPAN lang=EN-US>Applet</SPAN><SPAN style="FONT-FAMILY: 宋体">的应用范围更广（据说还得过＊＊的最佳创意奖），它对于布署一些小型的程序应用是非常方便的，但我以为现在还主要适用于局域网。因为一个程序一般约有几十</SPAN><SPAN lang=EN-US>M</SPAN><SPAN style="FONT-FAMILY: 宋体">，如果是</SPAN><SPAN lang=EN-US>Internet</SPAN><SPAN style="FONT-FAMILY: 宋体">用户第一次的下载速度会很慢。</SPAN></P>
<H3><SPAN lang=EN-US>3.&nbsp; 安全性问题。</SPAN></H3>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">但和</SPAN><SPAN lang=EN-US>Applet</SPAN><SPAN style="FONT-FAMILY: 宋体">一样，</SPAN><SPAN lang=EN-US>JWS</SPAN><SPAN style="FONT-FAMILY: 宋体">也面临安全性问题，默认情况下</SPAN><SPAN lang=EN-US>JWS</SPAN><SPAN style="FONT-FAMILY: 宋体">对本机磁盘和本地网络的访问是有限制的。如果该程序要越权访问，这时会弹出一个警告框（类似于</SPAN><SPAN lang=EN-US>ActivX</SPAN><SPAN style="FONT-FAMILY: 宋体">的数字签名），用户可以自已决定是否信任该软件，而对其放开限制。</SPAN></P>
<H3><SPAN lang=EN-US>4.&nbsp; JWS的优缺点</SPAN></H3>
<P class=MsoNormal><SPAN lang=EN-US>JWS</SPAN><SPAN style="FONT-FAMILY: 宋体">的优点就是让程序的布署更简单，而且用户端的应用可以时刻保持和服务器端的最新版本同步，这为升级版本提供了很大的方便。</SPAN></P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">缺点也是明显的，由于要运行应用必须一次下载所有的程序文件（</SPAN><SPAN lang=EN-US>JWS</SPAN><SPAN style="FONT-FAMILY: 宋体">的</SPAN><SPAN lang=EN-US>jnlp</SPAN><SPAN style="FONT-FAMILY: 宋体">配置文件有个</SPAN><SPAN lang=EN-US>lazy</SPAN><SPAN style="FONT-FAMILY: 宋体">选项，但作用不明显），所以第一次下载速度很慢，不适用于互联网。从这一点来看</SPAN><SPAN lang=EN-US>B/S</SPAN><SPAN style="FONT-FAMILY: 宋体">形式的应用还是有优势的。</SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US></SPAN>&nbsp;</P>
<H3>参考资料</H3>
<P class=MsoNormal><SPAN lang=EN-US><A href="http://www.chinaitlab.com/www/news/article_show.asp?id=25239">http://www.chinaitlab.com/www/news/article_show.asp?id=25239</A></SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US><A href="http://blog.csdn.net/emag_java/archive/2005/01/13/252047.aspx">http://blog.csdn.net/emag_java/archive/2005/01/13/252047.aspx</A>&nbsp; </SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P class=MsoNormal><SPAN lang=EN-US style="FONT-FAMILY: 宋体"></SPAN>&nbsp;</P>
<H1 style="MARGIN: 15.6pt 0cm"><SPAN lang=EN-US>Java Web Start</SPAN><SPAN style="FONT-FAMILY: 黑体">实例</SPAN></H1>
<H3 style="MARGIN-LEFT: 18pt; TEXT-INDENT: -18pt"><SPAN lang=EN-US>1、</SPAN>示例说明</H3>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">由于本</SPAN><SPAN lang=EN-US>BLOG</SPAN><SPAN style="FONT-FAMILY: 宋体">现主要以</SPAN><SPAN lang=EN-US>Eclipse</SPAN><SPAN style="FONT-FAMILY: 宋体">和</SPAN><SPAN lang=EN-US>SWT</SPAN><SPAN style="FONT-FAMILY: 宋体">为内容，所以</SPAN><SPAN lang=EN-US>Java Web Start</SPAN><SPAN style="FONT-FAMILY: 宋体">（简称</SPAN><SPAN lang=EN-US>JWS</SPAN><SPAN style="FONT-FAMILY: 宋体">）也以一个</SPAN><SPAN lang=EN-US>SWT</SPAN><SPAN style="FONT-FAMILY: 宋体">应用程序来做为示例。</SPAN></P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">本文用＜</SPAN><SPAN lang=EN-US>Eclipse</SPAN><SPAN style="FONT-FAMILY: 宋体">开发指南＞书中打包一章的打包结果为示例，该示例为一个</SPAN><SPAN lang=EN-US>SWT/JFace</SPAN><SPAN style="FONT-FAMILY: 宋体">程序，其打包后的文件结构如下：</SPAN></P>
<P class=a style="TEXT-INDENT: 20pt"><SPAN lang=EN-US><IMG height=53 alt="" src="http://blog.csdn.net/images/blog_csdn_net/glchengang/102036/o_20050302image002.jpg" width=116 border=0></SPAN></P>
<P class=a style="TEXT-INDENT: 20pt"><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P class=CharChar><SPAN lang=EN-US style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US>myswt</SPAN><SPAN style="FONT-FAMILY: 宋体">是主包，里面含有自己写的程序代码</SPAN></P>
<P class=CharChar><SPAN lang=EN-US style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US>swt-win32-3063.dll</SPAN><SPAN style="FONT-FAMILY: 宋体">是本地化文件</SPAN></P>
<P class=CharChar><SPAN lang=EN-US style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US>lib</SPAN><SPAN style="FONT-FAMILY: 宋体">子目录下还有三个</SPAN><SPAN lang=EN-US>jar</SPAN><SPAN style="FONT-FAMILY: 宋体">文件：</SPAN><SPAN lang=EN-US>jface.jar</SPAN><SPAN style="FONT-FAMILY: 宋体">、</SPAN><SPAN lang=EN-US>runtime.jar</SPAN><SPAN style="FONT-FAMILY: 宋体">、</SPAN><SPAN lang=EN-US>swt.jar</SPAN><SPAN style="FONT-FAMILY: 宋体">，这三个文件是</SPAN><SPAN lang=EN-US>SWT</SPAN><SPAN style="FONT-FAMILY: 宋体">程序的支持库。</SPAN></P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">如果是在本地运行此程序，双击</SPAN><SPAN lang=EN-US>myswt.jar</SPAN><SPAN style="FONT-FAMILY: 宋体">即可（要求</SPAN><SPAN lang=EN-US>Windows</SPAN><SPAN style="FONT-FAMILY: 宋体">中</SPAN><SPAN lang=EN-US>jar</SPAN><SPAN style="FONT-FAMILY: 宋体">格式的文件默认用</SPAN><SPAN lang=EN-US>javaw.exe</SPAN><SPAN style="FONT-FAMILY: 宋体">打开，如下图所示：</SPAN></P>
<P class=a style="TEXT-INDENT: 20pt"><SPAN lang=EN-US><IMG height=104 alt="" src="http://blog.csdn.net/images/blog_csdn_net/glchengang/102036/o_20050302image003.jpg" width=410 border=0></SPAN></P>
<P class=a style="TEXT-INDENT: 20pt"><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">现在我们要将这个程序用</SPAN><SPAN lang=EN-US>JWS</SPAN><SPAN style="FONT-FAMILY: 宋体">部署到服务器端，然后编写一个网页，让用户单击网页上的链接就可以下载该</SPAN><SPAN lang=EN-US>SWT</SPAN><SPAN style="FONT-FAMILY: 宋体">程序并运行。</SPAN></P>
<H3><SPAN lang=EN-US>2、准备工作</SPAN></H3>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">本人的环境为：</SPAN><SPAN lang=EN-US>WinodwsXP SP2 </SPAN><SPAN style="FONT-FAMILY: 宋体">＋</SPAN><SPAN lang=EN-US> JDK1.4.2 </SPAN><SPAN style="FONT-FAMILY: 宋体">＋</SPAN><SPAN lang=EN-US> Tomcat 5.0.28</SPAN></P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">（</SPAN><SPAN lang=EN-US>1</SPAN><SPAN style="FONT-FAMILY: 宋体">）首先得先安装</SPAN><SPAN lang=EN-US>Tomcat</SPAN><SPAN style="FONT-FAMILY: 宋体">，这一步的操作方法本文省略</SPAN></P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">（</SPAN><SPAN lang=EN-US>2</SPAN><SPAN style="FONT-FAMILY: 宋体">）在</SPAN><SPAN lang=EN-US>Tomcat</SPAN><SPAN style="FONT-FAMILY: 宋体">的</SPAN><SPAN lang=EN-US>webapps\ROOT</SPAN><SPAN style="FONT-FAMILY: 宋体">路径下创建一个“</SPAN><SPAN lang=EN-US>myswt</SPAN><SPAN style="FONT-FAMILY: 宋体">”目录。在我的电脑上，其绝对路径如下：</SPAN><SPAN lang=EN-US>E:\Program Files\Apache Software Foundation\Tomcat 5.0\webapps\ROOT\myswt</SPAN><SPAN style="FONT-FAMILY: 宋体">。</SPAN></P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">（</SPAN><SPAN lang=EN-US>3</SPAN><SPAN style="FONT-FAMILY: 宋体">）将前面所述的</SPAN><SPAN lang=EN-US>SWT</SPAN><SPAN style="FONT-FAMILY: 宋体">程序的文件复制到</SPAN><SPAN lang=EN-US>webapps\ROOT\myswt</SPAN><SPAN style="FONT-FAMILY: 宋体">目录中。</SPAN></P>
<H3><SPAN lang=EN-US>3、生成证书</SPAN></H3>
<P class=MsoNormal style="TEXT-INDENT: 0cm"><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-FAMILY: 宋体">创建一个批处理文件：</SPAN><SPAN lang=EN-US>key.bat</SPAN></P>
<DIV style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: #fff0e1; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid">
<P class=a0><SPAN lang=EN-US>c:\jdk\bin\keytool -genkey -keystore myKeystore -alias myself</SPAN></P>
<P class=a0><SPAN lang=EN-US>c:\jdk\bin\keytool -list -keystore myKeystore</SPAN></P>
<P class=a0><SPAN lang=EN-US>pause</SPAN></P></DIV>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">内容说明：</SPAN></P>
<P class=CharChar><SPAN lang=EN-US style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US>keytool</SPAN><SPAN style="FONT-FAMILY: 宋体">是</SPAN><SPAN lang=EN-US>JDK</SPAN><SPAN style="FONT-FAMILY: 宋体">自带的一个工具，用于数字签名。在我的电脑，它是位于</SPAN><SPAN lang=EN-US>c:\jdk\bin\</SPAN><SPAN style="FONT-FAMILY: 宋体">路径下，由于我没有设置环境变量</SPAN><SPAN lang=EN-US>path</SPAN><SPAN style="FONT-FAMILY: 宋体">，所以在批处理文件中硬性指定</SPAN><SPAN lang=EN-US>keytool</SPAN><SPAN style="FONT-FAMILY: 宋体">的路径。如果是自己用或者公司内部用，象本文这样用</SPAN><SPAN lang=EN-US>keytool</SPAN><SPAN style="FONT-FAMILY: 宋体">生成一个自签名的证书也就可以了。但如果你想让签名更正式一些，以获得其他用户的信任，最好去认证中心（如</SPAN><SPAN lang=EN-US> Thawte </SPAN><SPAN style="FONT-FAMILY: 宋体">或</SPAN><SPAN lang=EN-US> VeriSign</SPAN><SPAN style="FONT-FAMILY: 宋体">）获取一个证书。</SPAN></P>
<P class=CharChar><SPAN lang=EN-US style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体">第一句将生成一个证书，文件名：</SPAN><SPAN lang=EN-US>myKeystore</SPAN></P>
<P class=CharChar><SPAN lang=EN-US style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体">第二句是列出密钥证书中的所有入口。（这一句是可选的，只是为了显示出来看一下，不要也行）</SPAN></P>
<P class=CharChar><SPAN lang=EN-US style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体">最后一句是暂停</SPAN><SPAN lang=EN-US>pause</SPAN><SPAN style="FONT-FAMILY: 宋体">，以便批处理完成后，我们可以回顾一下全过程。</SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">运行批处理</SPAN><SPAN lang=EN-US>key.bat</SPAN><SPAN style="FONT-FAMILY: 宋体">后的全部输入过程如下图所示：</SPAN></P>
<P class=a style="TEXT-INDENT: 0cm; TEXT-ALIGN: left" align=left><SPAN lang=EN-US><IMG height=607 alt="" src="http://blog.csdn.net/images/blog_csdn_net/glchengang/102036/o_20050302image004.jpg" width=664 border=0></SPAN></P>
<H3><SPAN lang=EN-US>4、用证用为应用程序签名</SPAN></H3>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">（</SPAN><SPAN lang=EN-US>1</SPAN><SPAN style="FONT-FAMILY: 宋体">）因为签名只认</SPAN><SPAN lang=EN-US>jar</SPAN><SPAN style="FONT-FAMILY: 宋体">包，所以先将</SPAN><SPAN lang=EN-US>swt-win32-3063.dll</SPAN><SPAN style="FONT-FAMILY: 宋体">文件用</SPAN><SPAN lang=EN-US>WinRAR</SPAN><SPAN style="FONT-FAMILY: 宋体">或</SPAN><SPAN lang=EN-US>c:\jdk\bin\jar</SPAN><SPAN style="FONT-FAMILY: 宋体">打一个</SPAN><SPAN lang=EN-US>jar</SPAN><SPAN style="FONT-FAMILY: 宋体">包</SPAN><SPAN lang=EN-US>(swt-win32-3063.jar)</SPAN><SPAN style="FONT-FAMILY: 宋体">。客户端下载后，会自动解开此包，将</SPAN><SPAN lang=EN-US>swt-win32-3063.dll</SPAN><SPAN style="FONT-FAMILY: 宋体">还原到客户端。</SPAN></P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">注意：如果你用</SPAN><SPAN lang=EN-US>WinRAR</SPAN><SPAN style="FONT-FAMILY: 宋体">打包，在压缩时必须选</SPAN><SPAN lang=EN-US>ZIP</SPAN><SPAN style="FONT-FAMILY: 宋体">格式，不能选</SPAN><SPAN lang=EN-US>RAR</SPAN><SPAN style="FONT-FAMILY: 宋体">格式。</SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">（</SPAN><SPAN lang=EN-US>2</SPAN><SPAN style="FONT-FAMILY: 宋体">）创建一个用于签名的批处理文件：</SPAN><SPAN lang=EN-US>jarsigner.bat</SPAN><SPAN style="FONT-FAMILY: 宋体">，其内容如下：</SPAN></P>
<DIV style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: #fff0e1; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid">
<P class=a0><SPAN lang=EN-US>c:\jdk\bin\jarsigner -keystore myKeystore myswt.jar myself</SPAN></P>
<P class=a0><SPAN lang=EN-US>c:\jdk\bin\jarsigner -keystore myKeystore lib\jface.jar myself</SPAN></P>
<P class=a0><SPAN lang=EN-US>c:\jdk\bin\jarsigner -keystore myKeystore lib\runtime.jar myself</SPAN></P>
<P class=a0><SPAN lang=EN-US>c:\jdk\bin\jarsigner -keystore myKeystore lib\swt.jar myself</SPAN></P>
<P class=a0><SPAN lang=EN-US>c:\jdk\bin\jarsigner -keystore myKeystore swt-win32-3063.jar myself</SPAN></P>
<P class=a0><SPAN lang=EN-US>pause</SPAN></P></DIV>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">这里每一条命令都要求你输入密码，它就是在创建证书</SPAN><SPAN lang=EN-US>myKeystore</SPAN><SPAN style="FONT-FAMILY: 宋体">时设置的那个密码。至此，签名证书部份完成了，下一步是创建</SPAN><SPAN lang=EN-US>jnlp</SPAN><SPAN style="FONT-FAMILY: 宋体">文件。</SPAN></P>
<H3><SPAN lang=EN-US>5、创建jnlp文件</SPAN></H3>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">（</SPAN><SPAN lang=EN-US>1</SPAN><SPAN style="FONT-FAMILY: 宋体">）创建一个名为</SPAN><SPAN lang=EN-US>myswt.jnlp</SPAN><SPAN style="FONT-FAMILY: 宋体">的</SPAN><SPAN lang=EN-US>jnlp</SPAN><SPAN style="FONT-FAMILY: 宋体">文件，这个文件是</SPAN><SPAN lang=EN-US>Java Web Start</SPAN><SPAN style="FONT-FAMILY: 宋体">的核心配置文件，其内容如下：</SPAN></P>
<DIV style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: #fff0e1; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid">
<P class=a0><SPAN lang=EN-US>&lt;?xml version="1.0" encoding="GBK"?&gt; </SPAN></P>
<P class=a0><SPAN lang=EN-US>&lt;jnlp codebase="http://localhost:8080/myswt"&gt; </SPAN></P>
<P class=a0><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P class=a0><SPAN lang=EN-US>&nbsp; &lt;information&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp; &lt;title&gt;</SPAN><SPAN style="FONT-FAMILY: 'Courier New'">子在川曰</SPAN><SPAN lang=EN-US>(http://blog.csdn.net/glchengang)&lt;/title&gt; </SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp; &lt;vendor&gt;</SPAN><SPAN style="FONT-FAMILY: 'Courier New'">陈刚</SPAN><SPAN lang=EN-US>&lt;/vendor&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp; &lt;offline-allowed/&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp; &lt;/information&gt; </SPAN></P>
<P class=a0><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P class=a0><SPAN lang=EN-US>&nbsp; &lt;security&gt; </SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;all-permissions/&gt; </SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp; &lt;/security&gt; </SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp; </SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp; &lt;resources&gt; </SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp; &lt;j2se version="1.4+"/&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp; &lt;jar href="myswt.jar"/&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp; &lt;jar href="lib/jface.jar"/&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp; &lt;jar href="lib/runtime.jar"/&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp; &lt;jar href="lib/swt.jar"/&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp; &lt;nativelib href="swt-win32-3063.jar"/&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp; &lt;/resources&gt; </SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp; </SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp; &lt;application-desc main-class="jface.dialog.wizard.WizardDialog1"/&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp; </SPAN></P>
<P class=a0><SPAN lang=EN-US>&lt;/jnlp&gt;&nbsp;&nbsp; </SPAN></P></DIV>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">说明：</SPAN></P>
<P class=CharChar><SPAN lang=EN-US style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US>encoding="GBK"&nbsp; </SPAN><SPAN style="FONT-FAMILY: 宋体">本文选择了</SPAN><SPAN lang=EN-US>GBK</SPAN><SPAN style="FONT-FAMILY: 宋体">，一般来说应该用</SPAN><SPAN lang=EN-US>UTF-8</SPAN><SPAN style="FONT-FAMILY: 宋体">。我在这里之所以选择</SPAN><SPAN lang=EN-US>GBK</SPAN><SPAN style="FONT-FAMILY: 宋体">字符集，主要是为了演示示例方便，如果是正式应用，还是应该改为</SPAN><SPAN lang=EN-US>UTF-8</SPAN><SPAN style="FONT-FAMILY: 宋体">。如果用</SPAN><SPAN lang=EN-US>UTF</SPAN><SPAN style="FONT-FAMILY: 宋体">－</SPAN><SPAN lang=EN-US>8</SPAN><SPAN style="FONT-FAMILY: 宋体">，则该文件的中文要转换成</SPAN><SPAN lang=EN-US>UNICODE</SPAN><SPAN style="FONT-FAMILY: 宋体">码，否则实际运行时将显示乱码，你可以用</SPAN><SPAN lang=EN-US>c:\jdk\bin\native2ascii.exe</SPAN><SPAN style="FONT-FAMILY: 宋体">来进行“汉字－＞</SPAN><SPAN lang=EN-US>UNICODE</SPAN><SPAN style="FONT-FAMILY: 宋体">”的转换。</SPAN></P>
<P class=CharChar><SPAN lang=EN-US style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US>codebase="http://localhost:8080/myswt" </SPAN><SPAN style="FONT-FAMILY: 宋体">本应用程序的</SPAN><SPAN lang=EN-US>URL</SPAN></P>
<P class=CharChar><SPAN lang=EN-US style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US>&lt;information&gt;</SPAN><SPAN style="FONT-FAMILY: 宋体">项，是一些显示信息，</SPAN><SPAN lang=EN-US>&lt;title&gt;</SPAN><SPAN style="FONT-FAMILY: 宋体">、</SPAN><SPAN lang=EN-US>&lt;vendor&gt;</SPAN><SPAN style="FONT-FAMILY: 宋体">都是必选的。</SPAN><SPAN lang=EN-US>&lt;offline-allowed/&gt;</SPAN><SPAN style="FONT-FAMILY: 宋体">是可选的，它表示允许应用程序脱机运行（不和服务器联网）。</SPAN></P>
<P class=CharChar><SPAN lang=EN-US style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US>&lt;security&gt;</SPAN><SPAN style="FONT-FAMILY: 宋体">项是指开放用户本机的所有权限给应用程序，这一项会导致弹出一个数字签名对话框。</SPAN></P>
<P class=CharChar><SPAN lang=EN-US style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US>&lt;resources&gt;</SPAN><SPAN style="FONT-FAMILY: 宋体">列出了用户需要下载的资源。</SPAN><SPAN lang=EN-US>&lt;j2se version="1.4+"/&gt;</SPAN><SPAN style="FONT-FAMILY: 宋体">是指，要求用户本机安装</SPAN><SPAN lang=EN-US>Java1.4</SPAN><SPAN style="FONT-FAMILY: 宋体">以上版本。</SPAN><SPAN lang=EN-US>&lt;nativelib&gt;</SPAN><SPAN style="FONT-FAMILY: 宋体">是指此包含有本地文件，这时</SPAN><SPAN lang=EN-US>JWS</SPAN><SPAN style="FONT-FAMILY: 宋体">下载后会将此包解开。</SPAN></P>
<P class=CharChar><SPAN lang=EN-US style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US>&lt;application-desc&gt;</SPAN><SPAN style="FONT-FAMILY: 宋体">指定了程序的入口类，你也可以指定其他的入口类，它不受限制。</SPAN><SPAN lang=EN-US>jface.dialog.wizard.WizardDialog1</SPAN><SPAN style="FONT-FAMILY: 宋体">是</SPAN><SPAN lang=EN-US>myswt.jar</SPAN><SPAN style="FONT-FAMILY: 宋体">包中的一个向导式对话框，这是我自己编写的一个</SPAN><SPAN lang=EN-US>SWT</SPAN><SPAN style="FONT-FAMILY: 宋体">程序。</SPAN></P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">（</SPAN><SPAN lang=EN-US>2</SPAN><SPAN style="FONT-FAMILY: 宋体">）创建一个</SPAN><SPAN lang=EN-US>HTML</SPAN><SPAN style="FONT-FAMILY: 宋体">网页</SPAN></P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">创建一个</SPAN><SPAN lang=EN-US>HTML</SPAN><SPAN style="FONT-FAMILY: 宋体">网页，网页指向</SPAN><SPAN lang=EN-US>jnlp</SPAN><SPAN style="FONT-FAMILY: 宋体">文件。我们给此</SPAN><SPAN lang=EN-US>HTML</SPAN><SPAN style="FONT-FAMILY: 宋体">网页取名：</SPAN><SPAN lang=EN-US>test.html</SPAN><SPAN style="FONT-FAMILY: 宋体">，其内容如下：</SPAN></P>
<DIV style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: #fff0e1; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid">
<P class=a0><SPAN lang=EN-US>&lt;A HREF="myswt.jnlp"&gt;</SPAN><SPAN style="FONT-FAMILY: 'Courier New'">启动</SPAN><SPAN lang=EN-US>&lt;/A&gt;</SPAN></P></DIV>
<H3><SPAN lang=EN-US>6、最后效果</SPAN></H3>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">（</SPAN><SPAN lang=EN-US>1</SPAN><SPAN style="FONT-FAMILY: 宋体">）最后的服务器的目录结构如下图所示：</SPAN></P>
<P class=a style="TEXT-INDENT: 0cm"><SPAN lang=EN-US><IMG height=186 alt="" src="http://blog.csdn.net/images/blog_csdn_net/glchengang/102036/o_20050302image005.jpg" width=493 border=0></SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">（</SPAN><SPAN lang=EN-US>2</SPAN><SPAN style="FONT-FAMILY: 宋体">）用浏览器浏览：</SPAN><SPAN lang=EN-US>http://localhost:8080/myswt/test.html</SPAN></P>
<P class=a style="TEXT-INDENT: 0cm"><SPAN lang=EN-US><IMG height=296 alt="" src="http://blog.csdn.net/images/blog_csdn_net/glchengang/102036/o_20050302image006.jpg" width=553 border=0></SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">单击“启动”后出现下图，开始从服务器上下载</SPAN><SPAN lang=EN-US>SWT</SPAN><SPAN style="FONT-FAMILY: 宋体">应用程序：</SPAN></P>
<P class=a style="TEXT-INDENT: 0cm"><SPAN lang=EN-US><IMG height=230 alt="" src="http://blog.csdn.net/images/blog_csdn_net/glchengang/102036/o_20050302image007.jpg" width=455 border=0></SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">下载完成后，出现如下图，提示用户是否向应用程序开放本机所有权限（弹出这个对话框是由</SPAN><SPAN lang=EN-US>jnlp</SPAN><SPAN style="FONT-FAMILY: 宋体">文件中的</SPAN><SPAN lang=EN-US>&lt;security&gt;</SPAN><SPAN style="FONT-FAMILY: 宋体">项设置决定的）。</SPAN></P>
<P class=a style="TEXT-INDENT: 0cm"><SPAN lang=EN-US><IMG height=226 alt="" src="http://blog.csdn.net/images/blog_csdn_net/glchengang/102036/o_20050302image008.jpg" width=442 border=0></SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">单击“启动”按钮，将运行程序，出现下图。（附注：这里没有弹出提示你添加快捷菜单的对话框）</SPAN></P>
<P class=a style="TEXT-INDENT: 0cm"><SPAN lang=EN-US><IMG height=243 alt="" src="http://blog.csdn.net/images/blog_csdn_net/glchengang/102036/o_20050302image009.jpg" width=438 border=0></SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US></SPAN>&nbsp;</P>
<H3><SPAN lang=EN-US>7、其他注意事项</SPAN></H3>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">（</SPAN><SPAN lang=EN-US>1</SPAN><SPAN style="FONT-FAMILY: 宋体">）如果单击网页的“启动”链接时，显示的是</SPAN><SPAN lang=EN-US>jnlp</SPAN><SPAN style="FONT-FAMILY: 宋体">文件的内容，还非下载服务器的应用程序。这时你需要做如下检查：</SPAN></P>
<P class=CharChar><SPAN lang=EN-US style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体">在</SPAN><SPAN lang=EN-US>Windows</SPAN><SPAN style="FONT-FAMILY: 宋体">中，</SPAN><SPAN lang=EN-US>jnlp</SPAN><SPAN style="FONT-FAMILY: 宋体">格式的文件应该默认用</SPAN><SPAN lang=EN-US>javaw</SPAN><SPAN style="FONT-FAMILY: 宋体">打开。如果你把它改变成了用记事本或其他程序打开，就也会出错。</SPAN></P>
<P class=CharChar><SPAN lang=EN-US style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN lang=EN-US>WEB</SPAN><SPAN style="FONT-FAMILY: 宋体">服务器是否能否辨识</SPAN><SPAN lang=EN-US>jnlp</SPAN><SPAN style="FONT-FAMILY: 宋体">、</SPAN><SPAN lang=EN-US>jar</SPAN><SPAN style="FONT-FAMILY: 宋体">、</SPAN><SPAN lang=EN-US>class</SPAN><SPAN style="FONT-FAMILY: 宋体">文件的格式。如果你是用</SPAN><SPAN lang=EN-US>Tomcat</SPAN><SPAN style="FONT-FAMILY: 宋体">，可以打开</SPAN><SPAN lang=EN-US>conf</SPAN><SPAN style="FONT-FAMILY: 宋体">目录的</SPAN><SPAN lang=EN-US>WEB.XML</SPAN><SPAN style="FONT-FAMILY: 宋体">文件检查一下。一般来说，较新的</SPAN><SPAN lang=EN-US>WEB</SPAN><SPAN style="FONT-FAMILY: 宋体">服务器都支持</SPAN><SPAN lang=EN-US>jnlp</SPAN><SPAN style="FONT-FAMILY: 宋体">，如果</SPAN><SPAN lang=EN-US>Tomcat</SPAN><SPAN style="FONT-FAMILY: 宋体">、</SPAN><SPAN lang=EN-US>WebLogic</SPAN><SPAN style="FONT-FAMILY: 宋体">等（微软的</SPAN><SPAN lang=EN-US>IIS</SPAN><SPAN style="FONT-FAMILY: 宋体">不支持</SPAN><SPAN lang=EN-US>Java</SPAN><SPAN style="FONT-FAMILY: 宋体">，当然也不可能支持</SPAN><SPAN lang=EN-US>jnlp</SPAN><SPAN style="FONT-FAMILY: 宋体">，我是这么想的没去测试过）。如果不支持，就在</SPAN><SPAN lang=EN-US>WEB</SPAN><SPAN style="FONT-FAMILY: 宋体">服务器的配置文件里加上下面的内容。</SPAN></P>
<DIV style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: #fff0e1; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid">
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp; &lt;mime-mapping&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;extension&gt;class&lt;/extension&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;mime-type&gt;application/java&lt;/mime-type&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp; &lt;/mime-mapping&gt;&nbsp;&nbsp;&nbsp; </SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp; &lt;mime-mapping&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;extension&gt;jar&lt;/extension&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;mime-type&gt;application/java-archive&lt;/mime-type&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp; &lt;/mime-mapping&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp; &lt;mime-mapping&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;extension&gt;jnlp&lt;/extension&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;mime-type&gt;application/x-java-jnlp-file&lt;/mime-type&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp; &lt;/mime-mapping&gt;&nbsp; </SPAN></P></DIV>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">（</SPAN><SPAN lang=EN-US>2</SPAN><SPAN style="FONT-FAMILY: 宋体">）在使用</SPAN><SPAN lang=EN-US>Java Web Start</SPAN><SPAN style="FONT-FAMILY: 宋体">的时候可能会出现</SPAN><SPAN lang=EN-US>"</SPAN><SPAN style="FONT-FAMILY: 宋体">下载资源错误</SPAN><SPAN lang=EN-US>"</SPAN><SPAN style="FONT-FAMILY: 宋体">，大致的出错信息如下：</SPAN><SPAN lang=EN-US>&nbsp;&nbsp; </SPAN></P>
<DIV style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: #fff0e1; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid">
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp; JNLPException[category: Download Error : Exception:</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp; java.io.IOException:</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp; rename failed in cache : LaunchDesc: null ] at..... </SPAN></P></DIV>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">这个错误的原因是因为每次调用</SPAN><SPAN lang=EN-US>Java Web Start</SPAN><SPAN style="FONT-FAMILY: 宋体">都会到</SPAN><SPAN lang=EN-US>server</SPAN><SPAN style="FONT-FAMILY: 宋体">上查找程序是否更新，然后将程序下载到本地的</SPAN><SPAN lang=EN-US>java web start</SPAN><SPAN style="FONT-FAMILY: 宋体">目录下的</SPAN><SPAN lang=EN-US>cache</SPAN><SPAN style="FONT-FAMILY: 宋体">目录中，如果</SPAN><SPAN lang=EN-US>cache</SPAN><SPAN style="FONT-FAMILY: 宋体">中已经有同名文件，而且该文件正在被使用，那么新下载的文件就会出现</SPAN><SPAN lang=EN-US> rename failed</SPAN><SPAN style="FONT-FAMILY: 宋体">错误，而且手工去删除本地的文件还会报错：文件正被使用！</SPAN></P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">这里涉及到</SPAN><SPAN lang=EN-US>Java Web Start</SPAN><SPAN style="FONT-FAMILY: 宋体">中的</SPAN><SPAN lang=EN-US>sign</SPAN><SPAN style="FONT-FAMILY: 宋体">机制，可能对每个</SPAN><SPAN lang=EN-US>jar</SPAN><SPAN style="FONT-FAMILY: 宋体">文件都需要标记，有的时候会在任务管理器中看到</SPAN><SPAN lang=EN-US>javaw.exe</SPAN><SPAN style="FONT-FAMILY: 宋体">在运行，将该程序终止后就可以将本地的</SPAN><SPAN lang=EN-US>jar</SPAN><SPAN style="FONT-FAMILY: 宋体">文件删除掉，说明这些本地文件可能还保留着文件锁定吧！有时即使将</SPAN><SPAN lang=EN-US>Task Manager</SPAN><SPAN style="FONT-FAMILY: 宋体">中将所有的</SPAN><SPAN lang=EN-US>java</SPAN><SPAN style="FONT-FAMILY: 宋体">程序都</SPAN><SPAN lang=EN-US>kill</SPAN><SPAN style="FONT-FAMILY: 宋体">掉还是会出错，必须要注销</SPAN><SPAN lang=EN-US>windows</SPAN><SPAN style="FONT-FAMILY: 宋体">才可以，不知道是不是</SPAN><SPAN lang=EN-US>Java Web Start</SPAN></P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">（</SPAN><SPAN lang=EN-US>3</SPAN><SPAN style="FONT-FAMILY: 宋体">）如果需要给</SPAN><SPAN lang=EN-US>*.jar</SPAN><SPAN style="FONT-FAMILY: 宋体">文件传递参数，可以用如下代码：</SPAN></P>
<DIV style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: #fff0e1; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid">
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp; &lt;application-desc main-class="XBFrame"/&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;argument&gt;-port&lt;/argument&gt;</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;argument&gt;1008&lt;/argument&gt;&nbsp;&nbsp;&nbsp; '' </SPAN><SPAN style="FONT-FAMILY: 'Courier New'">要注意</SPAN><SPAN lang=EN-US>-port </SPAN><SPAN style="FONT-FAMILY: 'Courier New'">和</SPAN><SPAN lang=EN-US>1008</SPAN><SPAN style="FONT-FAMILY: 'Courier New'">是两个参数，要分开写</SPAN><SPAN lang=EN-US>.</SPAN></P>
<P class=a0><SPAN lang=EN-US>&nbsp;&nbsp;&nbsp; &lt;/application-desc&gt;</SPAN></P></DIV>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">（</SPAN><SPAN lang=EN-US>4</SPAN><SPAN style="FONT-FAMILY: 宋体">）有的时候还需要看到</SPAN><SPAN lang=EN-US>*.jar</SPAN><SPAN style="FONT-FAMILY: 宋体">中</SPAN><SPAN lang=EN-US>System.out.print</SPAN><SPAN style="FONT-FAMILY: 宋体">语句输出的信息，就要打开</SPAN><SPAN lang=EN-US>jws</SPAN><SPAN style="FONT-FAMILY: 宋体">的</SPAN><SPAN lang=EN-US>console</SPAN><SPAN style="FONT-FAMILY: 宋体">，可以在</SPAN><SPAN lang=EN-US>jws manager </SPAN><SPAN style="FONT-FAMILY: 宋体">中的首选项中设置</SPAN></P>
<P class=MsoNormal><I><SPAN style="FONT-FAMILY: 宋体">（附注：（</SPAN><SPAN lang=EN-US>2</SPAN></I><I><SPAN style="FONT-FAMILY: 宋体">）、（</SPAN><SPAN lang=EN-US>3</SPAN></I><I><SPAN style="FONT-FAMILY: 宋体">）、（</SPAN><SPAN lang=EN-US>4</SPAN></I><I><SPAN style="FONT-FAMILY: 宋体">）照抄＜＜</SPAN><SPAN lang=EN-US>java web start</SPAN></I><I><SPAN style="FONT-FAMILY: 宋体">实现关键问题</SPAN><SPAN lang=EN-US>(</SPAN></I><I><SPAN style="FONT-FAMILY: 宋体">二</SPAN><SPAN lang=EN-US>)</SPAN></I><I><SPAN style="FONT-FAMILY: 宋体">＞＞一文）</SPAN></I></P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">（</SPAN><SPAN lang=EN-US>5</SPAN><SPAN style="FONT-FAMILY: 宋体">）如果出现失败，最基本的查错手段就是看看出错的“详细信息”，如下图所示。</SPAN></P>
<P class=a style="TEXT-INDENT: 0cm"><SPAN lang=EN-US><IMG height=230 alt="" src="http://blog.csdn.net/images/blog_csdn_net/glchengang/102036/o_20050302image010.jpg" width=455 border=0></SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">单击“详细信息”按钮，出现下图</SPAN></P>
<P class=a style="TEXT-INDENT: 0cm"><SPAN lang=EN-US><IMG height=299 alt="" src="http://blog.csdn.net/images/blog_csdn_net/glchengang/102036/o_20050302image011.jpg" width=450 border=0></SPAN></P>
<P class=a style="TEXT-INDENT: 0cm"><SPAN lang=EN-US></SPAN>&nbsp;</P>
<P class=a style="TEXT-INDENT: 0cm"><SPAN lang=EN-US></SPAN>&nbsp;</P>
<H3>参考资料</H3>
<P class=MsoNormal style="TEXT-INDENT: 18pt"><SPAN class=MsoHyperlink><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial"><A href="http://www-900.ibm.com/developerWorks/cn/java/j-webstart/index.shtml">http://www-900.ibm.com/developerWorks/cn/java/j-webstart/index.shtml</A></SPAN></SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 18pt"><SPAN class=MsoHyperlink><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial"><A href="http://www-900.ibm.com/developerWorks/cn/linux/opensource/os-jws/index.shtml">http://www-900.ibm.com/developerWorks/cn/linux/opensource/os-jws/index.shtml</A></SPAN></SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 18pt"><SPAN class=MsoHyperlink><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial"><A href="http://www-900.ibm.com/developerWorks/cn/java/l-webstart/index.shtml#author1">http://www-900.ibm.com/developerWorks/cn/java/l-webstart/index.shtml#author1</A></SPAN></SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 18pt"><SPAN class=MsoHyperlink><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial"><A href="http://dev.csdn.net/article/14/14216.shtm">http://dev.csdn.net/article/14/14216.shtm</A></SPAN></SPAN><SPAN lang=EN-US>&nbsp; </SPAN><SPAN style="FONT-FAMILY: 宋体">学用</SPAN><SPAN lang=EN-US>Java Web Start </SPAN><SPAN style="FONT-FAMILY: 宋体">部署应用程序</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 0cm"><SPAN lang=EN-US>&nbsp;&nbsp; <A href="http://ecolab.ruc.edu.cn/new/Article_Show.asp?ArticleID=80">http://ecolab.ruc.edu.cn/new/Article_Show.asp?ArticleID=80</A>&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="FONT-FAMILY: 宋体">关于</SPAN><SPAN lang=EN-US>java</SPAN><SPAN style="FONT-FAMILY: 宋体">的数字签名</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 18pt"><SPAN class=MsoHyperlink><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial"><A href="http://www.51one.net/info/3291681715538397.htm">http://www.51one.net/info/3291681715538397.htm</A></SPAN></SPAN><SPAN lang=EN-US>&nbsp;&nbsp; java web start</SPAN><SPAN style="FONT-FAMILY: 宋体">实现关键问题</SPAN><SPAN lang=EN-US>(</SPAN><SPAN style="FONT-FAMILY: 宋体">二</SPAN><SPAN lang=EN-US>)</SPAN></P><img src ="http://www.blogjava.net/jackybu/aggbug/1717.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackybu/" target="_blank">辰</a> 2005-03-05 14:29 <a href="http://www.blogjava.net/jackybu/articles/1717.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA程序员面试32问 </title><link>http://www.blogjava.net/jackybu/articles/1540.html</link><dc:creator>辰</dc:creator><author>辰</author><pubDate>Sun, 27 Feb 2005 09:38:00 GMT</pubDate><guid>http://www.blogjava.net/jackybu/articles/1540.html</guid><wfw:comment>http://www.blogjava.net/jackybu/comments/1540.html</wfw:comment><comments>http://www.blogjava.net/jackybu/articles/1540.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackybu/comments/commentRss/1540.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackybu/services/trackbacks/1540.html</trackback:ping><description><![CDATA[<SPAN id=ArticleContent1_ArticleContent1_lblContent><FONT face="Courier New" size=2>第一，谈谈final, finally, finalize的区别。</FONT> 
<P><FONT face="Courier New" size=2>第二，Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类，是否可以implements(实现)interface(接口)?</FONT></P>
<P><FONT face="Courier New" size=2>第三，Static Nested Class 和 Inner Class的不同，说得越多越好(面试题有的很笼统)。</FONT></P>
<P><FONT face="Courier New" size=2>第四，&amp;和&amp;&amp;的区别。</FONT></P>
<P><FONT face="Courier New" size=2>第五，HashMap和Hashtable的区别。</FONT></P>
<P><FONT face="Courier New" size=2>第六，Collection 和 Collections的区别。</FONT></P>
<P><FONT face="Courier New" size=2>第七，什么时候用assert。</FONT></P>
<P><FONT face="Courier New" size=2>第八，GC是什么? 为什么要有GC? </FONT></P>
<P><FONT face="Courier New" size=2>第九，String s = new String("xyz");创建了几个String Object?</FONT></P>
<P><FONT face="Courier New" size=2>第十，Math.round(11.5)等於多少? Math.round(-11.5)等於多少?</FONT></P>
<P><FONT face="Courier New" size=2>第十一，short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?</FONT></P>
<P><FONT face="Courier New" size=2>第十二，sleep() 和 wait() 有什么区别?</FONT></P>
<P><FONT face="Courier New" size=2>第十三，Java有没有goto?</FONT></P>
<P><FONT face="Courier New" size=2>第十四，数组有没有length()这个方法? String有没有length()这个方法?</FONT></P>
<P><FONT face="Courier New" size=2>第十五，Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?</FONT></P>
<P><FONT face="Courier New" size=2>第十六，Set里的元素是不能重复的，那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?</FONT></P>
<P><FONT face="Courier New" size=2>第十七，给我一个你最常见到的runtime exception。</FONT></P>
<P><FONT face="Courier New" size=2>第十八，error和exception有什么区别?</FONT></P>
<P><FONT face="Courier New" size=2>第十九，List, Set, Map是否继承自Collection接口?</FONT></P>
<P><FONT face="Courier New" size=2>第二十，abstract class和interface有什么区别?</FONT></P>
<P><FONT face="Courier New" size=2>第二十一，abstract的method是否可同时是static,是否可同时是native，是否可同时是synchronized?</FONT></P>
<P><FONT face="Courier New" size=2>第二十二，接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?</FONT></P>
<P><FONT face="Courier New" size=2>第二十三，启动一个线程是用run()还是start()?</FONT></P>
<P><FONT face="Courier New" size=2>第二十四，构造器Constructor是否可被override?</FONT></P>
<P><FONT face="Courier New" size=2>第二十五，是否可以继承String类?</FONT></P>
<P><FONT face="Courier New" size=2>第二十六，当一个线程进入一个对象的一个synchronized方法后，其它线程是否可进入此对象的其它方法?</FONT></P>
<P><FONT face="Courier New" size=2>第二十七，try {}里有一个return语句，那么紧跟在这个try后的finally {}里的code会不会被执行，什么时候被执行，在return前还是后?</FONT></P>
<P><FONT face="Courier New" size=2>第二十八，编程题: 用最有效率的方法算出2乘以8等於几?</FONT></P>
<P><FONT face="Courier New" size=2>第二十九，两个对象值相同(x.equals(y) == true)，但却可有不同的hash code，这句话对不对?</FONT></P>
<P><FONT face="Courier New" size=2>第三十，当一个对象被当作参数传递到一个方法后，此方法可改变这个对象的属性，并可返回变化后的结果，那么这里到底是值传递还是引用传递?</FONT></P>
<P><FONT face="Courier New" size=2>第三十一，swtich是否能作用在byte上，是否能作用在long上，是否能作用在String上?</FONT></P>
<P><FONT face="Courier New" size=2>第三十二，编程题: 写一个Singleton出来。<BR><BR></FONT><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0000ff size=2><STRONG>以下是答案<BR><BR></STRONG></FONT><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第一</FONT>，谈谈final, finally, finalize的区别。<BR>final—修饰符（关键字）如果一个类被声明为final，意味着它不能再派生出新的子类，不能作为父类被继承。因此一个类不能既被声明为 abstract的，又被声明为final的。将变量或方法声明为final，可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值，而在以后的引用中只能读取，不可修改。被声明为final的方法也同样只能使用，不能重载<BR>finally—再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常，那么相匹配的 catch 子句就会执行，然后控制就会进入 finally 块（如果有的话）。<BR>finalize—方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的，因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第二</FONT>，Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类，是否可以implements(实现)interface(接口)?<BR>匿名的内部类是没有名字的内部类。不能extends(继承) 其它类，但一个内部类可以作为一个接口，由另一个内部类实现。</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第三</FONT>，Static Nested Class 和 Inner Class的不同，说得越多越好(面试题有的很笼统)。<BR>Nested Class （一般是C++的说法），Inner Class (一般是JAVA的说法)。Java内部类与C++嵌套类最大的不同就在于是否有指向外部的引用上。具体可见http: //www.frontfree.net/articles/services/view.asp?id=704&amp;page=1<BR>注： 静态内部类（Inner Class）意味着1创建一个static内部类的对象，不需要一个外部类对象，2不能从一个static内部类的一个对象访问一个外部类对象</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2>第四，&amp;和&amp;&amp;的区别。<BR>&amp;是位运算符。&amp;&amp;是布尔逻辑运算符。</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第五</FONT>，HashMap和Hashtable的区别。<BR>都属于Map接口的类，实现了将惟一键映射到特定的值上。<BR>HashMap 类没有分类或者排序。它允许一个 null 键和多个 null 值。 <BR>Hashtable 类似于 HashMap，但是不允许 null 键和 null 值。它也比 HashMap 慢，因为它是同步的。</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第六</FONT>，Collection 和 Collections的区别。<BR>Collections是个java.util下的类，它包含有各种有关集合操作的静态方法。<BR>Collection是个java.util下的接口，它是各种集合结构的父接口。</FONT></P>
<P><BR><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第七</FONT>，什么时候用assert。<BR>断言是一个包含布尔表达式的语句，在执行这个语句时假定该表达式为 true。如果表达式计算为 false，那么系统会报告一个 AssertionError。它用于调试目的： <BR>&nbsp; assert(a &gt; 0); // throws an AssertionError if a &lt;= 0 <BR>断言可以有两种形式：&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp; assert Expression1 ; <BR>&nbsp; assert Expression1 : Expression2 ; <BR>Expression1 应该总是产生一个布尔值。 <BR>Expression2 可以是得出一个值的任意表达式。这个值用于生成显示更多调试信息的 String 消息。<BR>断言在默认情况下是禁用的。要在编译时启用断言，需要使用 source 1.4 标记：&nbsp; <BR>&nbsp; javac -source 1.4 Test.java<BR>要在运行时启用断言，可使用 -enableassertions 或者 -ea 标记。 <BR>要在运行时选择禁用断言，可使用 -da 或者 -disableassertions 标记。 <BR>要系统类中启用断言，可使用 -esa 或者 -dsa 标记。还可以在包的基础上启用或者禁用断言。 <BR>可以在预计正常情况下不会到达的任何位置上放置断言。断言可以用于验证传递给私有方法的参数。不过，断言不应该用于验证传递给公有方法的参数，因为不管是否启用了断言，公有方法都必须检查其参数。不过，既可以在公有方法中，也可以在非公有方法中利用断言测试后置条件。另外，断言不应该以任何方式改变程序的状态。 </FONT></P>
<P><BR><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第八</FONT>，GC是什么? 为什么要有GC? (基础)。<BR>GC是垃圾收集器。Java 程序员不用担心内存管理，因为垃圾收集器会自动进行管理。要请求垃圾收集，可以调用下面的方法之一： <BR>&nbsp; System.gc()<BR>&nbsp; Runtime.getRuntime().gc()</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第九</FONT>，String s = new String("xyz");创建了几个String Object?<BR>两个对象，一个是“xyx”,一个是指向“xyx”的引用对象s。</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第十</FONT>，Math.round(11.5)等於多少? Math.round(-11.5)等於多少?<BR>Math.round(11.5)返回（long）12，Math.round(-11.5)返回（long）-11;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第十一</FONT>，short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?<BR>short s1 = 1; s1 = s1 + 1;有错，s1是short型，s1+1是int型,不能显式转化为short型。可修改为s1 =(short)(s1 + 1) 。short s1 = 1; s1 += 1正确。</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第十二</FONT>，sleep() 和 wait() 有什么区别? 搞线程的最爱<BR>sleep()方法是使线程停止一段时间的方法。在sleep 时间间隔期满后，线程不一定立即恢复执行。这是因为在那个时刻，其它线程可能正在运行而且没有被调度为放弃执行，除非(a)“醒来”的线程具有更高的优先级<BR>(b)正在运行的线程因为其它原因而阻塞。<BR>wait()是线程交互时，如果线程对一个同步对象x 发出一个wait()调用，该线程会暂停执行，被调对象进入等待状态，直到被唤醒或等待时间到。</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2></FONT>&nbsp;</P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第十三</FONT>，Java有没有goto?<BR>Goto—java中的保留字，现在没有在java中使用。</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第十四</FONT>，数组有没有length()这个方法? String有没有length()这个方法？<BR>数组没有length()这个方法，有length的属性。<BR>String有有length()这个方法。</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第十五</FONT>，Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?<BR>方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现，重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数，我们说该方法被重写 (Overriding)。子类的对象使用这个方法时，将调用子类中的定义，对它而言，父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法，它们或有不同的参数个数或有不同的参数类型，则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第十六</FONT>，Set里的元素是不能重复的，那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?<BR>Set里的元素是不能重复的，那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等。<BR>equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖，为的是当两个分离的对象的内容和类型相配的话，返回真值。</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第十七</FONT>，给我一个你最常见到的runtime exception。<BR>ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException, <BR>ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFormatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第十八</FONT>，error和exception有什么区别?<BR>error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。<BR>exception 表示一种设计或实现问题。也就是说，它表示如果程序运行正常，从不会发生的情况。</FONT></P>
<P><BR><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第十九</FONT>，List, Set, Map是否继承自Collection接口?<BR>List，Set是</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2>Map不是</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0033ff size=2><FONT style="BACKGROUND-COLOR: #ffcccc"><FONT style="BACKGROUND-COLOR: #ffffcc">第二十</FONT>，abstract class和interface有什么区别?<BR>声明方法的存在而不去实现它的类被叫做抽象类（abstract class），它用于要创建一个体现某些基本行为的类，并为该类声明方法，但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量，其类型是一个抽象类，并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现，否则它们也是抽象类为。取而代之，在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。<BR>接口（interface）是抽象类的变体。在接口中，所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的，没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似，除了该实现类不能从接口定义中继承行为。当类实现特殊接口时，它定义（即将程序体给予）所有这种接口的方法。然后，它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类，它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换，instanceof 运算符可以用来决定某对象的类是否实现了接口。</FONT><BR></FONT><FONT style="BACKGROUND-COLOR: #ffcccc" color=#0000ff><BR><FONT face="Courier New" size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第二十一</FONT>，abstract的method是否可同时是static,是否可同时是native，是否可同时是synchronized?<BR>都不能</FONT></FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0000ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第二十二</FONT>，接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?<BR>接口可以继承接口。抽象类可以实现(implements)接口，抽象类是否可继承实体类，但前提是实体类必须有明确的构造函数。</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #ffcccc" face="Courier New" color=#0000ff size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第二十三</FONT>，启动一个线程是用run()还是start()?<BR>启动一个线程是调用start()方法，使线程所代表的虚拟处理机处于可运行状态，这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。</FONT></P><FONT style="BACKGROUND-COLOR: #ffcccc" color=#0000ff>
<P><FONT face="Courier New" size=2></FONT>&nbsp;</P>
<P><FONT face="Courier New" size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第二十四</FONT>，构造器Constructor是否可被override?<BR>构造器Constructor不能被继承，因此不能重写Overriding，但可以被重载Overloading。</FONT></P>
<P><FONT face="Courier New" size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第二十五</FONT>，是否可以继承String类?<BR>String类是final类故不可以继承。</FONT></P>
<P><FONT face="Courier New" size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第二十六</FONT>，当一个线程进入一个对象的一个synchronized方法后，其它线程是否可进入此对象的其它方法?<BR>不能，一个对象的一个synchronized方法只能由一个线程访问。</FONT></P>
<P><FONT face="Courier New" size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第二十七</FONT>，try {}里有一个return语句，那么紧跟在这个try后的finally {}里的code会不会被执行，什么时候被执行，在return前还是后?<BR>会执行，在return前执行。</FONT></P>
<P><BR><FONT face="Courier New" size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第二十八</FONT>，编程题: 用最有效率的方法算出2乘以8等於几?<BR>有C背景的程序员特别喜欢问这种问题。</FONT></P>
<P><FONT face="Courier New" size=2>2 &lt;&lt; 3</FONT></P>
<P><FONT face="Courier New" size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第二十九</FONT>，两个对象值相同(x.equals(y) == true)，但却可有不同的hash code，这句话对不对?<BR>不对，有相同的hash code。</FONT></P>
<P><FONT face="Courier New" size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第三十</FONT>，当一个对象被当作参数传递到一个方法后，此方法可改变这个对象的属性，并可返回变化后的结果，那么这里到底是值传递还是引用传递? <BR>是值传递。Java 编程语言只由值传递参数。当一个对象实例作为一个参数被传递到方法中时，参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变，但对象的引用是永远不会改变的。</FONT></P>
<P><BR><FONT face="Courier New" size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第三十一</FONT>，swtich是否能作用在byte上，是否能作用在long上，是否能作用在String上?<BR>switch（expr1）中，expr1是一个整数表达式。因此传递给 switch 和 case 语句的参数应该是 int、 short、 char 或者 byte。long,string 都不能作用于swtich。</FONT></P>
<P><FONT face="Courier New" size=2><FONT style="BACKGROUND-COLOR: #ffffcc">第三十二</FONT>，编程题: 写一个Singleton出来。<BR>&nbsp;&nbsp;&nbsp;&nbsp; Singleton模式主要作用是保证在Java应用程序中，一个类Class只有一个实例存在。<BR>一般Singleton模式通常有几种种形式:<BR>第一种形式: 定义一个类，它的构造函数为private的，它有一个static的private的该类变量，在类初始化时实例话，通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。<BR>public class Singleton {<BR>　　private Singleton(){}<BR>　　//在自己内部定义自己一个实例，是不是很奇怪？<BR>　　//注意这是private 只供内部调用<BR>　　private static Singleton instance = new Singleton();<BR>　　//这里提供了一个供外部访问本class的静态方法，可以直接访问　　<BR>　　public static Singleton getInstance() {<BR>　　　　return instance; 　　<BR>　　 } <BR>} <BR>第二种形式: <BR>public class Singleton { <BR>　　private static Singleton instance = null;<BR>　　public static synchronized Singleton getInstance() {<BR>　　//这个方法比上面有所改进，不用每次都进行生成对象，只是第一次　　　 　<BR>　　//使用时生成实例，提高了效率！<BR>　　if (instance==null)<BR>　　　　instance＝new Singleton();<BR>return instance; 　　} <BR>} <BR>其他形式:<BR>定义一个类，它的构造函数为private的，所有方法为static的。<BR>一般认为第一种形式要更加安全些 <BR>第三十三 Hashtable和HashMap <BR>Hashtable继承自Dictionary类，而HashMap是Java1.2引进的Map interface的一个实现 </FONT></P>
<P><FONT face="Courier New" size=2>HashMap允许将null作为一个entry的key或者value，而Hashtable不允许 </FONT></P>
<P><FONT face="Courier New" size=2>还有就是，HashMap把Hashtable的contains方法去掉了，改成containsvalue和containsKey。因为contains方法容易让人引起误解。 </FONT></P>
<P><FONT face="Courier New" size=2>最大的不同是，Hashtable的方法是Synchronize的，而HashMap不是，在 <BR>多个线程访问Hashtable时，不需要自己为它的方法实现同步，而HashMap <BR>就必须为之提供外同步。 </FONT></P>
<P><FONT size=2><FONT face="Courier New">Hashtable和HashMap采用的hash/rehash算法都大概一样，所以性能不会有很大的差异。</FONT><BR></FONT></P></FONT></SPAN><img src ="http://www.blogjava.net/jackybu/aggbug/1540.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackybu/" target="_blank">辰</a> 2005-02-27 17:38 <a href="http://www.blogjava.net/jackybu/articles/1540.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对Java同步一些理解 </title><link>http://www.blogjava.net/jackybu/articles/1539.html</link><dc:creator>辰</dc:creator><author>辰</author><pubDate>Sun, 27 Feb 2005 09:37:00 GMT</pubDate><guid>http://www.blogjava.net/jackybu/articles/1539.html</guid><wfw:comment>http://www.blogjava.net/jackybu/comments/1539.html</wfw:comment><comments>http://www.blogjava.net/jackybu/articles/1539.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackybu/comments/commentRss/1539.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackybu/services/trackbacks/1539.html</trackback:ping><description><![CDATA[<P>对Java同步一些理解<BR>kingfish 2005<BR>------------------------------------------------------------<BR>基本概念:<BR>&nbsp; 每个Object都会有1个锁.<BR>&nbsp; 同步就是串行使用一些资源.</P>
<P>(说明:以下有些例子为了突出重点,省略了不必要的代码.特别是省掉了一些成员变量,就是需要同步的对象.)</P>
<P>1. 多线程中对共享、可变的数据进行同步.<BR>&nbsp;&nbsp; 对于函数中的局部变量没必要进行同步.<BR>&nbsp;&nbsp; 对于不可变数据,也没必要进行同步.</P>
<P>&nbsp;&nbsp; 多线程中访问共享可变数据才有必要.</P>
<P><BR>2. 单个线程中可以使用synchronized,而且可以嵌套,但无意义.<BR>&nbsp;&nbsp; class Test {<BR>&nbsp;&nbsp;&nbsp;&nbsp; public static void main(String[] args) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Test t = new Test();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized(t) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized(t) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("ok!");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp; }<BR>&nbsp;&nbsp; <BR>3. 对象实例的锁<BR>&nbsp;&nbsp; class Test{<BR>&nbsp;&nbsp;&nbsp;&nbsp; public synchronized void f1(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //do something here<BR>&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp; public void f2(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized(this){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //do something here<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp; }<BR>&nbsp;<BR>&nbsp;&nbsp; 上面的f1()和f2()效果一致, synchronized取得的锁都是Test某个实列(this)的锁.<BR>&nbsp;&nbsp; 比如: Test t = new Test(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 线程A调用t.f2()时, 线程B无法进入t.f1(),直到t.f2()结束.</P>
<P>&nbsp;&nbsp; 作用: 多线程中访问Test的同一个实例的同步方法时会进行同步.</P>
<P>4. class的锁<BR>&nbsp;&nbsp; class Test{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final static Object o= new Object();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static synchronized void f1(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //do something here<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static void f2(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized(Test.class){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //do something here<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static void f3(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized (Class.forName("Test")) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //do something here<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (ClassNotFoundException ex) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static void g(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized(o){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //do something here<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp; 上面f1(),f2(),f3(),g()效果一致<BR>&nbsp;&nbsp; f1(),f2(),f3()中synchronized取得的锁都是Test.class的锁. <BR>&nbsp;&nbsp; <BR>&nbsp;&nbsp; g()是自己产生一个对象o,利用o的锁做同步<BR>&nbsp;&nbsp; 作用: 多线程中访问此类或此类任一个实例的同步方法时都会同步. singleton模式lazily initializing属于此类.</P>
<P>5. static method<BR>&nbsp;&nbsp; class Test{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private static int v = 0;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static void f1(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //do something, 但函数中没用用到v<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public synchronized static void f2(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //do something, 函数中对v进行了读/写.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <BR>&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp; 多线程中使用Test的某个实列时,<BR>&nbsp;&nbsp;&nbsp; (1) f1()是线程安全的,不需要同步<BR>&nbsp;&nbsp;&nbsp; (2) f2()这个静态方法中使用了函数外静态变量,所以需要同步.</P>
<P>6.&nbsp; 对线程的run()进行同步没有意义,如 public synchronized void run()<BR>&nbsp;&nbsp;&nbsp; class Test extends Thread{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public synchronized void run(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(true){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //do something<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public synchronized void f(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //...<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; 这种例子会有一个问题, 执行run()时(内部在循环), 外部无法执行f()</P>
<P><BR>&nbsp;&nbsp;&nbsp; class Test extends Thread{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public synchronized void run(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //do something<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; 这种例子同步基本没用, 因为run()通常靠 new Test().start()来执行的.<BR>&nbsp;&nbsp;&nbsp; 因为Test实例不同,锁也不同.</P><img src ="http://www.blogjava.net/jackybu/aggbug/1539.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackybu/" target="_blank">辰</a> 2005-02-27 17:37 <a href="http://www.blogjava.net/jackybu/articles/1539.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDK1.5 最新特性 </title><link>http://www.blogjava.net/jackybu/articles/1206.html</link><dc:creator>辰</dc:creator><author>辰</author><pubDate>Tue, 15 Feb 2005 03:22:00 GMT</pubDate><guid>http://www.blogjava.net/jackybu/articles/1206.html</guid><wfw:comment>http://www.blogjava.net/jackybu/comments/1206.html</wfw:comment><comments>http://www.blogjava.net/jackybu/articles/1206.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackybu/comments/commentRss/1206.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackybu/services/trackbacks/1206.html</trackback:ping><description><![CDATA[<FONT size=4>请先看以下两段代码（分别选自 Core Java 5E 和 Core Java 7E），不同之处已用蓝色表明。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;程序一：<BR>&nbsp;&nbsp;&nbsp; public class Welcome<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static void main(String[] args)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String[] greeting = new String[3];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; greeting[0] = "Welcome to Core Java";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; greeting[1] = "by Cay Horstmann";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; greeting[2] = "and Gary Cornell";<BR>&nbsp;&nbsp;&nbsp; <BR></FONT><FONT size=4><FONT color=#0000ff>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; greeting.length; i++)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(greeting[i]);<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;程序二：<BR>&nbsp;&nbsp;&nbsp; public class Welcome<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static void main(String[] args)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String[] greeting = new String[3];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; greeting[0] = "Welcome to Core Java";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; greeting[1] = "by Cay Horstmann";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; greeting[2] = "and Gary Cornell";<BR>&nbsp;&nbsp;&nbsp; <BR></FONT><FONT size=4><FONT color=#0000ff>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (String g : greeting)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(g);</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }</FONT> 
<P><FONT size=4>&nbsp;&nbsp;&nbsp;&nbsp;这两个程序输出的结果是相同的，均为：<BR><FONT color=#800080>&nbsp;&nbsp;&nbsp;&nbsp;Welcome to Core Java<BR>&nbsp;&nbsp;&nbsp;&nbsp;by Cay Horstmann<BR>&nbsp;&nbsp;&nbsp;&nbsp;and Gary Cornell<BR><BR></FONT><FONT color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;而程序二如果使用JDK1.4或以下版本编译就会出错，使用1.5则可顺利通过。这说明了此“<FONT color=#0000ff>：</FONT>”操作符是JDK1.5新加的特性之一。</FONT></FONT></P></SPAN><img src ="http://www.blogjava.net/jackybu/aggbug/1206.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackybu/" target="_blank">辰</a> 2005-02-15 11:22 <a href="http://www.blogjava.net/jackybu/articles/1206.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java异常学习心得</title><link>http://www.blogjava.net/jackybu/articles/1197.html</link><dc:creator>辰</dc:creator><author>辰</author><pubDate>Tue, 15 Feb 2005 03:00:00 GMT</pubDate><guid>http://www.blogjava.net/jackybu/articles/1197.html</guid><wfw:comment>http://www.blogjava.net/jackybu/comments/1197.html</wfw:comment><comments>http://www.blogjava.net/jackybu/articles/1197.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackybu/comments/commentRss/1197.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackybu/services/trackbacks/1197.html</trackback:ping><description><![CDATA[<P>Java异常学习心得</P>
<P>本文重在Java中异常机制的一些概念。写本文的目的在于方便我很长时间后若是忘了这些东西可以通过这片文章迅速回忆起来。</P>
<P>1.&nbsp;异常机制<BR>1.1&nbsp;异常机制是指当程序出现错误后，程序如何处理。具体来说，异常机制提供了程序退出的安全通道。当出现错误后，程序执行的流程发生改变，程序的控制权转移到异常处理器。<BR>1.2&nbsp;传统的处理异常的办法是，函数返回一个特殊的结果来表示出现异常（通常这个特殊结果是大家约定俗称的），调用该函数的程序负责检查并分析函数返回的结果。这样做有如下的弊端：例如函数返回-1代表出现异常，但是如果函数确实要返回-1这个正确的值时就会出现混淆；可读性降低，将程序代码与处理异常的代码混爹在一起；由调用函数的程序来分析错误，这就要求客户程序员对库函数有很深的了解。<BR>1.3&nbsp;异常处理的流程<BR>1.3.1&nbsp;遇到错误，方法立即结束，并不返回一个值；同时，抛出一个异常对象<BR>1.3.2&nbsp;调用该方法的程序也不会继续执行下去，而是搜索一个可以处理该异常的异常处理器，并执行其中的代码</P>
<P>2&nbsp;异常的分类<BR>2.1&nbsp;异常的分类<BR>2.1.1&nbsp;异常的继承结构：基类为Throwable，Error和Exception继承Throwable，RuntimeException和IOException等继承Exception，具体的RuntimeException继承RuntimeException。<BR>2.1.2&nbsp;Error和RuntimeException及其子类成为未检查异常（unchecked），其它异常成为已检查异常（checked）。<BR>2.2&nbsp;每个类型的异常的特点<BR>2.2.1&nbsp;Error体系<BR>Error类体系描述了Java运行系统中的内部错误以及资源耗尽的情形。应用程序不应该抛出这种类型的对象（一般是由虚拟机抛出）。如果出现这种错误，除了尽力使程序安全退出外，在其他方面是无能为力的。所以，在进行程序设计时，应该更关注Exception体系。<BR>2.2.2&nbsp;Exception体系<BR>Exception体系包括RuntimeException体系和其他非RuntimeException的体系<BR>2.2.2.1&nbsp;RuntimeException<BR>RuntimeException体系包括错误的类型转换、数组越界访问和试图访问空指针等等。处理RuntimeException的原则是：如果出现RuntimeException，那么一定是程序员的错误。例如，可以通过检查数组下标和数组边界来避免数组越界访问异常。<BR>2.2.2.2&nbsp;其他（IOException等等）<BR>这类异常一般是外部错误，例如试图从文件尾后读取数据等，这并不是程序本身的错误，而是在应用环境中出现的外部错误。<BR>2.3&nbsp;与C++异常分类的不同<BR>2.3.1&nbsp;其实，Java中RuntimeException这个类名起的并不恰当，因为任何异常都是运行时出现的。（在编译时出现的错误并不是异常，换句话说，异常就是为了解决程序运行时出现的的错误）。<BR>2.3.2&nbsp;C++中logic_error与Java中的RuntimeException是等价的，而runtime_error与Java中非RuntimeException类型的异常是等价的。</P>
<P>3&nbsp;异常的使用方法<BR>3.1&nbsp;声明方法抛出异常&nbsp;<BR>3.1.1&nbsp;语法：throws（略）<BR>3.1.2&nbsp;为什么要声明方法抛出异常？<BR>方法是否抛出异常与方法返回值的类型一样重要。假设方法抛出异常确没有声明该方法将抛出异常，那么客户程序员可以调用这个方法而且不用编写处理异常的代码。那么，一旦出现异常，那么这个异常就没有合适的异常控制器来解决。<BR>3.1.3&nbsp;为什么抛出的异常一定是已检查异常？<BR>RuntimeException与Error可以在任何代码中产生，它们不需要由程序员显示的抛出，一旦出现错误，那么相应的异常会被自动抛出。而已检查异常是由程序员抛出的，这分为两种情况：客户程序员调用会抛出异常的库函数（库函数的异常由库程序员抛出）；客户程序员自己使用throw语句抛出异常。遇到Error，程序员一般是无能为力的；遇到RuntimeException，那么一定是程序存在逻辑错误，要对程序进行修改（相当于调试的一种方法）；只有已检查异常才是程序员所关心的，程序应该且仅应该抛出或处理已检查异常。<BR>3.1.4&nbsp;注意：覆盖父类某方法的子类方法不能抛出比父类方法更多的异常，所以，有时设计父类的方法时会声明抛出异常，但实际的实现方法的代码却并不抛出异常，这样做的目的就是为了方便子类方法覆盖父类方法时可以抛出异常。<BR>3.2&nbsp;如何抛出异常<BR>3.2.1&nbsp;语法：throw（略）<BR>3.2.2&nbsp;抛出什么异常？<BR>对于一个异常对象，真正有用的信息时异常的对象类型，而异常对象本身毫无意义。比如一个异常对象的类型是ClassCastException，那么这个类名就是唯一有用的信息。所以，在选择抛出什么异常时，最关键的就是选择异常的类名能够明确说明异常情况的类。<BR>3.2.3&nbsp;异常对象通常有两种构造函数：一种是无参数的构造函数；另一种是带一个字符串的构造函数，这个字符串将作为这个异常对象除了类型名以外的额外说明。<BR>3.2.4&nbsp;创建自己的异常：当Java内置的异常都不能明确的说明异常情况的时候，需要创建自己的异常。需要注意的是，唯一有用的就是类型名这个信息，所以不要在异常类的设计上花费精力。<BR>3.3&nbsp;捕获异常<BR>如果一个异常没有被处理，那么，对于一个非图形界面的程序而言，该程序会被中止并输出异常信息；对于一个图形界面程序，也会输出异常的信息，但是程序并不中止，而是返回用户界面处理循环中。<BR>3.3.1&nbsp;语法：try、catch和finally（略）<BR>控制器模块必须紧接在try块后面。若掷出一个异常，异常控制机制会搜寻参数与异常类型相符的第一个控制器随后它会进入那个catch 从句，并认为异常已得到控制。一旦catch 从句结束对控制器的搜索也会停止。<BR>3.3.1.1&nbsp;捕获多个异常（注意语法与捕获的顺序）（略）<BR>3.3.1.2&nbsp;finally的用法与异常处理流程（略）<BR>3.3.2&nbsp;异常处理做什么？<BR>对于Java来说，由于有了垃圾收集，所以异常处理并不需要回收内存。但是依然有一些资源需要程序员来收集，比如文件、网络连接和图片等资源。<BR>3.3.3&nbsp;应该声明方法抛出异常还是在方法中捕获异常？<BR>原则：捕捉并处理哪些知道如何处理的异常，而传递哪些不知道如何处理的异常<BR>3.3.4&nbsp;再次抛出异常<BR>3.3.4.1&nbsp;为什么要再次抛出异常？<BR>在本级中，只能处理一部分内容，有些处理需要在更高一级的环境中完成，所以应该再次抛出异常。这样可以使每级的异常处理器处理它能够处理的异常。<BR>3.3.4.2&nbsp;异常处理流程<BR>对应与同一try块的catch块将被忽略，抛出的异常将进入更高的一级。</P>
<P>4&nbsp;关于异常的其他问题<BR>4.1&nbsp;过度使用异常<BR>首先，使用异常很方便，所以程序员一般不再愿意编写处理错误的代码，而仅仅是简简单单的抛出一个异常。这样做是不对的，对于完全已知的错误，应该编写处理这种错误的代码，增加程序的鲁棒性。另外，异常机制的效率很差。<BR>4.2&nbsp;将异常与普通错误区分开<BR>对于普通的完全一致的错误，应该编写处理这种错误的代码，增加程序的鲁棒性。只有外部的不能确定和预知的运行时错误才需要使用异常。<BR>4.3&nbsp;异常对象中包含的信息<BR>一般情况下，异常对象唯一有用的信息就是类型信息。但使用异常带字符串的构造函数时，这个字符串还可以作为额外的信息。调用异常对象的getMessage()、toString()或者printStackTrace()方法可以分别得到异常对象的额外信息、类名和调用堆栈的信息。并且后一种包含的信息是前一种的超集。<BR></P><img src ="http://www.blogjava.net/jackybu/aggbug/1197.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackybu/" target="_blank">辰</a> 2005-02-15 11:00 <a href="http://www.blogjava.net/jackybu/articles/1197.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于接口的简单解释 </title><link>http://www.blogjava.net/jackybu/articles/1098.html</link><dc:creator>辰</dc:creator><author>辰</author><pubDate>Sat, 12 Feb 2005 15:23:00 GMT</pubDate><guid>http://www.blogjava.net/jackybu/articles/1098.html</guid><wfw:comment>http://www.blogjava.net/jackybu/comments/1098.html</wfw:comment><comments>http://www.blogjava.net/jackybu/articles/1098.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackybu/comments/commentRss/1098.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackybu/services/trackbacks/1098.html</trackback:ping><description><![CDATA[汽车的方向盘就是可以看做是一个接口，他有什么方法？&nbsp;他有转向的方法，但他不需要<BR>自己去实现汽车如何转向，只要告诉其它的其它部件，我调用转向的时候你们就给我转。。。。<BR><BR>写接口一般是高级行为，做设计的时候用的多，当两个程序员要相互调用的各自的程序的时候<BR>就应该通过接口来调用，隐藏实现细节，对方要啥方法，我就在接口中定义这个几个方法，<BR>如何实现不用对方知道，他知道调用这个几个方法就行了，其它的相关的方法根本不用对方知道，<BR>这就达到了隐藏细节的目的，减少差错！ <B><BR></B><img src ="http://www.blogjava.net/jackybu/aggbug/1098.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackybu/" target="_blank">辰</a> 2005-02-12 23:23 <a href="http://www.blogjava.net/jackybu/articles/1098.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转帖]学java i/o库要掌握的三个关键知识点 </title><link>http://www.blogjava.net/jackybu/articles/1092.html</link><dc:creator>辰</dc:creator><author>辰</author><pubDate>Sat, 12 Feb 2005 15:15:00 GMT</pubDate><guid>http://www.blogjava.net/jackybu/articles/1092.html</guid><wfw:comment>http://www.blogjava.net/jackybu/comments/1092.html</wfw:comment><comments>http://www.blogjava.net/jackybu/articles/1092.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jackybu/comments/commentRss/1092.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jackybu/services/trackbacks/1092.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN style="FONT-FAMILY: 宋体">大家讨论<SPAN lang=EN-US>java i/o库很久了,</SPAN></SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: Arial"> Pale</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 宋体">Sting也刚发了&lt;&lt;初级 Java I/O 综述&gt;&gt;系列文章,但我估计还是有些读者会觉得java i/o库难以琢磨,所以也来凑凑热闹,说说我认为的学习java i/o库要掌握的三个关键知识点。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><B><SPAN style="FONT-FAMILY: 宋体">知识点一<SPAN lang=EN-US>: 四大等级结构<o:p></o:p></SPAN></SPAN></B></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US style="FONT-FAMILY: 宋体">java语言的i/o库提供了四大等级结构:InputStream,OutputStream,Reader,Writer四个系列的类。InputStream和OutputStream处理8位字节流数据, Reader和Writer处理16位的字符流数据。InputStream和Reader处理输入, OutputStream和Writer处理输出。大家一定要到</SPAN><SPAN lang=EN-US style="COLOR: #333333">J2SE</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文档中看看这四大</SPAN><SPAN style="FONT-FAMILY: 宋体">等级结构的类继承体系。<SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN style="FONT-FAMILY: 宋体">除了这四大系列类<SPAN lang=EN-US>,i/o库还提供了少数的辅助类,其中比较重要的是InputStreamReader和OutputStreamWriter。InputStreamReader把InputStream适配为Reader, OutputStreamWriter把OutputStream适配为Writer;这样就架起了字节流处理类和字符流处理类间的桥梁。<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN style="FONT-FAMILY: 宋体">您使用<SPAN lang=EN-US>i/o库时,只要按以上的规则,到相应的类体系中寻找您需要的类即可。<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><B><SPAN style="FONT-FAMILY: 宋体">知识点二<SPAN lang=EN-US>: 适配功能<o:p></o:p></SPAN></SPAN></B></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US style="FONT-FAMILY: 宋体">java i/o库中的继承不是普通的继承;它的继承模式分为两种,其一就是Adapter模式(具体分析请参见&lt;<JAVA与模式>&gt;一书) 。下面以InputStream类体系为例进行说明。<o:p></o:p></SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US style="FONT-FAMILY: 宋体">InputStream有7个直接子类:ByteArrayInputStream,FileInputStream,PipedInputStream,StringBufferInputStream,FilterInputStream,ObjectInputStream</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US>SequenceInputStream</SPAN><SPAN style="FONT-FAMILY: 宋体">。前四个采用了<SPAN lang=EN-US>Adapter模式,如FileInputStream部分代码如下:<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US>Public class FileInputStream extends InputStream</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US>{</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">??? </SPAN>/* File Descriptor - handle to the open file */</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">??? </SPAN>private FileDescriptor fd;</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">??? </SPAN>public FileInputStream(FileDescriptor fdObj)</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">?</SPAN>{</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">?? </SPAN><SPAN style="mso-spacerun: yes">? </SPAN>SecurityManager security = System.getSecurityManager();</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">?? </SPAN><SPAN style="mso-spacerun: yes">? </SPAN>if (fdObj == null) {</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">?? </SPAN><SPAN style="mso-spacerun: yes">??? </SPAN>throw new NullPointerException();</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">?? </SPAN><SPAN style="mso-spacerun: yes">? </SPAN>}</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">?? </SPAN><SPAN style="mso-spacerun: yes">? </SPAN>if (security != null) {</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">?? </SPAN><SPAN style="mso-spacerun: yes">??? </SPAN>security.checkRead(fdObj);</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">?? </SPAN><SPAN style="mso-spacerun: yes">? </SPAN>}</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">?? </SPAN><SPAN style="mso-spacerun: yes">??? </SPAN>fd = fdObj;</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt; mso-char-indent-count: 3.07; mso-char-indent-size: 10.5pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">?</SPAN>}</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt; mso-char-indent-count: 3.07; mso-char-indent-size: 10.5pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">?</SPAN>//</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="TEXT-INDENT: 27pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 27pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可见</SPAN><SPAN lang=EN-US>,FileInputStream</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">继承了</SPAN><SPAN lang=EN-US>InputStream,</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">组合了</SPAN><SPAN lang=EN-US>FileDescriptor,</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">采用的是对象</SPAN><SPAN lang=EN-US>Adapter</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模式</SPAN><SPAN style="FONT-FAMILY: 宋体">。我们学习<SPAN lang=EN-US>i/o库时,主要应该掌握这四个</SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象</SPAN><SPAN lang=EN-US>Adapter</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><SPAN lang=EN-US style="FONT-FAMILY: 宋体"> ByteArrayInputStream的</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">适配源是</SPAN><SPAN lang=EN-US>Byte</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数组</SPAN><SPAN lang=EN-US>, FileInputStream</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的适配源是</SPAN><SPAN lang=EN-US>File</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><SPAN lang=EN-US style="FONT-FAMILY: 宋体"> PipedInputStream的</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">适配源是</SPAN><SPAN lang=EN-US>PipedOutputStream</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><SPAN lang=EN-US style="FONT-FAMILY: 宋体"> StringBufferInputStream的适配源是String对象。其它三个系列类的学习方法与此相同。<o:p></o:p></SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><B><SPAN style="FONT-FAMILY: 宋体">知识点三<SPAN lang=EN-US>: Decorator功能<o:p></o:p></SPAN></SPAN></B></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US style="FONT-FAMILY: 宋体">InputStream的其它三个直接子类采用的是Decorator模式,&lt;<JAVA与模式>&gt;中描述得比较清楚,其实我们不用管它采用什么模式,看看代码就明白了。 FilterInputStream部分代码如下:<o:p></o:p></SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US>Public class FilterInputStream extends InputStream {</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">??? </SPAN>/**</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">???? </SPAN>* The input stream to be filtered. </SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">???? </SPAN>*/</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">??? </SPAN>protected InputStream in;</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">??? </SPAN>protected FilterInputStream(InputStream in) {</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">?? </SPAN><SPAN style="mso-spacerun: yes">???? </SPAN>this.in = in;</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">??? </SPAN>}</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">??? </SPAN>//</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="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US>}</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">?</SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">看清楚没有</SPAN><SPAN lang=EN-US>? FilterInputStream</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">继承了</SPAN><SPAN lang=EN-US>InputStream,</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">也引用了</SPAN><SPAN lang=EN-US>InputStream,</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><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这就是所谓的</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 宋体">Decorator模式。我们暂时可以不管为什么要用Decorator模式,但我们现在应该知道:因为</SPAN><SPAN lang=EN-US>InputStream</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><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">所以我们可以将其它子类作为参数来构造</SPAN><SPAN lang=EN-US>FilterInputStream</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><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这是我们开发时常用的功能</SPAN><SPAN lang=EN-US>,</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="TEXT-INDENT: 42.75pt; mso-char-indent-count: 4.07; mso-char-indent-size: 10.5pt"><SPAN lang=EN-US>{</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 42.75pt; mso-char-indent-count: 4.07; mso-char-indent-size: 10.5pt"><SPAN lang=EN-US>//</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="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">?? </SPAN>SecretKey key=null;<SPAN style="mso-spacerun: yes">?? </SPAN></SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">?? </SPAN>ObjectInputStream keyFile=new ObjectInputStream(</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">??????? </SPAN>new FileInputStream("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>\\</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对称密钥</SPAN><SPAN lang=EN-US>\\yhb.des"));</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">??? </SPAN>key=(SecretKey)keyFile.readObject();</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">??? </SPAN>keyFile.close();</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">?? </SPAN>}</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">?</SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">上面的代码中</SPAN><SPAN lang=EN-US>, ObjectInputStream</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">也是</SPAN><SPAN lang=EN-US>InputStream</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><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">也使用了</SPAN><SPAN lang=EN-US>Decorator</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><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不过</SPAN><SPAN lang=EN-US>,</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就算你不懂也不想懂</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 宋体">Decorator模式,只要记住</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">本文给出的</SPAN><SPAN lang=EN-US>FilterInputStream </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的两段代码即可</SPAN><SPAN style="FONT-FAMILY: 宋体">。<SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 32.25pt"><SPAN style="FONT-FAMILY: 宋体">掌握了以上三点<SPAN lang=EN-US>,相信我们已经能够很好的应用java i/o库。</SPAN></SPAN></P><img src ="http://www.blogjava.net/jackybu/aggbug/1092.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jackybu/" target="_blank">辰</a> 2005-02-12 23:15 <a href="http://www.blogjava.net/jackybu/articles/1092.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>