﻿<?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-oneJavaer-文章分类-Java</title><link>http://www.blogjava.net/onejavaer/category/46184.html</link><description>让我在热血沸腾中度此一生 让我在醇酒般的幻梦里醉沉！莫使我眼见这泥塑的肉身，终以空虚的躯壳毁于泥尘</description><language>zh-cn</language><lastBuildDate>Tue, 31 Aug 2010 16:11:32 GMT</lastBuildDate><pubDate>Tue, 31 Aug 2010 16:11:32 GMT</pubDate><ttl>60</ttl><item><title>全面文件操作java代码</title><link>http://www.blogjava.net/onejavaer/articles/102307.html</link><dc:creator>暗夜精灵</dc:creator><author>暗夜精灵</author><pubDate>Wed, 07 Mar 2007 01:09:00 GMT</pubDate><guid>http://www.blogjava.net/onejavaer/articles/102307.html</guid><wfw:comment>http://www.blogjava.net/onejavaer/comments/102307.html</wfw:comment><comments>http://www.blogjava.net/onejavaer/articles/102307.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/onejavaer/comments/commentRss/102307.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/onejavaer/services/trackbacks/102307.html</trackback:ping><description><![CDATA[		<div class="postbody">import java.io.BufferedReader;<br />import java.io.File;<br />import java.io.FileInputStream;<br />import java.io.FileOutputStream;<br />import java.io.FileWriter;<br />import java.io.IOException;<br />import java.io.InputStream;<br />import java.io.InputStreamReader;<br />import java.io.PrintWriter;<br />import java.util.StringTokenizer;<br />public class FileOperate {<br />&#160;&#160;&#160; private String message;<br />&#160;&#160;&#160; public FileOperate() {<br />&#160;&#160;&#160; } 
<p><font color="#338fcc">&#160;&#160;&#160; /**<br />&#160;&#160;&#160;&#160; * 读取文本文件内容<br />&#160;&#160;&#160;&#160; * @param filePathAndName 带有完整绝对路径的文件名<br />&#160;&#160;&#160;&#160; * @param encoding 文本文件打开的编码方式<br />&#160;&#160;&#160;&#160; * @return 返回文本文件的内容<br />&#160;&#160;&#160;&#160; */</font><br />&#160;&#160;&#160; public String readTxt(String filePathAndName,String encoding) throws IOException{<br />&#160;&#160;&#160; &#160;encoding = encoding.trim();<br />&#160;&#160;&#160; &#160;StringBuffer str = new StringBuffer("");<br />&#160;&#160;&#160; &#160;String st = "";<br />&#160;&#160;&#160; &#160;try{<br />&#160;&#160;&#160;&#160; &#160;FileInputStream fs = new FileInputStream(filePathAndName);<br />&#160;&#160;&#160;&#160; &#160;InputStreamReader isr;<br />&#160;&#160;&#160;&#160; &#160;if(encoding.equals("")){<br />&#160;&#160;&#160;&#160; &#160;&#160;isr = new InputStreamReader(fs);<br />&#160;&#160;&#160;&#160; &#160;}else{<br />&#160;&#160;&#160;&#160; &#160;&#160;isr = new InputStreamReader(fs,encoding);<br />&#160;&#160;&#160;&#160; &#160;}<br />&#160;&#160;&#160;&#160; &#160;BufferedReader br = new BufferedReader(isr);<br />&#160;&#160;&#160;&#160; &#160;try{<br />&#160;&#160;&#160;&#160; &#160;&#160;String data = "";<br />&#160;&#160;&#160;&#160; &#160;&#160;while((data = br.readLine())!=null){<br />&#160;&#160;&#160;&#160; &#160;&#160;&#160;&#160;str.append(data+" "); <br />&#160;&#160;&#160;&#160; &#160;&#160;}<br />&#160;&#160;&#160;&#160; &#160;}catch(Exception e){<br />&#160;&#160;&#160;&#160; &#160;&#160;str.append(e.toString());<br />&#160;&#160;&#160;&#160; &#160;}<br />&#160;&#160;&#160;&#160; &#160;st = str.toString();<br />&#160;&#160;&#160; &#160;}catch(IOException es){<br />&#160;&#160;&#160; &#160;&#160;st = "";<br />&#160;&#160;&#160; &#160;}<br />&#160;&#160;&#160; &#160;return st;&#160;&#160;&#160; &#160;<br />&#160;&#160;&#160; }</p><p><font color="#448cbb">&#160;&#160;&#160; /**<br />&#160;&#160;&#160;&#160; * 新建目录<br />&#160;&#160;&#160;&#160; * @param folderPath 目录<br />&#160;&#160;&#160;&#160; * @return 返回目录创建后的路径<br />&#160;&#160;&#160;&#160; */</font><br />&#160;&#160;&#160; public String createFolder(String folderPath) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; String txt = folderPath;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; try {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; java.io.File myFilePath = new java.io.File(txt);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; txt = folderPath;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (!myFilePath.exists()) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; myFilePath.mkdir();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; catch (Exception e) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; message = "创建目录操作出错";<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return txt;<br />&#160;&#160;&#160; }<br />&#160;&#160;&#160; <br /><font color="#3c8dc4">&#160;&#160;&#160; /**<br />&#160;&#160;&#160;&#160; * 多级目录创建<br />&#160;&#160;&#160;&#160; * @param folderPath 准备要在本级目录下创建新目录的目录路径 例如 c:myf<br />&#160;&#160;&#160;&#160; * @param paths 无限级目录参数，各级目录以单数线区分 例如 a|b|c<br />&#160;&#160;&#160;&#160; * @return 返回创建文件后的路径 例如 c:myfa&#x8;c<br />&#160;&#160;&#160;&#160; */</font><br />&#160;&#160;&#160; public String createFolders(String folderPath, String paths){<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; String txts = folderPath;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; try{<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; String txt;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; txts = folderPath;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; StringTokenizer st = new StringTokenizer(paths,"|");<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; for(int i=0; st.hasMoreTokens(); i++){<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; txt = st.nextToken().trim();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(txts.lastIndexOf("/")!=-1){ <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; txts = createFolder(txts+txt);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }else{<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; txts = createFolder(txts+txt+"/");&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160; }catch(Exception e){<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; message = "创建目录操作出错！";<br />&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return txts;<br />&#160;&#160;&#160; }</p><p>&#160;&#160;&#160; <br /><font color="#3c8dc4">&#160;&#160;&#160; /**<br />&#160;&#160;&#160;&#160; * 新建文件<br />&#160;&#160;&#160;&#160; * @param filePathAndName 文本文件完整绝对路径及文件名<br />&#160;&#160;&#160;&#160; * @param fileContent 文本文件内容<br />&#160;&#160;&#160;&#160; * @return<br />&#160;&#160;&#160;&#160; */</font><br />&#160;&#160;&#160; public void createFile(String filePathAndName, String fileContent) {<br />&#160;&#160;&#160; &#160;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; try {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; String filePath = filePathAndName;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; filePath = filePath.toString();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; File myFilePath = new File(filePath);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (!myFilePath.exists()) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; myFilePath.createNewFile();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FileWriter resultFile = new FileWriter(myFilePath);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; PrintWriter myFile = new PrintWriter(resultFile);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; String strContent = fileContent;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; myFile.println(strContent);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; myFile.close();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; resultFile.close();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; catch (Exception e) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; message = "创建文件操作出错";<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160; }</p><p><br /><font color="#3c8dc4">&#160;&#160;&#160; /**<br />&#160;&#160;&#160;&#160; * 有编码方式的文件创建<br />&#160;&#160;&#160;&#160; * @param filePathAndName 文本文件完整绝对路径及文件名<br />&#160;&#160;&#160;&#160; * @param fileContent 文本文件内容<br />&#160;&#160;&#160;&#160; * @param encoding 编码方式 例如 GBK 或者 UTF-8<br />&#160;&#160;&#160;&#160; * @return<br />&#160;&#160;&#160;&#160; */</font><br />&#160;&#160;&#160; public void createFile(String filePathAndName, String fileContent, String encoding) {<br />&#160;&#160;&#160; &#160;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; try {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; String filePath = filePathAndName;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; filePath = filePath.toString();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; File myFilePath = new File(filePath);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (!myFilePath.exists()) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; myFilePath.createNewFile();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; PrintWriter myFile = new PrintWriter(myFilePath,encoding);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; String strContent = fileContent;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; myFile.println(strContent);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; myFile.close();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; catch (Exception e) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; message = "创建文件操作出错";<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160; } </p><p><br /><font color="#338fcc">&#160;&#160;&#160; /**<br />&#160;&#160;&#160;&#160; * 删除文件<br />&#160;&#160;&#160;&#160; * @param filePathAndName 文本文件完整绝对路径及文件名<br />&#160;&#160;&#160;&#160; * @return Boolean 成功删除返回true遭遇异常返回false<br />&#160;&#160;&#160;&#160; */</font><br />&#160;&#160;&#160; public boolean delFile(String filePathAndName) {<br />&#160;&#160;&#160; &#160;boolean bea = false;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; try {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; String filePath = filePathAndName;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; File myDelFile = new File(filePath);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(myDelFile.exists()){<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;myDelFile.delete();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;bea = true;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }else{<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;bea = false;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;message = (filePathAndName+"<br />删除文件操作出错");<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; catch (Exception e) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; message = e.toString();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return bea;<br />&#160;&#160;&#160; }<br />&#160;&#160;&#160; </p><p><br /><font color="#3c8dc4">&#160;&#160;&#160; /**<br />&#160;&#160;&#160;&#160; * 删除文件夹<br />&#160;&#160;&#160;&#160; * @param folderPath 文件夹完整绝对路径<br />&#160;&#160;&#160;&#160; * @return<br />&#160;&#160;&#160;&#160; */</font><br />&#160;&#160;&#160; public void delFolder(String folderPath) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; try {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; delAllFile(folderPath); //删除完里面所有内容<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; String filePath = folderPath;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; filePath = filePath.toString();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; java.io.File myFilePath = new java.io.File(filePath);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; myFilePath.delete(); //删除空文件夹<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; catch (Exception e) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; message = ("删除文件夹操作出错");<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160; }<br />&#160;&#160;&#160; <br />&#160;&#160;&#160; <br /><font color="#3c8dc4">&#160;&#160;&#160; /**<br />&#160;&#160;&#160;&#160; * 删除指定文件夹下所有文件<br />&#160;&#160;&#160;&#160; * @param path 文件夹完整绝对路径<br />&#160;&#160;&#160;&#160; * @return<br />&#160;&#160;&#160;&#160; * @return<br />&#160;&#160;&#160;&#160; */</font><br />&#160;&#160;&#160; public boolean delAllFile(String path) {<br />&#160;&#160;&#160; &#160;boolean bea = false;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; File file = new File(path);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (!file.exists()) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return bea;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (!file.isDirectory()) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return bea;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; String[] tempList = file.list();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; File temp = null;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; for (int i = 0; i &lt; tempList.length; i++) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (path.endsWith(File.separator)) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; temp = new File(path + tempList[i]);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }else{<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; temp = new File(path + File.separator + tempList[i]);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (temp.isFile()) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; temp.delete();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (temp.isDirectory()) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; delAllFile(path+"/"+ tempList[i]);//先删除文件夹里面的文件<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; delFolder(path+"/"+ tempList[i]);//再删除空文件夹<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; bea = true;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return bea;<br />&#160;&#160;&#160; }</p><p><br /><font color="#448cbb">&#160;&#160;&#160; /**<br />&#160;&#160;&#160;&#160; * 复制单个文件<br />&#160;&#160;&#160;&#160; * @param oldPathFile 准备复制的文件源<br />&#160;&#160;&#160;&#160; * @param newPathFile 拷贝到新绝对路径带文件名<br />&#160;&#160;&#160;&#160; * @return<br />&#160;&#160;&#160;&#160; */</font><br />&#160;&#160;&#160; public void copyFile(String oldPathFile, String newPathFile) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; try {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; int bytesum = 0;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; int byteread = 0;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; File oldfile = new File(oldPathFile);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (oldfile.exists()) { //文件存在时<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; InputStream inStream = new FileInputStream(oldPathFile); //读入原文件<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FileOutputStream fs = new FileOutputStream(newPathFile);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; byte[] buffer = new byte[1444];<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; while((byteread = inStream.read(buffer)) != -1){<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; bytesum += byteread; //字节数 文件大小<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println(bytesum);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; fs.write(buffer, 0, byteread);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; inStream.close();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }catch (Exception e) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; message = ("复制单个文件操作出错");<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160; }<br />&#160;&#160;&#160; </p><p><font color="#3c8dc4">&#160;&#160;&#160; /**<br />&#160;&#160;&#160;&#160; * 复制整个文件夹的内容<br />&#160;&#160;&#160;&#160; * @param oldPath 准备拷贝的目录<br />&#160;&#160;&#160;&#160; * @param newPath 指定绝对路径的新目录<br />&#160;&#160;&#160;&#160; * @return<br />&#160;&#160;&#160;&#160; */</font><br />&#160;&#160;&#160; public void copyFolder(String oldPath, String newPath) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; try {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; new File(newPath).mkdirs(); //如果文件夹不存在 则建立新文件夹<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; File a=new File(oldPath);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; String[] file=a.list();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; File temp=null;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; for (int i = 0; i &lt; file.length; i++) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(oldPath.endsWith(File.separator)){<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; temp=new File(oldPath+file[i]);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }else{<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; temp=new File(oldPath+File.separator+file[i]);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(temp.isFile()){<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FileInputStream input = new FileInputStream(temp);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FileOutputStream output = new FileOutputStream(newPath + "/" +<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (temp.getName()).toString());<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; byte[] b = new byte[1024 * 5];<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; int len;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; while ((len = input.read(b)) != -1) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; output.write(b, 0, len);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; output.flush();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; output.close();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; input.close();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(temp.isDirectory()){//如果是子文件夹<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; copyFolder(oldPath+"/"+file[i],newPath+"/"+file[i]);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }catch (Exception e) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; message = "复制整个文件夹内容操作出错";<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160; }</p><p><br /><font color="#3c8dc4">&#160;&#160;&#160; /**<br />&#160;&#160;&#160;&#160; * 移动文件<br />&#160;&#160;&#160;&#160; * @param oldPath<br />&#160;&#160;&#160;&#160; * @param newPath<br />&#160;&#160;&#160;&#160; * @return<br />&#160;&#160;&#160;&#160; */</font><br />&#160;&#160;&#160; public void moveFile(String oldPath, String newPath) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; copyFile(oldPath, newPath);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; delFile(oldPath);<br />&#160;&#160;&#160; }<br />&#160;&#160;&#160; </p><p><font color="#3c8dc4">&#160;&#160;&#160; /**<br />&#160;&#160;&#160;&#160; * 移动目录<br />&#160;&#160;&#160;&#160; * @param oldPath<br />&#160;&#160;&#160;&#160; * @param newPath<br />&#160;&#160;&#160;&#160; * @return<br />&#160;&#160;&#160;&#160; */</font><br />&#160;&#160;&#160; public void moveFolder(String oldPath, String newPath) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; copyFolder(oldPath, newPath);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; delFolder(oldPath);<br />&#160;&#160;&#160; }<br />&#160;&#160;&#160; public String getMessage(){<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return this.message;<br />&#160;&#160;&#160; }<br />}</p></div>
 <img src ="http://www.blogjava.net/onejavaer/aggbug/102307.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/onejavaer/" target="_blank">暗夜精灵</a> 2007-03-07 09:09 <a href="http://www.blogjava.net/onejavaer/articles/102307.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA语言的反射和内省</title><link>http://www.blogjava.net/onejavaer/articles/101998.html</link><dc:creator>暗夜精灵</dc:creator><author>暗夜精灵</author><pubDate>Mon, 05 Mar 2007 13:41:00 GMT</pubDate><guid>http://www.blogjava.net/onejavaer/articles/101998.html</guid><wfw:comment>http://www.blogjava.net/onejavaer/comments/101998.html</wfw:comment><comments>http://www.blogjava.net/onejavaer/articles/101998.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/onejavaer/comments/commentRss/101998.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/onejavaer/services/trackbacks/101998.html</trackback:ping><description><![CDATA[		<div class="postText">
				<p class="MsoNormal" style="TEXT-INDENT: 21pt">
						<span style="FONT-FAMILY: 宋体">很多朋友在深入的接触</span>
						<span lang="EN-US">JAVA</span>
						<span style="FONT-FAMILY: 宋体">语言后就会发现这样两个词：反射</span>
						<span lang="EN-US">(Reflection)</span>
						<span style="FONT-FAMILY: 宋体">和内省</span>
						<span lang="EN-US">(Introspector)</span>
						<span style="FONT-FAMILY: 宋体">，经常搞不清楚这到底是怎么回事，在什么场合下应用以及如何使用？今天把这二者放在一起介绍，因为它们二者是相辅相成的。</span>
				</p>
				<p class="MsoNormal">
						<span style="FONT-FAMILY: 宋体">反射</span>
				</p>
				<p class="MsoNormal">
						<span lang="EN-US">
								<?xml:namespace prefix = o /?>
								<o:p>
								</o:p>
						</span>
				</p>
				<p class="MsoNormal" style="TEXT-INDENT: 21pt">
						<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>
				</p>
				<p class="MsoNormal">
						<span style="FONT-FAMILY: 宋体">还是写两个例子让大家更直观的了解反射的使用方法：</span>
				</p>
				<p class="MsoNormal">
						<span lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</p>
				<table style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse" cellspacing="0" cellpadding="0" border="1">
						<tbody>
								<tr>
										<td style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 426.1pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid" valign="top" width="568">
												<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
														<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,127,95); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">//</span>
														<span style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,127,95); FONT-FAMILY: 宋体; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">通过类名来构造一个类的实例<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">Class cls_str = Class.forName(</span>
														<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: rgb(42,0,255); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">"java.lang.String"</span>
														<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">);<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,127,95); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">//</span>
														<span style="FONT-SIZE: 10pt; COLOR: rgb(63,127,95); FONT-FAMILY: 宋体">上面这句很眼熟，因为使用过</span>
														<span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: rgb(63,127,95); FONT-FAMILY: 'Courier New'">JDBC</span>
														<span style="FONT-SIZE: 10pt; COLOR: rgb(63,127,95); FONT-FAMILY: 宋体">访问数据库的人都用过</span>
														<span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: rgb(63,127,95); FONT-FAMILY: Wingdings">
																<span>J<br /></span>
														</span>
														<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">Object str = cls_str.newInstance();<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,127,95); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">//</span>
														<span style="FONT-SIZE: 10pt; COLOR: rgb(63,127,95); FONT-FAMILY: 宋体">相当于</span>
														<span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: rgb(63,127,95); FONT-FAMILY: 'Courier New'">String str = new String();</span>
												</p>
										</td>
								</tr>
						</tbody>
				</table>
				<p class="MsoNormal">
						<span lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</p>
				<table style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse" cellspacing="0" cellpadding="0" border="1">
						<tbody>
								<tr>
										<td style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 426.1pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid" valign="top" width="568">
												<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
														<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,127,95); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">//</span>
														<span style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,127,95); FONT-FAMILY: 宋体; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">通过方法名来调用一个方法<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">String methodName = </span>
														<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: rgb(42,0,255); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">"length"</span>
														<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">;<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">Method m = cls_str.getMethod(methodName,</span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">null</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">);<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">System.out.println(</span>
														<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: rgb(42,0,255); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">"length is "</span>
														<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">+ m.invoke(str,</span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">null</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">));<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,127,95); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">//</span>
														<span style="FONT-SIZE: 10pt; COLOR: rgb(63,127,95); FONT-FAMILY: 宋体">相当于</span>
														<span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: rgb(63,127,95); FONT-FAMILY: 'Courier New'">System.out.println(str.length());</span>
												</p>
										</td>
								</tr>
						</tbody>
				</table>
				<p class="MsoNormal">
						<span lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</p>
				<p class="MsoNormal" style="TEXT-INDENT: 21pt">
						<span style="FONT-FAMILY: 宋体">上面的两个例子是比较常用方法。看到上面的例子就有人要发问了：为什么要这么麻烦呢？本来一条语句就完成的事情干吗要整这么复杂？没错，在上面的例子中确实没有必要这么麻烦。不过你想像这样一个应用程序，它支持动态的功能扩展，也就是说程序不重新启动但是可以自动加载新的功能，这个功能使用一个具体类来表示。首先我们必须为这些功能定义一个接口类，然后我们要求所有扩展的功能类必须实现我指定的接口，这个规定了应用程序和可扩展功能之间的接口规则，但是怎么动态加载呢？我们必须让应用程序知道要扩展的功能类的类名，比如是</span>
						<span lang="EN-US">test.Func1</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>
				</p>
				<p class="MsoNormal">
						<span lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</p>
				<p class="MsoNormal">
						<span lang="EN-US">
								<span>&#160;&#160;&#160;&#160;&#160;&#160; </span>
						</span>
						<span style="FONT-FAMILY: 宋体">关于方法的反射建议大家看我的另外一篇文章《</span>
						<span style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 宋体; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">利用</span>
						<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">Turbine</span>
						<span style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 宋体; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">的事件映射来扩展</span>
						<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">Struts</span>
						<span style="FONT-SIZE: 10pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 宋体; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">的功能</span>
						<span style="FONT-FAMILY: 宋体">》，地址是：</span>
						<span lang="EN-US">
								<a href="http://www.javayou.com/article/CSDN/extend_struts.html">http://www.javayou.com/article/CSDN/extend_struts.html</a>
						</span>
						<span style="FONT-FAMILY: 宋体">。这篇文章详细介绍了如果通过反射来扩展</span>
						<span lang="EN-US">Struts</span>
						<span style="FONT-FAMILY: 宋体">框架的功能。</span>
				</p>
				<p class="MsoNormal">
						<span lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</p>
				<p class="MsoNormal">
						<span style="FONT-FAMILY: 宋体">内省</span>
				</p>
				<p class="MsoNormal">
						<span lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</p>
				<p class="MsoNormal" style="TEXT-INDENT: 21pt">
						<span style="FONT-FAMILY: 宋体">内省是</span>
						<span lang="EN-US">Java</span>
						<span style="FONT-FAMILY: 宋体">语言对</span>
						<span lang="EN-US">Bean</span>
						<span style="FONT-FAMILY: 宋体">类属性、事件的一种缺省处理方法。例如类</span>
						<span lang="EN-US">A</span>
						<span style="FONT-FAMILY: 宋体">中有属性</span>
						<span lang="EN-US">name,</span>
						<span style="FONT-FAMILY: 宋体">那我们可以通过</span>
						<span lang="EN-US">getName,setName</span>
						<span style="FONT-FAMILY: 宋体">来得到其值或者设置新的值。通过</span>
						<span lang="EN-US">getName/setName</span>
						<span style="FONT-FAMILY: 宋体">来访问</span>
						<span lang="EN-US">name</span>
						<span style="FONT-FAMILY: 宋体">属性，这就是默认的规则。</span>
						<span lang="EN-US">Java</span>
						<span style="FONT-FAMILY: 宋体">中提供了一套</span>
						<span lang="EN-US">API</span>
						<span style="FONT-FAMILY: 宋体">用来访问某个属性的</span>
						<span lang="EN-US">getter/setter</span>
						<span style="FONT-FAMILY: 宋体">方法，通过这些</span>
						<span lang="EN-US">API</span>
						<span style="FONT-FAMILY: 宋体">可以使你不需要了解这个规则（但你最好还是要搞清楚），这些</span>
						<span lang="EN-US">API</span>
						<span style="FONT-FAMILY: 宋体">存放于包</span>
						<span lang="EN-US">java.beans</span>
						<span style="FONT-FAMILY: 宋体">中。</span>
				</p>
				<p class="MsoNormal">
						<span lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</p>
				<p class="MsoNormal" style="TEXT-INDENT: 21pt">
						<span style="FONT-FAMILY: 宋体">一般的做法是通过类</span>
						<span lang="EN-US">Introspector</span>
						<span style="FONT-FAMILY: 宋体">来获取某个对象的</span>
						<span lang="EN-US">BeanInfo</span>
						<span style="FONT-FAMILY: 宋体">信息，然后通过</span>
						<span lang="EN-US">BeanInfo</span>
						<span style="FONT-FAMILY: 宋体">来获取属性的描述器（</span>
						<span lang="EN-US">PropertyDescriptor</span>
						<span style="FONT-FAMILY: 宋体">），通过这个属性描述器就可以获取某个属性对应的</span>
						<span lang="EN-US">getter/setter</span>
						<span style="FONT-FAMILY: 宋体">方法，然后我们就可以通过反射机制来调用这些方法。下面我们来看一个例子，这个例子把某个对象的所有属性名称和值都打印出来：</span>
				</p>
				<p class="MsoNormal" style="TEXT-INDENT: 21pt">
						<span lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</p>
				<table style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse" cellspacing="0" cellpadding="0" border="1">
						<tbody>
								<tr>
										<td style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 426.1pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid" valign="top" width="568">
												<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,127,95); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">/*&#160;<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,127,95); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;</span>* Created on 2004-6-29<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,127,95); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;</span>*/</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">
																<o:p>
																</o:p>
														</span>
												</p>
												<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">package</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">demo;</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">
																<o:p>
																</o:p>
														</span>
												</p>
												<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
														<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">
																<o:p>
																</o:p>
														</span>
												</p>
												<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">import</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">java.beans.BeanInfo;<br /></span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">import</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">java.beans.Introspector;<br /></span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">import</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">java.beans.PropertyDescriptor;</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">
																<o:p>
																</o:p>
														</span>
												</p>
												<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
														<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">
																<o:p>
																</o:p>
														</span>
												</p>
												<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,95,191); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">/**<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;</span>
														</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,95,191); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">*</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
														</span>
														<span style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,95,191); FONT-FAMILY: 宋体; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">内省演示例子<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;</span>
														</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,95,191); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">*</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
														</span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,159,191); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">@author</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
														</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,95,191); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">liudong<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;</span>
														</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,95,191); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">*/</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">
																<o:p>
																</o:p>
														</span>
												</p>
												<p class="MsoNormal" dir="ltr" style="MARGIN-RIGHT: 0px; TEXT-ALIGN: left" align="left">
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">public</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
														</span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">class</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">IntrospectorDemo {<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;&#160;&#160; </span>String name;<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;&#160;&#160; </span>
														</span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">public</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
														</span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">static</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
														</span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">void</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">main(String[] args) </span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">throws</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">Exception{<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">&#160;&#160;&#160;&#160;&#160;&#160;&#160; IntrospectorDemo demo = </span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">new</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">IntrospectorDemo();<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">&#160;&#160;&#160;&#160;&#160;&#160;&#160; demo.setName(</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(42,0,255); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">"Winter Lau"</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">);</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>
														</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">
																<o:p>
																</o:p>
														</span>
												</p>
												<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>
														</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,127,95); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">//</span>
														<span style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,127,95); FONT-FAMILY: 宋体; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">如果不想把父类的属性也列出来的话，<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>
														</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,127,95); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">//</span>
														<span style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,127,95); FONT-FAMILY: 宋体; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">那</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,127,95); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">getBeanInfo</span>
														<span style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(63,127,95); FONT-FAMILY: 宋体; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">的第二个参数填写父类的信息<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>BeanInfo bi = Introspector.getBeanInfo(demo.getClass(),</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">Object.</span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">class</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">);<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>PropertyDescriptor[] props = bi.getPropertyDescriptors();<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>
														</span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">for</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">(</span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">int</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">i=0;i&lt;props.length;i++){<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>System.out.println(props[i].getName()+</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(42,0,255); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">"="</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">+<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>props[i].getReadMethod().invoke(demo,</span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">null</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">));<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>}</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">
																<o:p>
																</o:p>
														</span>
												</p>
												<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;&#160;&#160; </span>}</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;&#160;&#160; </span>
														</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">
																<o:p>
																</o:p>
														</span>
												</p>
												<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;&#160;&#160; </span>
														</span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">public</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">String getName() {<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>
														</span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">return</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">name;<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;&#160;&#160; </span>}</span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">
																<o:p>
																</o:p>
														</span>
												</p>
												<p class="MsoNormal" style="TEXT-ALIGN: left" align="left">
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;&#160;&#160; </span>
														</span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">public</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
														</span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">void</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">setName(String name) {<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>
														</span>
														<strong>
																<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: rgb(127,0,85); FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">this</span>
														</strong>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">.name = name;<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">
																<span>&#160;&#160;&#160; </span>}<br /></span>
														<span lang="EN-US" style="FONT-SIZE: 9pt; BACKGROUND: white 0% 50%; COLOR: black; FONT-FAMILY: 'Courier New'; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">}</span>
												</p>
										</td>
								</tr>
						</tbody>
				</table>
				<p class="MsoNormal">
						<span lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</p>
				<p class="MsoNormal" style="TEXT-INDENT: 21pt">
						<span lang="EN-US">Web</span>
						<span style="FONT-FAMILY: 宋体">开发框架</span>
						<span lang="EN-US">Struts</span>
						<span style="FONT-FAMILY: 宋体">中的</span>
						<span lang="EN-US">FormBean</span>
						<span style="FONT-FAMILY: 宋体">就是通过内省机制来将表单中的数据映射到类的属性上，因此要求</span>
						<span lang="EN-US">FormBean</span>
						<span style="FONT-FAMILY: 宋体">的每个属性要有</span>
						<span lang="EN-US">getter/setter</span>
						<span style="FONT-FAMILY: 宋体">方法。但也并不总是这样，什么意思呢？就是说对一个</span>
						<span lang="EN-US">Bean</span>
						<span style="FONT-FAMILY: 宋体">类来讲，我可以没有属性，但是只要有</span>
						<span lang="EN-US">getter/setter</span>
						<span style="FONT-FAMILY: 宋体">方法中的其中一个，那么</span>
						<span lang="EN-US">Java</span>
						<span style="FONT-FAMILY: 宋体">的内省机制就会认为存在一个属性，比如类中有方法</span>
						<span lang="EN-US">setMobile</span>
						<span style="FONT-FAMILY: 宋体">，那么就认为存在一个</span>
						<span lang="EN-US">mobile</span>
						<span style="FONT-FAMILY: 宋体">的属性，这样可以方便我们把</span>
						<span lang="EN-US">Bean</span>
						<span style="FONT-FAMILY: 宋体">类通过一个接口来定义而不用去关心具体实现，不用去关心 </span>
						<span lang="EN-US">Bean</span>
						<span style="FONT-FAMILY: 宋体">中数据的存储。比如我们可以把所有的</span>
						<span lang="EN-US">getter/setter</span>
						<span style="FONT-FAMILY: 宋体">方法放到接口里定义，但是真正数据的存取则是在具体类中去实现，这样可提高系统的扩展性。</span>
				</p>
				<p class="MsoNormal">
						<span lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</p>
				<p class="MsoNormal">
						<span style="FONT-FAMILY: 宋体">总结</span>
				</p>
				<p class="MsoNormal">
						<span lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</p>
				<p class="MsoNormal" style="TEXT-INDENT: 21pt">
						<span style="FONT-FAMILY: 宋体">将</span>
						<span lang="EN-US">Java</span>
						<span style="FONT-FAMILY: 宋体">的反射以及内省应用到程序设计中去可以大大的提供程序的智能化和可扩展性。有很多项目都是采取这两种技术来实现其核心功能，例如我们前面提到的</span>
						<span lang="EN-US">Struts</span>
						<span style="FONT-FAMILY: 宋体">，还有用于处理</span>
						<span lang="EN-US">XML</span>
						<span style="FONT-FAMILY: 宋体">文件的</span>
						<span lang="EN-US">Digester</span>
						<span style="FONT-FAMILY: 宋体">项目，其实应该说几乎所有的项目都或多或少的采用这两种技术。在实际应用过程中二者要相互结合方能发挥真正的智能化以及高度可扩展性。</span>
				</p>
		</div>
 <img src ="http://www.blogjava.net/onejavaer/aggbug/101998.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/onejavaer/" target="_blank">暗夜精灵</a> 2007-03-05 21:41 <a href="http://www.blogjava.net/onejavaer/articles/101998.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字符串匹配</title><link>http://www.blogjava.net/onejavaer/articles/101992.html</link><dc:creator>暗夜精灵</dc:creator><author>暗夜精灵</author><pubDate>Mon, 05 Mar 2007 13:25:00 GMT</pubDate><guid>http://www.blogjava.net/onejavaer/articles/101992.html</guid><wfw:comment>http://www.blogjava.net/onejavaer/comments/101992.html</wfw:comment><comments>http://www.blogjava.net/onejavaer/articles/101992.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/onejavaer/comments/commentRss/101992.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/onejavaer/services/trackbacks/101992.html</trackback:ping><description><![CDATA[		<h1>1 术语定义</h1>
		<p>在字符串匹配问题中，我们期待察看串T中是否含有串P。<br />其中串T被称为目标串，串S被称为模式串。</p>
		<h1>2 朴素匹配算法</h1>
		<p>进行字符串匹配，最简单的一个想法是：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img id="Codehighlighter1_25_607_Open_Image" onclick="this.style.display='none'; Codehighlighter1_25_607_Open_Text.style.display='none'; Codehighlighter1_25_607_Closed_Image.style.display='inline'; Codehighlighter1_25_607_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
				<img id="Codehighlighter1_25_607_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_25_607_Closed_Text.style.display='none'; Codehighlighter1_25_607_Open_Image.style.display='inline'; Codehighlighter1_25_607_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />
				<span style="COLOR: #0000ff">public</span>
				<span style="COLOR: #000000">&#160;</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000">&#160;SimpleMatch&#160;</span>
				<span id="Codehighlighter1_25_607_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.blogjava.net/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_25_607_Open_Text">
						<span style="COLOR: #000000">{<br /><img id="Codehighlighter1_81_424_Open_Image" onclick="this.style.display='none'; Codehighlighter1_81_424_Open_Text.style.display='none'; Codehighlighter1_81_424_Closed_Image.style.display='inline'; Codehighlighter1_81_424_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_81_424_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_81_424_Closed_Text.style.display='none'; Codehighlighter1_81_424_Open_Image.style.display='inline'; Codehighlighter1_81_424_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&#160;&#160;</span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000">&#160;</span>
						<span style="COLOR: #0000ff">int</span>
						<span style="COLOR: #000000">&#160;StringMatch(String&#160;target,String&#160;patten)&#160;</span>
						<span id="Codehighlighter1_81_424_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.blogjava.net/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_81_424_Open_Text">
								<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;</span>
								<span style="COLOR: #0000ff">int</span>
								<span style="COLOR: #000000">&#160;tl&#160;</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">&#160;target.length();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;</span>
								<span style="COLOR: #0000ff">int</span>
								<span style="COLOR: #000000">&#160;pl&#160;</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">&#160;patten.length();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;</span>
								<span style="COLOR: #0000ff">int</span>
								<span style="COLOR: #000000">&#160;i&#160;</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">&#160;</span>
								<span style="COLOR: #000000">0</span>
								<span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;</span>
								<span style="COLOR: #0000ff">int</span>
								<span style="COLOR: #000000">&#160;j&#160;</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">&#160;</span>
								<span style="COLOR: #000000">0</span>
								<span style="COLOR: #000000">;<br /><img id="Codehighlighter1_216_365_Open_Image" onclick="this.style.display='none'; Codehighlighter1_216_365_Open_Text.style.display='none'; Codehighlighter1_216_365_Closed_Image.style.display='inline'; Codehighlighter1_216_365_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_216_365_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_216_365_Closed_Text.style.display='none'; Codehighlighter1_216_365_Open_Image.style.display='inline'; Codehighlighter1_216_365_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;</span>
								<span style="COLOR: #0000ff">while</span>
								<span style="COLOR: #000000">(i&#160;</span>
								<span style="COLOR: #000000">&lt;</span>
								<span style="COLOR: #000000">&#160;tl&#160;</span>
								<span style="COLOR: #000000">-</span>
								<span style="COLOR: #000000">&#160;pl&#160;</span>
								<span style="COLOR: #000000">&amp;&amp;</span>
								<span style="COLOR: #000000">&#160;j&#160;</span>
								<span style="COLOR: #000000">&lt;</span>
								<span style="COLOR: #000000">&#160;pl)&#160;</span>
								<span id="Codehighlighter1_216_365_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
										<img src="http://www.blogjava.net/images/dot.gif" />
								</span>
								<span id="Codehighlighter1_216_365_Open_Text">
										<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span>
										<span style="COLOR: #0000ff">if</span>
										<span style="COLOR: #000000">(patten.charAt(j)&#160;</span>
										<span style="COLOR: #000000">==</span>
										<span style="COLOR: #000000">&#160;target.charAt(i</span>
										<span style="COLOR: #000000">+</span>
										<span style="COLOR: #000000">j))<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;j</span>
										<span style="COLOR: #000000">++</span>
										<span style="COLOR: #000000">;<br /><img id="Codehighlighter1_305_357_Open_Image" onclick="this.style.display='none'; Codehighlighter1_305_357_Open_Text.style.display='none'; Codehighlighter1_305_357_Closed_Image.style.display='inline'; Codehighlighter1_305_357_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_305_357_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_305_357_Closed_Text.style.display='none'; Codehighlighter1_305_357_Open_Image.style.display='inline'; Codehighlighter1_305_357_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span>
										<span style="COLOR: #0000ff">else</span>
										<span style="COLOR: #000000">&#160;</span>
										<span id="Codehighlighter1_305_357_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
												<img src="http://www.blogjava.net/images/dot.gif" />
										</span>
										<span id="Codehighlighter1_305_357_Open_Text">
												<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;j&#160;</span>
												<span style="COLOR: #000000">=</span>
												<span style="COLOR: #000000">&#160;</span>
												<span style="COLOR: #000000">0</span>
												<span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;i</span>
												<span style="COLOR: #000000">++</span>
												<span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}</span>
										</span>
										<span style="COLOR: #000000">
												<br />
												<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;}</span>
								</span>
								<span style="COLOR: #000000">
										<br />
										<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;</span>
								<span style="COLOR: #0000ff">if</span>
								<span style="COLOR: #000000">(j&#160;</span>
								<span style="COLOR: #000000">==</span>
								<span style="COLOR: #000000">&#160;pl)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span>
								<span style="COLOR: #0000ff">return</span>
								<span style="COLOR: #000000">&#160;i;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;</span>
								<span style="COLOR: #0000ff">return</span>
								<span style="COLOR: #000000">&#160;</span>
								<span style="COLOR: #000000">-</span>
								<span style="COLOR: #000000">1</span>
								<span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&#160;&#160;}</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;<br /><img id="Codehighlighter1_469_605_Open_Image" onclick="this.style.display='none'; Codehighlighter1_469_605_Open_Text.style.display='none'; Codehighlighter1_469_605_Closed_Image.style.display='inline'; Codehighlighter1_469_605_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_469_605_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_469_605_Closed_Text.style.display='none'; Codehighlighter1_469_605_Open_Image.style.display='inline'; Codehighlighter1_469_605_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&#160;&#160;</span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000">&#160;</span>
						<span style="COLOR: #0000ff">static</span>
						<span style="COLOR: #000000">&#160;</span>
						<span style="COLOR: #0000ff">void</span>
						<span style="COLOR: #000000">&#160;main(String[]&#160;args)</span>
						<span id="Codehighlighter1_469_605_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.blogjava.net/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_469_605_Open_Text">
								<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;String&#160;t&#160;</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">&#160;</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">123456789</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;String&#160;p&#160;</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">&#160;</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">456</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;SimpleMatch&#160;sm&#160;</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">&#160;</span>
								<span style="COLOR: #0000ff">new</span>
								<span style="COLOR: #000000">&#160;SimpleMatch();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;System.out.println(sm.StringMatch(t,&#160;p));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&#160;&#160;}</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
		</div>
		<p>可以看见，这个算法（假定m&gt;&gt;n）的复杂度是O(mn)，其中m是T的长度，n是P的长度。这种算法的缺陷是匹配过程中带有回溯——准确地说是T串存在回溯，也就是当匹配不成功的时候，之前进行的匹配完全变为无用功，所有的比较需要重新开始。</p>
		<h1>3 KMP算法</h1>
		<p>KMP算法是D.E.Knuth、J.H.Morris和V.R.Pratt提出的无回溯的字符串匹配算法，算法的核心思想就是设法在匹配失败的时候，尽量利用之前的匹配结果，消除T串的回溯问题。那么如何消除回溯呢？请看下面的例子：</p>
		<p>假设P=abacd，如果T=abax...，当从头开始匹配到字符c时，若c=x，显然，匹配过程继续；当c&#8800;x时，按照朴素的匹配算法，T串会发生回溯，之后T串会从第2个字符b开始重新匹配，而不是从匹配失败的字符x开始继续。但是显然，对于上述的匹配过程，T串不需要从b开始重新匹配，它只需要从x开始和P的b字符继续匹配即可。如下：<br />匹配过程：<br />P=abacd<br />T=abax....<br />&#160;&#160;&#160;&#160; ^----比较到此处时发生匹配失败<br />朴素匹配算法：<br />P= abacd<br />T=abax...<br />&#160;&#160; ^----回溯到b，重新开始和P的匹配<br />KMP算法：<br />P=&#160; abacd<br />T=abax...<br />&#160;&#160;&#160;&#160; ^----T串不回溯，从x处继续匹配</p>
		<p>现在的问题是，按照KMP算法，匹配失败的时候，P串需要重新调整位置，但是调整的依据是什么？Knuth等人发现，P调整位置的依据和P的构造有关，和T无关。具体来说，定义失效函数：f(j)=k，其中0&lt;=k&lt;=j，且k是使得p<sub>0</sub>p<sub>1</sub>...p<sub>k-1</sub> = p<sub>j-k+1</sub>p<sub>j-k+2</sub>...p<sub>j</sub>成立的最大整数。建立失效函数的算法如下：<br />public void Build() {<br />&#160;if(pattern == null)<br />&#160;&#160;throw new Exception("KMP Exception : null pattern");<br />&#160;array = new int[pattern.Length];<br />&#160;int i = 0, s = pattern.Length;<br />&#160;if(s &gt; 1)<br />&#160;&#160;array[0] = 0;<br />&#160;for(i = 1; i &lt; s; i++) {<br />&#160;&#160;if(pattern[i] == pattern[array[i - 1]])<br />&#160;&#160;&#160;array[i] = array[i - 1] + 1;<br />&#160;&#160;else<br />&#160;&#160;&#160;array[i] = 0;<br />&#160;}<br />}</p>
		<p>匹配过程如下：<br />public int Match(String target, int start) {<br />&#160;if(array == null || pattern == null || target == null)<br />&#160;&#160;return -1;<br />&#160;int target_index = start;<br />&#160;int pattern_index = 0;<br />&#160;int token_length = target.Length;<br />&#160;int pattern_length = pattern.Length;<br />&#160;while(target_index &lt; token_length &amp;&amp; pattern_index &lt; pattern_length) {<br />&#160;&#160;if(target[target_index] == pattern[pattern_index]) {<br />&#160;&#160;&#160;target_index++;<br />&#160;&#160;&#160;pattern_index++;<br />&#160;&#160;} else {<br />&#160;&#160;&#160;if(pattern_index == begin)<br />&#160;&#160;&#160;&#160;target_index++;<br />&#160;&#160;&#160;else<br />&#160;&#160;&#160;&#160;pattern_index = array[pattern_index - 1];<br />&#160;&#160;}<br />&#160;}<br />&#160;if(pattern_index == pattern_length)<br />&#160;&#160;return target_index - pattern_length;<br />&#160;return -1;<br />}</p>
		<h1>4 支持通配符?和*的KMP算法</h1>
		<p>KMP算法虽然能够进行字符串匹配，但是，在实践中字符串匹配往往还要支持通配符，MS系统中最常见的通配符是?和*。其中，?可以代表一个字符（不能没有），*可以代表任意多个字符（可以为空）。经典的KMP算法针对通配符是无能为力的，但是经过简单的改造，KMP算法也可以识别通配符。</p>
		<p>首先是?，根据?的功能，?表示任意字符，也就是说在匹配过程中，?永远匹配成功。因此对匹配函数的修改十分简单：<br />...<br />&#160;while(target_index &lt; token_length &amp;&amp; pattern_index &lt; pattern_length) {<br />&#160;&#160;if(target[target_index] == pattern[pattern_index]|| pattern[pattern_index] == '?') {<br />&#160;&#160;&#160;target_index++;<br />&#160;&#160;&#160;pattern_index++;<br />&#160;&#160;} else {<br />...<br />建立失效函数的过程和匹配过程类似，修改如下：<br />...<br />&#160;for(i = 1; i &lt; s; i++) {<br />&#160;&#160;if(pattern[i] == pattern[array[i - 1]]|| pattern[i] == '?' || pattern[array[i - 1]] == '?')<br />&#160;&#160;&#160;array[i] = array[i - 1] + 1;<br />...</p>
		<p>本质上，?并没有修改算法，而仅仅修改了匹配规则——遇到?则一定匹配。然而*与此不同，*的作用是匹配任意多个字符，显然我们不能简单的修改匹配过程而满足要求。如果我们重新思考*的作用，我们会发现*的另一个作用就是分割P串，即如果P=P<sub>1</sub>*P<sub>2</sub>，那么与其说*代表匹配任意多个字符，不如说P的匹配条件是在匹配P<sub>1</sub>子串后再匹配P<sub>2</sub>子串。</p>
		<p>现在回顾失效函数的作用，如果当匹配到P的j+1位时匹配失败，那么重新开始匹配的时候，P串的位置调整到f(j)位，直到P串的位置调整到0，则匹配重新开始。但当P=P<sub>1</sub>*P<sub>2</sub>，假如P<sub>1</sub>已经匹配成功，而在P<sub>2</sub>中发生匹配失败，那么P串要需要调整位置，但P串无论如何调整，此时也不应该调整到0，最多调整到P<sub>2</sub>的开始处，因为P<sub>1</sub>已经匹配，只需匹配P<sub>2</sub>即可。假如P=abcab*abcab，失效函数应该是（注意之前提到*的作用）：<br />a b c a b * a b c a b<br />0 0 0 1 2 - 6 6 6 7 8</p>
		<p>因此，要想让KMP支持*，那么关键是要重新设计失效函数的建立算法，如下：<br />public void Build() {<br />&#160;if(pattern == null)<br />&#160;&#160;throw new Exception("KMP Exception : null pattern");<br />&#160;array = new int[pattern.Length];<br />&#160;int i = 0, s = pattern.Length;<br />&#160;if(s &gt; 1)<br />&#160;&#160;array[0] = 0;<br />&#160;int begin = 0;<br />&#160;for(i = 1; i &lt; s; i++) {<br />&#160;&#160;if(pattern[i] == '*') {<br />&#160;&#160;&#160;array[i] = i;<br />&#160;&#160;&#160;begin = i + 1;<br />&#160;&#160;} else if(pattern[i] == pattern[array[i - 1]] || pattern[i] == '?' || pattern[array[i - 1]] == '?')<br />&#160;&#160;&#160;array[i] = array[i - 1] + 1;<br />&#160;&#160;else<br />&#160;&#160;&#160;array[i] = begin;<br />&#160;}<br />}&#160;</p>
		<p>算法中begin表示每段字符串的开始位置。此外，匹配过程也应该进行相应的修改，因为字符*对于匹配没有任何帮助，它属于占位符，因此需要跳过，匹配算法如下：<br />public int Match(String target, int start) {<br />&#160;if(array == null || pattern == null || target == null)<br />&#160;&#160;return -1;<br />&#160;int target_index = start;<br />&#160;int pattern_index = 0;<br />&#160;int token_length = target.Length;<br />&#160;int pattern_length = pattern.Length;<br />&#160;int begin = 0;<br />&#160;while(target_index &lt; token_length &amp;&amp; pattern_index &lt; pattern_length) {<br />&#160;&#160;if(pattern[pattern_index] == '*') {<br />&#160;&#160;&#160;begin = pattern_index + 1;<br />&#160;&#160;&#160;pattern_index++;<br />&#160;&#160;} else if(target[target_index] == pattern[pattern_index] || pattern[pattern_index] == '?') {<br />&#160;&#160;&#160;target_index++;<br />&#160;&#160;&#160;pattern_index++;<br />&#160;&#160;} else {<br />&#160;&#160;&#160;if(pattern_index == begin)<br />&#160;&#160;&#160;&#160;target_index++;<br />&#160;&#160;&#160;else<br />&#160;&#160;&#160;&#160;pattern_index = array[pattern_index - 1];<br />&#160;&#160;}<br />&#160;}<br />&#160;if(pattern_index == pattern_length)<br />&#160;&#160;return target_index - pattern_length + begin;<br />&#160;return -1;<br />}</p>
		<h1>5 正则语言和确定状态自动机</h1>
		<p>一个数字逻辑的问题：设计一个识别11011的电路，解这个问题的关键就是设计出这个电路的DFA，如下：<br /><img style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.blog.edu.cn/UploadFiles/2006-8/823915044.png" onload="javascript:if(this.width&gt;500){this.resized=true;this.style.width=500;}" /></p>
		<p>仔细看看这个状态机，是不是和KMP的算法有几分类似呢？这并不是巧合，因为KMP算法中的失效函数总可以等价的转化为一个DFA。当然KMP的DFA远比识别11011的DFA要复杂，原因在于KMP接受的输入是全体字符集合，识别11011的DFA只接受0和1这两个输入。我们知道，一个正则语言和一个DFA是等价的，而KMP计算失效函数的算法，实际上等价于求DFA的过程，f(j)的值实际上表明状态j+1接受到不正确的字符时应该回溯到的状态（注意此时输入流并没有前进）。普通的字符串都能看成是一个正则语言，含有通配符?和*的字符串也可以等价的转换为一个正则表达式。但是，正则语言的集合远比KMP算法所能支持的模式集合的更大，期间原因还是刚才提过的输入问题。试想P=p<sub>1</sub>p<sub>2</sub>...p<sub>n</sub>，当匹配到p<sub>j</sub>的时候，如果下一个输入字符正是p<sub>j</sub>，那么状态机进入下一个状态，如果不是p<sub>j</sub>，那么状态机按照实效函数的指示转移到状态f(j-1)，也就是说KMP状态机的每个状态只能根据输入是否为p<sub>j</sub>来进行转移。而正则表达式所对应的状态机则有所不同，如果正则语言L=l<sub>1</sub>l<sub>2</sub>...l<sub>n</sub>，假设这些都是字母，当匹配到l<sub>j</sub>位的时候，如果下一个输入字符正是l<sub>j</sub>，那么状态机进入下一个状态，否则它还可以根据输入的值进行转移，例如l<sub>j</sub>=c<sub>1</sub>时转换到状态x，l<sub>j</sub>=c<sub>2</sub>时状态转换到y等等。</p>
		<h1>6 结语</h1>
		<p>字符串匹配问题是老问题了，并没有太多新意可言，只不过虽然KMP算法十分简单，但它的内在含义还是十分深刻的。横向比较KMP、DFA和正则语言、正则表达式我们会发现，它们之间存在很多的关联，而这种比较也有利于我们更好的理解这些算法，或者改进这些算法。最后说一句，试图利用目前的框架使得KMP算法支持全部种类的通配符（对应于正则表达式就是x?、x*、x+、{m,n}等等）是不可能，而我们也不需要这么做，因为我们还有正则表达式嘛。</p>
 <img src ="http://www.blogjava.net/onejavaer/aggbug/101992.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/onejavaer/" target="_blank">暗夜精灵</a> 2007-03-05 21:25 <a href="http://www.blogjava.net/onejavaer/articles/101992.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>NoClassDefDoundErr与ClassNotFoundException区别 </title><link>http://www.blogjava.net/onejavaer/articles/101651.html</link><dc:creator>暗夜精灵</dc:creator><author>暗夜精灵</author><pubDate>Sat, 03 Mar 2007 10:23:00 GMT</pubDate><guid>http://www.blogjava.net/onejavaer/articles/101651.html</guid><wfw:comment>http://www.blogjava.net/onejavaer/comments/101651.html</wfw:comment><comments>http://www.blogjava.net/onejavaer/articles/101651.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/onejavaer/comments/commentRss/101651.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/onejavaer/services/trackbacks/101651.html</trackback:ping><description><![CDATA[		<p>作者:langm</p>
		<p>版权声明：本文可以自由转载，转载时请务必以超链接形式标明文章原始出处和作者信息及本声明 <br />作者:langm <br />原文:http://www.matrix.org.cn/resource/article/44/44056_NoClassDefDoundErr.html <br />关键字:NoClassDefDoundErr ClassNotFoundException</p>
		<p>在读这篇文章之前，你最好了解一下Java的Exception机制。</p>
		<p>也许你在开发的过程中经常地见到ClassNotFoundException和NoClassDefFoundErr这两个异常，每每看到之后，都会一概而论的是类没有找到，但有些时候见到他们的时候又有些疑惑（至少我是这样），为什么Java要用两个异常来表示类定义没有找到那？他们之间有什么区别那？</p>
		<p>正巧今天我又碰到了这个问题，顺便的仔细研究了一下这两个异常的区别。 <br />首先： <br />ClassNotFoundException直接继承与Exception，它是一个checked的异常。 <br />NoClassDefFoundErr 继承自Error-&gt;LinkageError ，它是一个unchecked的异常。</p>
		<p>下面让我们看一下两个异常在API文档中的说明</p>
		<p>ClassNotFoundException： <br />当应用尝试用字符串名称通过下面的方法装载一个类时这个类的定义却没有找到时会抛出的异常。 <br />Class.forName <br />ClassLoader.findSystemClass <br />ClassLoader.loadClass <br /><br />NoClassDefFoundErr： <br />当JVM或者ClassLoader实例尝试装载一个类的定义（这通常是一个方法调用或者new表达式创建一个实例过程的一部分）而这个类定义并没有找时所抛出的错误。 <br />当编译的时候可以找到这个类的定义，但是以后这个类不再存在。</p>
		<p>这比较显而易见了吧，读好文档是很重要的事情。这里我就说一下我对这两个类的区别的理解。</p>
		<p>ClassNotFoundException异常只出现在你的应用程序主动的装载类的过程中，这个异常很多时候出现在我们的应用框架在初始化或者运行中动态装载已配置的类的过程中。这种情况下我们应该首先检查我们的配置或者参数是否错误，是否企图装载一个并不存在的类，如果配置没有错误，我们就应该查看Classpath是否配置错误而导致ClassLoader无法找到这个类，也应该检查要装载的类是否在一个jar包中而我们在引入这个jar包的过程中是否有遗漏或错误（这里jar包的版本也是一个需要格外注意的问题，很多时候混乱的jar包版本会造成太多的麻烦）。 <br /><br />NoClassDefFoundErr异常一般出现在我们编译环境和运行环境不一致的情况下，就是说我们有可能在编译过后更改了Classpath或者jar包所以导致在运行的过程中JVM或者ClassLoader无法找到这个类的定义（我曾经在编译后作了一次jar包的清理，然后应用就送给了我一个这样的礼物）。</p>
		<p>我们经常用SDK开发应用，开发的过程中要引入很多jar包，有些SDK也会设定自己的Classpath。编译过程结束后在运行的过程中就要将已开发的应用和所有引入的jar包拷贝到应用服务器的相应目录下才可以运行，而应用服务器使用的Classpath也很有可能与SDK的不同，在这个过程中就有很大的几率造成双方环境不一致。所以很多开发者就会遇到在SDK中可以编译，运行也没有问题，但是同样的程序放到应用服务器上就出现NoClassDefFoundErr这个异常这种情况，这是让初学者很挠头的一个问题。</p>
		<p>以上就是我对这两个异常的一点个人理解，希望对各位开发者有所帮助，可以让各位开发者在以后的开发过程中能够更快的找到问题所在。祝开发顺利</p>
 <img src ="http://www.blogjava.net/onejavaer/aggbug/101651.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/onejavaer/" target="_blank">暗夜精灵</a> 2007-03-03 18:23 <a href="http://www.blogjava.net/onejavaer/articles/101651.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java异常处理</title><link>http://www.blogjava.net/onejavaer/articles/101649.html</link><dc:creator>暗夜精灵</dc:creator><author>暗夜精灵</author><pubDate>Sat, 03 Mar 2007 10:14:00 GMT</pubDate><guid>http://www.blogjava.net/onejavaer/articles/101649.html</guid><wfw:comment>http://www.blogjava.net/onejavaer/comments/101649.html</wfw:comment><comments>http://www.blogjava.net/onejavaer/articles/101649.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/onejavaer/comments/commentRss/101649.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/onejavaer/services/trackbacks/101649.html</trackback:ping><description><![CDATA[		<p>
				<strong>
						<font size="4">1 Java的异常控制机制</font>
				</strong>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">捕获错误最理想的是在编译期，最好在试图运行程序以前。然而，并非所有错误都能在编译期间侦测到。有些问题必须在运行期间解决。让错误的缔结者通过一定的方法预先向接收者传递一些适当的信息，使其知道可能发生什么样的错误以及该如何处理遇到的问题，这就是Java的异常控制机制。<br />&#8220;异常&#8221;（Exception）这个词表达的是一种正常情况之外的&#8220;异常&#8221;。在问题发生的时候，我们可能不知具体该如何解决，但肯定知道已不能不顾一切地继续下去。此时，必须坚决地停下来，并由某人、某地指出发生了什么事情，以及该采取何种对策。异常机制的另一项好处就是能够简化错误控制代码。我们再也不用检查一个特定的错误，然后在程序的多处地方对其进行控制。此外，也不需要在方法调用的时候检查错误（因为保证有人能捕获这里的错误）。我们只需要在一个地方处理问题：&#8220;异常控制模块&#8221;或者&#8220;异常控制器&#8221;。这样可有效减少代码量，并将那些用于描述具体操作的代码与专门纠正错误的代码分隔开。一般情况下，用于读取、写入以及调试的代码会变得更富有条理。<br />若某个方法产生一个异常，必须保证该异常能被捕获，并获得正确对待。Java的异常控制机制的一个好处就是允许我们在一个地方将精力集中在要解决的问题上，然后在另一个地方对待来自那个代码内部的错误。那个可能发生异常的地方叫做&#8220;警戒区&#8221;，它是一个语句块，我们有必要派遣警探日夜监视着。生成的异常必须在某个地方被捕获和进行处理，就象警察抓到嫌疑犯后要带到警署去询问。这个地方便是异常控制模块。<br />&#8220;警戒区&#8221;是一个try关键字开头后面用花括号括起来的语句块，我们把它叫作&#8220;try块&#8221;。当try块中有语句发生异常时就掷出某种异常类的一个对象。异常被异常控制器捕获和处理，异常控制器紧接在try块后面，且用catch关键字标记，因此叫做&#8220;catch块&#8221;。catch块可以有多个，每一个用来处理一个相应的异常，因为在&#8220;警戒区&#8221;内可能发生的异常种类不止一个。所以，异常处理语句的一般格式是：<br />try {<br />&#160; // 可能产生异常的代码<br />&#160; }<br />&#160;catch (异常对象 e) {<br />&#160;&#160; //异常 e的处理语句<br />&#160;}catch (异常对象 e1) {<br />&#160;&#160; //异常 e的处理语句<br />&#160;}catch (异常对象 e2) {<br />&#160;&#160; //异常 e的处理语句<br />&#160;}</font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">即使不使用try-catch结构，发生异常时Java的异常控制机制也会捕获该异常，输出异常的名称并从异常发生的位置打印一个堆栈跟踪。然后立即终止程序的运行。下面的例子发生了一个&#8220;零除&#8221;异常，后面的hello没有被打印。</font>
		</p>
		<p>
				<font face="宋体" size="4">例1 没有作异常控制的程序。</font>
		</p>
		<p>
				<font face="宋体" size="4">///</font>
				<font face="宋体" color="#ff0000">
						<br />
						<font size="4">public</font>
				</font>
				<font size="4">
						<font face="宋体">
						</font>
						<font face="宋体" color="#ff0000">class</font>
				</font>
				<font size="4">
						<font face="宋体"> Exception1 {<br />&#160;&#160;&#160;</font>
						<font face="宋体" color="#ff0000">public</font>
						<font face="宋体">
						</font>
						<font face="宋体" color="#ff0000">static</font>
						<font face="宋体">
						</font>
						<font face="宋体" color="#ff0000">void</font>
				</font>
				<font size="4">
						<font face="宋体"> main(String args[]) {<br />&#160;&#160;&#160;</font>
						<font face="宋体" color="#ff0000">int</font>
				</font>
				<font size="4">
						<font face="宋体"> b = 0;<br />&#160;&#160;&#160;</font>
						<font face="宋体" color="#ff0000">int</font>
				</font>
				<font size="4">
						<font face="宋体"> a = 3 / b;<br />&#160;&#160;&#160;</font>
						<font face="宋体">System.out.println(</font>
						<font face="宋体" color="#006600">"Hello!"</font>
				</font>
				<font size="4">
						<font face="宋体">);<br /></font>&#160; </font>
				<font face="宋体" size="4">}<br />}<br />///</font>
		</p>
		<p>
				<font size="4">输出结果：<br />java.lang.ArithmeticException: / by zero<br />at Exception1.main(Exception1.java:5)<br />Exception in thread "main" Exit code: 1<br />There were errors</font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">但是如果使用了try-catch来处理异常，那么在打印出异常信息后，程序还将继续运行下去。下面是处理了的代码。</font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font face="宋体" size="4">///<br />// Exception2.java</font>
				<font face="宋体" color="#ff0000">
						<br />
						<font size="4">public</font>
				</font>
				<font size="4">
						<font face="宋体">
						</font>
						<font face="宋体" color="#ff0000">class</font>
				</font>
				<font size="4">
						<font face="宋体"> Exception2 {<br />&#160; </font>
						<font face="宋体" color="#ff0000">public</font>
						<font face="宋体">
						</font>
						<font face="宋体" color="#ff0000">static</font>
						<font face="宋体">
						</font>
						<font face="宋体" color="#ff0000">void</font>
				</font>
				<font size="4">
						<font face="宋体"> main(String args[]) {<br />&#160;&#160; <font color="#ff0000">try</font> {&#160;</font>&#160;</font>
				<font face="宋体">
						<br />
						<font size="4">&#160;&#160;&#160;</font>
				</font>
				<font size="4">
						<font face="宋体" color="#ff0000">int</font>
						<font face="宋体"> b = 0;&#160;</font>&#160;</font>
				<font face="宋体" color="#ff0000">
						<br />
						<font size="4">&#160;&#160;&#160; int</font>
				</font>
				<font size="4">
						<font face="宋体"> a = 3 / b;<br />&#160;&#160;&#160; }<br /></font>&#160;&#160; <font color="#ff0000">catch</font>(ArithmeticException e) {<br /><font face="宋体">&#160;&#160;&#160;</font>&#160; e.printStackTrace<br />&#160;&#160;&#160; }</font>
				<font face="宋体">
						<br />
						<font size="4">&#160;&#160;&#160;</font>
				</font>
				<font size="4">
						<font face="宋体">System.out.println(</font>
						<font face="宋体" color="#006600">"Hello!"</font>
				</font>
				<font size="4">
						<font face="宋体">);<br /></font>&#160; </font>
				<font face="宋体" size="4">}<br />}<br />///</font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">输出结果：<br />Exception:<br />java.lang.ArithmeticException: / by zero<br />&#160;&#160; at Exception2.main(Exception1.java:5)<br /><font color="#ff0000">Hello!</font></font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">与前例不同的是，Hello!被输出了。这就是try-catch结构的用处，它使异常发生和处理后程序得以&#8220;恢复&#8221;而不是&#8220;中断&#8221;。</font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<strong>
						<font size="4">2 异常类、异常规范和throw语句</font>
						<a name="t2">
						</a>
				</strong>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">为了使异常控制机制更出色地发挥它的功效，Java设计者几乎所以可能发生的异常，预制了各色各样的异常类和错误类。它们都是从&#8220;可掷出&#8221;类Throwable继承而来的，它派生出两个类Error和Exception。由Error派生的子类命名为XXXError，其中词XXX是描述错误类型的词。由Exception派生的子类命名为XXXException，其中词XXX是描述异常类型的词。Error类处理的是运行使系统发生的内部错误，是不可恢复的，唯一的办法只要终止运行运行程序。因此，客户程序员只要掌握和处理好Exception类就可以了。<br />Exception类是一切异常的根。现成的异常类非常之多，我们不可能也没有必要全部掌握它。好在异常类的命名规则大致描述出了该类的用途，而异常类的方法基本是一样的。下面给出lang包中声明的部分异常类。</font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">RuntimeException&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 运行时异常<br />NullPointerException&#160;&#160;&#160;&#160;&#160;&#160;&#160; 数据没有初始化就使用<br />IndexOutOfBoundsException&#160;&#160; 数组或字符串索引越界<br />NoSuchFieldException&#160;&#160;&#160;&#160;&#160;&#160;&#160; 文件找不到<br />NoSuchMethodException&#160;&#160;&#160;&#160;&#160;&#160; 方法没有定义<br />ArithmeticException&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 非法算术运行</font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">在其他包中也有相关的异常类，例如io包中有IOEception类。利用异常的命名规则，你可以使用下面的DOS命令在包所在的目录查看有什么异常类可用：<br />&#160;&#160;&#160; DIR *Eception.class&#160;<br />对于运行时异常RuntimeException，我们没必要专门为它写一个异常控制器，因为它们是由于编程不严谨而造成的逻辑错误。只要让出现终止，它会自动得到处理。需要程序员进行异常处理的是那些非运行期异常。<br />Throwable有三个基本方法：</font>
		</p>
		<ul>
				<li>
						<p style="LINE-HEIGHT: 150%">
								<font size="4">String getMessage()&#160;&#160; 获得详细的消息。 </font>
						</p>
				</li>
				<li>
						<p style="LINE-HEIGHT: 150%">
								<font size="4">String toString()&#160;&#160;&#160;&#160; 返回对本类的一段简要说明，其中包括详细的消息（如果有的话）。 </font>
						</p>
				</li>
				<li>
						<p style="LINE-HEIGHT: 150%">
								<font size="4">void printStackTrace()&#160; 或&#160; void printStackTrace(PrintStream)<br />打印出调用堆栈路径。调用堆栈显示出将我们带到异常发生地点的方法调用的顺序。 </font>
						</p>
				</li>
		</ul>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">因为Exception类是一切异常的根，所以对任何一个现有的异常类都可以使用上述方法。 </font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">
						<strong>异常规范</strong>
						<strong>和</strong>
						<strong>throws</strong>
				</font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">java库程序员为了使客户程序员准确地知道要编写什么代码来捕获所有潜在的异常，采用一种叫做throws的语法结构。它用来通知那些要调用方法的客户程序员，他们可能从自己的方法里&#8220;掷&#8221;出什么样的异常。这便是所谓的&#8220;异常规范&#8221;，它属于方法声明的一部分，即在自变量（参数）列表的后面加上throws 异常类列表。例如<br />&#160;&#160;&#160; void f() throws tooBig, tooSmall, divZero { 方法体}<br />若使用下述代码：<br />&#160;&#160;&#160; void f() [ // ...<br />它意味着不会从方法里&#8220;掷&#8221;出异常（除类型为RuntimeException的异常以外，它可能从任何地方掷出）。<br />如果一个方法使用了异常规范，我们在调用它时必须使用try-catch结构来捕获和处理异常规范所指示的异常，否则编译程序会报错而不能通过编译。这正是Java的异常控制机制的杰出贡献，它对可能发生的意外及早预防从而加强了代码的健壮性。<br />在使用了异常规范的方法声明中，库程序员使用throw语句来掷出一个异常。throw语句的格式为：<br />&#160;&#160;&#160; <font color="#0000ff">throw</font><font color="#0000ff">new</font> XXXException();<br />由此可见，throw语句掷出的是XXX类型的异常的对象（隐式的句柄）。而catch控制器捕获对象时要给出一个句柄 catch(XXXException e)。<br />我们也可以采取&#8220;欺骗手段&#8221;，用throw语句&#8220;掷&#8221;出一个并没有发生的异常。编译器能理解我们的要求，并强迫使用这个方法的用户当作真的产生了那个异常处理。在实际应用中，可将其作为那个异常的一个&#8220;占位符&#8221;使用。这样一来，以后可以方便地产生实际的异常，毋需修改现有的代码。下面我们用&#8220;欺骗手段&#8221;给出一个捕获异常的示例程序。</font>
		</p>
		<p>
				<font size="4">例2 本例程演示异常类的常用方法。</font>
		</p>
		<p>
				<font size="4">///</font>
				<font color="#0000ff">
						<br />
						<font size="4">public</font>
				</font>
				<font size="4">
						<font color="#0000ff">class</font> ExceptionMethods {<br />&#160; <font color="#0000ff">public</font><font color="#0000ff">static</font><font color="#0000ff">void</font> main(String[] args) {<br />&#160;&#160;&#160; <font color="#0000ff">try</font> {<br />&#160;&#160;&#160;&#160;&#160; <font color="#0000ff">throw</font><font color="#0000ff">new</font> Exception(<font color="#004488">"Here's my Exception"</font>);<br />&#160;&#160;&#160; } <font color="#0000ff">catch</font>(Exception e) {<br />&#160;&#160;&#160;&#160;&#160; System.out.println(<font color="#004488">"Caught Exception"</font>);<br />&#160;&#160;&#160;&#160;&#160; System.out.println(<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="#004488">"e.getMessage(): "</font> + e.getMessage());<br />&#160;&#160;&#160;&#160;&#160; System.out.println(<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="#004488">"e.toString(): "</font> + e.toString());<br />&#160;&#160;&#160;&#160;&#160; System.out.println(<font color="#004488">"e.printStackTrace():"</font>);<br />&#160;&#160;&#160;&#160;&#160; e.printStackTrace();<br />&#160;&#160;&#160; }<br />&#160; }<br />}<br />///</font>
		</p>
		<p>
				<font size="4">该程序输出如下：<br />Caught Exception<br />e.getMessage(): Here's my Exception<br />e.toString(): java.lang.Exception: Here's my Exception<br />e.printStackTrace():<br />java.lang.Exception: Here's my Exception<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; at ExceptionMethods.main</font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">在一个try区中潜在的异常可能是多种类型的，那时我们需要用多个catch块来捕获和处理这些异常。但异常发生时掷出了某类异常对象，Java依次逐个检查这些异常控制器，发现与掷出的异常类型匹配时就执行那以段处理代码，而其余的不会被执行。为了防止可能遗漏了某一类异常控制器，可以放置一个捕获Exception类的控制器。Exception是可以从任何类方法中&#8220;掷&#8221;出的基本类型。但是它必须放在最后一个位置，因为它能够截获任何异常，从而使后面具体的异常控制器不起作用。下面的示例说明了这一点。</font>
		</p>
		<p>
				<font size="4">例3 本例程演示多个异常控制器的排列次序的作用。</font>
		</p>
		<p>
				<font size="4">///</font>
				<font face="宋体" color="#ff0000">
						<br />
						<font size="4">public</font>
				</font>
				<font size="4">
						<font face="宋体">
						</font>
						<font face="宋体" color="#ff0000">class</font>
				</font>
				<font size="4">
						<font face="宋体"> MutilCatch {<br /></font>&#160; <font face="宋体" color="#ff0000">private static</font><font face="宋体" color="#000000"></font><font face="宋体" color="#ff0000">void</font><font face="宋体" color="#000000"> test(</font><font face="宋体" color="#ff0000">int</font></font>
				<font size="4">
						<font face="宋体" color="#000000"> i) {<br /></font>
						<font face="宋体" color="#ff0000">&#160;&#160;&#160;</font>
						<font face="宋体" color="#000000">
						</font>
						<font face="宋体" color="#ff0000">try</font>
				</font>
				<font size="4">
						<font face="宋体"> {<br />&#160;&#160;&#160;</font>
						<font face="宋体" color="#ff0000">int</font>
				</font>
				<font size="4">
						<font face="宋体" color="#000000"> x = i;<br />&#160;&#160;&#160;</font>
						<font face="宋体" color="#ff0000">if</font>
				</font>
				<font size="4">
						<font face="宋体" color="#000000"> (x&gt;0)<br />&#160;&#160;&#160;&#160;&#160;</font>
						<font face="宋体" color="#ff0000">throw</font>
						<font face="宋体" color="#000000">
						</font>
						<font face="宋体" color="#ff0000">new</font>
						<font face="宋体" color="#000000"> ArithmeticException (</font>
						<font face="宋体" color="#006600">"this is a Arithmetic Exception!"</font>
				</font>
				<font size="4">
						<font face="宋体" color="#000000">);<br />&#160;&#160;&#160;</font>
						<font face="宋体" color="#ff0000">else</font>
						<font face="宋体" color="#000000">
						</font>
						<font face="宋体" color="#ff0000">if</font>
				</font>
				<font size="4">
						<font face="宋体" color="#000000"> (x&lt;0)<br />&#160;&#160;&#160;&#160;&#160;</font>
						<font face="宋体" color="#ff0000">throw</font>
						<font face="宋体" color="#000000">
						</font>
						<font face="宋体" color="#ff0000">new</font>
						<font face="宋体" color="#000000"> NullPointerException (</font>
						<font face="宋体" color="#006600">"this is a NullPointer Exception!"</font>
				</font>
				<font size="4">
						<font face="宋体" color="#000000">);<br />&#160;&#160;&#160;</font>
				</font>
				<font size="4">
						<font face="宋体" color="#ff0000">else<br />&#160;&#160;&#160;</font>
						<font face="宋体" color="#000000">&#160;&#160; </font>
						<font face="宋体" color="#ff0000">throw</font>
						<font face="宋体" color="#000000">
						</font>
						<font face="宋体" color="#ff0000">new</font>
						<font face="宋体" color="#000000"> Exception(</font>
						<font face="宋体" color="#006600">"this is a Exception!"</font>
						<font face="宋体" color="#000000">);</font>
				</font>
				<font face="宋体">
						<br />
						<font size="4">&#160;&#160;&#160;</font>
				</font>
				<font size="4">
						<font face="宋体">} </font>
						<font face="宋体" color="#ff0000">catch</font>
				</font>
				<font size="4">
						<font face="宋体">(ArithmeticException e) {<br />&#160;&#160;&#160;</font>&#160;<font face="宋体">&#160;&#160;&#160;</font></font>
				<font size="4">
						<font face="宋体">System.out.println(e.toString());<br />&#160;&#160;&#160;</font>
						<font face="宋体">} </font>
						<font face="宋体" color="#ff0000">catch</font>
				</font>
				<font size="4">
						<font face="宋体">(NullPointerException e) {<br />&#160;&#160;&#160;</font>&#160;<font face="宋体">&#160;&#160;&#160;</font></font>
				<font size="4">
						<font face="宋体">System.out.println(e.toString());<br />&#160;&#160;&#160;</font>
						<font face="宋体">} </font>
						<font face="宋体" color="#ff0000">catch</font>
				</font>
				<font size="4">
						<font face="宋体">(Exception e) {<br />&#160;&#160;&#160;</font>&#160;<font face="宋体">&#160;&#160;&#160;</font></font>
				<font size="4">
						<font face="宋体">System.out.println(e.toString());<br />&#160;&#160;&#160;</font>
						<font face="宋体">}</font>
				</font>
				<font face="宋体" color="#000000">
						<br />
						<font size="4">&#160;&#160;</font>
				</font>
				<font size="4">
						<font face="宋体" color="#000000">}</font>
				</font>
				<font face="宋体" color="#ff0000">
						<br />
						<font size="4">&#160; public</font>
				</font>
				<font size="4">
						<font face="宋体">
						</font>
						<font face="宋体" color="#ff0000">static</font>
						<font face="宋体">
						</font>
						<font face="宋体" color="#ff0000">void</font>
				</font>
				<font size="4">
						<font face="宋体"> main(String[] args) {<br />&#160;&#160;&#160;</font>
				</font>
				<font size="4">
						<font face="宋体">test(-1); test(0); test(1);<br /></font>&#160; </font>
				<font size="4">
						<font face="宋体">}<br /></font>&#160;</font>
				<font face="宋体" size="4">}<br />///</font>
		</p>
		<p>
				<font face="宋体" size="4">运行结果：<br />java.lang.NullPointerException: this is a NullPointer Exception!<br />java.lang.Exception: this is a Exception!<br />java.lang.ArithmeticException: this is a Arithmetic Exception!<br />如果你把捕获Exception的catch放在前面，编译就通不过。</font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<br />
				<strong>
						<font size="4">3 用finally清理</font>
						<a name="t3">
						</a>
				</strong>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">我们经常会遇到这样的情况，无论一个异常是否发生，必须执行某些特定的代码。比如文件已经打开，关闭文件是必须的。但是，在try区内位于异常发生点以后的代码，在发生异常后不会被执行。在catch区中的代码在异常没有发生的情况下不会被执行。为了无论异常是否发生都要执行的代码，可在所有异常控制器的末尾使用一个finally从句，在finally块中放置这些代码。（但在恢复内存时一般都不需要，因为垃圾收集器会自动照料一切。）所以完整的异常控制结构象下面这个样子：<br /><br />try { 警戒区域 }<br />catch (A a1) { 控制器 A }<br />catch (B b1) { 控制器 B }<br />catch (C c1) { 控制器 C }<br />finally { 必须执行的代码}</font>
		</p>
		<font size="4">例4 演示finally从句的程序。 </font>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">
						<font color="#009900">///<br />// FinallyWorks.java</font>
						<br />
						<font color="#009900">// The finally clause is always executed</font>
						<br />
						<font color="#0000ff">public</font>
						<font color="#0000ff">class</font> FinallyWorks {<br />&#160; <font color="#0000ff">static</font><font color="#0000ff">int</font> count = 0;<br />&#160; <font color="#0000ff">public</font><font color="#0000ff">static</font><font color="#0000ff">void</font> main(String[] args) {<br />&#160;&#160;&#160; <font color="#0000ff">while</font>(<font color="#0000ff">true</font>) {<br />&#160;&#160;&#160;&#160;&#160; <font color="#0000ff">try</font> {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="#009900">// post-increment is zero first time:</font><br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="#0000ff">if</font>(count++ == 0)<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="#0000ff">throw</font><font color="#0000ff">new</font> Exception();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println(<font color="#004488">"No exception"</font>);<br />&#160;&#160;&#160;&#160;&#160; } <font color="#0000ff">catch</font>(Exception e) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println(<font color="#004488">"Exception thrown"</font>);<br />&#160;&#160;&#160;&#160;&#160; } <font color="#0000ff">finally</font> {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println(<font color="#004488">"in finally clause"</font>);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="#0000ff">if</font>(count == 2) <font color="#0000ff">break</font>; <font color="#009900">// out of "while"</font><br />&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160; }<br />&#160; }<br />}<br />///</font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">运行结果：<br />Exception thrown<br />in finally clause<br />No exception<br />in finally clause<br />一开始count=0发生异常，然后进入finally块；进入循环第二轮没有异常，但又执行一次finally块，并在其中跳出循环。<br />下面我们给出一个有的实用但较为复杂一点的程序。我们创建了一个InputFile的类。它的作用是打开一个文件，然后每次读取它的一行内容。</font>
		</p>
		<p>
				<font size="4">例5 读文本文件并显示到屏幕上。</font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">
						<font color="#009900">///<br />//: Cleanup.java</font>
						<br />
						<font color="#009900">// Paying attention to exceptions in constructors</font>
						<br />
						<font color="#0000ff">import</font> java.io.*;<br /><br /><font color="#0000ff">class</font> InputFile {<br />&#160; <font color="#0000ff">private</font> BufferedReader in;<br />&#160; InputFile(String fname) <font color="#0000ff">throws</font> Exception {<br />&#160;&#160;&#160; <font color="#0000ff">try</font> {<br />&#160;&#160;&#160;&#160;&#160; in = <font color="#0000ff">new</font> BufferedReader(<font color="#0000ff">new</font> FileReader(fname));<br />&#160;&#160;&#160;&#160;&#160; <font color="#009900">// Other code that might throw exceptions</font><br />&#160;&#160;&#160; } <font color="#0000ff">catch</font>(FileNotFoundException e) {<br />&#160;&#160;&#160;&#160;&#160; System.out.println(<font color="#004488">"Could not open "</font> + fname);<br />&#160;&#160;&#160;&#160;&#160; <font color="#009900">// Wasn't open, so don't close it</font><br />&#160;&#160;&#160;&#160;&#160; <font color="#0000ff">throw</font> e;<br />&#160;&#160;&#160; } <font color="#0000ff">catch</font>(Exception e) {<br />&#160;&#160;&#160;&#160;&#160; <font color="#009900">// All other exceptions must close it</font><br />&#160;&#160;&#160;&#160;&#160; <font color="#0000ff">try</font> {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; in.close();<br />&#160;&#160;&#160;&#160;&#160; } <font color="#0000ff">catch</font>(IOException e2) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println(<font color="#004488">"in.close() unsuccessful"</font>);<br />&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160; <font color="#0000ff">throw</font> e;<br />&#160;&#160;&#160; } <font color="#0000ff">finally</font> {<br />&#160;&#160;&#160;&#160;&#160; <font color="#009900">// Don't close it here!!!</font><br />&#160;&#160;&#160; }<br />&#160; }<br />&#160; String getLine() {<br />&#160;&#160;&#160; String s;<br />&#160;&#160;&#160; <font color="#0000ff">try</font> {<br />&#160;&#160;&#160;&#160;&#160; s = in.readLine();<br />&#160;&#160;&#160; } <font color="#0000ff">catch</font>(IOException e) {<br />&#160;&#160;&#160;&#160;&#160; System.out.println(<font color="#004488">"readLine() unsuccessful"</font>);<br />&#160;&#160;&#160;&#160;&#160; s = <font color="#004488">"failed"</font>;<br />&#160;&#160;&#160; }<br />&#160;&#160;&#160; <font color="#0000ff">return</font> s;<br />&#160; }<br />&#160; <font color="#0000ff">void</font> cleanup() {<br />&#160;&#160;&#160; <font color="#0000ff">try</font> {<br />&#160;&#160;&#160;&#160;&#160; in.close();<br />&#160;&#160;&#160; } <font color="#0000ff">catch</font>(IOException e2) {<br />&#160;&#160;&#160;&#160;&#160; System.out.println(<font color="#004488">"in.close() unsuccessful"</font>);<br />&#160;&#160;&#160; }<br />&#160; }<br />} <br /><font color="#0000ff">public</font><font color="#0000ff">class</font> Cleanup {<br />&#160; <font color="#0000ff">public</font><font color="#0000ff">static</font><font color="#0000ff">void</font> main(String[] args) {<br />&#160;&#160;&#160; <font color="#0000ff">try</font> {<br />&#160;&#160;&#160;&#160;&#160; InputFile in = <font color="#0000ff">new</font> InputFile(<font color="#004488">"Cleanup.java"</font>);<br />&#160;&#160;&#160;&#160;&#160; String s;<br />&#160;&#160;&#160;&#160;&#160; <font color="#0000ff">int</font> i = 1;<br />&#160;&#160;&#160;&#160;&#160; <font color="#0000ff">while</font>((s = in.getLine()) != <font color="#0000ff">null</font>)<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println(<font color="#004488">""</font>+ i++ + <font color="#004488">": "</font> + s);<br />&#160;&#160;&#160;&#160;&#160; in.cleanup();<br />&#160;&#160;&#160; } <font color="#0000ff">catch</font>(Exception e) {<br />&#160;&#160;&#160;&#160;&#160; System.out.println( <font color="#004488">"Caught in main, e.printStackTrace()"</font>);<br />&#160;&#160;&#160;&#160;&#160; e.printStackTrace();<br />&#160;&#160;&#160; }<br />&#160; }<br />}<br />///</font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">运行后输出的前2行是：<br />1: //: Cleanup.java<br />2: // Paying attention to exceptions in constructors<br />3: import java.io.*;</font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">简要说明 InputFile的类包含一个构建器和两个方法cleanup和getLine。构建器要打开一个文件fname，首先要捕获FileNotFoundException类异常。在它的处理代码中再掷出这个异常(<font color="#0000ff">throw</font> e;)。在更高的控制器中试图关闭文件，并捕捉关闭失败的异常IOException。cleanup()关闭文件，getLine()读文件的一行到字符串，它们都用了异常处理机制。Cleanup是主类，在main()中首先创建一个InputFile类对象，因为它的构建器声明时用了异常规范，所以必须用try-catch结构来捕获异常。</font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<strong>
						<font size="4">4 创建自己的异常类</font>
						<a name="t4">
						</a>
				</strong>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">虽然Java类库提供了十分丰富的异常类型，能够满足绝大多数编程需要。但是，在开发较大的程序时，也有可能需要建立自己的异常类。要创建自己的异常类，必须从一个现有的异常类型继承——最好在含义上与新异常近似。创建一个异常相当简单，只要按如下格式写两个构建器就行：</font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">class MyException extends Exception {<br />&#160;&#160;&#160; public MyException() {}<br />&#160;&#160;&#160; public MyException(String msg) {<br />&#160;&#160;&#160; super(msg);<br />&#160; }<br />}<br />这里的关键是&#8220;extends Exception&#8221;，它的意思是：除包括一个Exception的全部含义以外，还有更多的含义。增加的代码数量非常少——实际只添加了两个构建器，对MyException的创建方式进行了定义。请记住，假如我们不明确调用一个基础类构建器，编译器会自动调用基础类默认构建器。在第二个构建器中，通过使用super关键字，明确调用了带有一个String参数的基础类构建器。</font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">例6 本例程演示建立和应用自己的异常类。</font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">
						<font color="#009900">///<br />//: Inheriting.java</font>
						<br />
						<font color="#009900">// Inheriting your own exceptions</font>
						<br />
						<font color="#0000ff">class</font> MyException <font color="#0000ff">extends</font> Exception {<br />&#160; <font color="#0000ff">public</font> MyException() {}<br />&#160; <font color="#0000ff">public</font> MyException(String msg) {<br />&#160;&#160;&#160; <font color="#0000ff">super</font>(msg);<br />&#160; }<br />}<br /><font color="#0000ff">public</font><font color="#0000ff">class</font> Inheriting {<br />&#160; <font color="#0000ff">public</font><font color="#0000ff">static</font><font color="#0000ff">void</font> f() <font color="#0000ff">throws</font> MyException {<br />&#160;&#160;&#160; System.out.println(<br />&#160;&#160;&#160;&#160;&#160; <font color="#004488">"Throwing MyException from f()"</font>);<br />&#160;&#160;&#160; <font color="#0000ff">throw</font><font color="#0000ff">new</font> MyException();<br />&#160; }<br />&#160; <font color="#0000ff">public</font><font color="#0000ff">static</font><font color="#0000ff">void</font> g() <font color="#0000ff">throws</font> MyException {<br />&#160;&#160;&#160; System.out.println(<br />&#160;&#160;&#160;&#160;&#160; <font color="#004488">"Throwing MyException from g()"</font>);<br />&#160;&#160;&#160; <font color="#0000ff">throw</font><font color="#0000ff">new</font> MyException(<font color="#004488">"Originated in g()"</font>);<br />&#160; }<br />&#160; <font color="#0000ff">public</font><font color="#0000ff">static</font><font color="#0000ff">void</font> main(String[] args) {<br />&#160;&#160;&#160; <font color="#0000ff">try</font> {<br />&#160;&#160;&#160;&#160;&#160; f();<br />&#160;&#160;&#160; } <font color="#0000ff">catch</font>(MyException e) {<br />&#160;&#160;&#160;&#160;&#160; e.printStackTrace();<br />&#160;&#160;&#160; }<br />&#160;&#160;&#160; <font color="#0000ff">try</font> {<br />&#160;&#160;&#160;&#160;&#160; g();<br />&#160;&#160;&#160; } <font color="#0000ff">catch</font>(MyException e) {<br />&#160;&#160;&#160;&#160;&#160; e.printStackTrace();<br />&#160;&#160;&#160; }<br />&#160; }<br />}<br />///&#160; </font>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">输出结果：<br />Throwing MyException from f()<br />MyException<br />at Inheriting.f(Inheriting.java:14)<br />at Inheriting.main(Inheriting.java:22)<br />Throwing MyException from g()<br />MyException: Originated in g()<br />at Inheriting.g(Inheriting.java:18)<br />at Inheriting.main(Inheriting.java:27)</font>
		</p>
		<font size="4">创建自己的异常时，还可以采取更多的操作。我们可添加额外的构建器及成员： </font>
		<p style="LINE-HEIGHT: 150%">
				<font size="4">class MyException2 extends Exception {<br />&#160; public MyException2() {}<br />&#160; public MyException2(String msg) {<br />&#160;&#160;&#160; super(msg);<br />&#160; }<br />&#160; public MyException2(String msg, int x) {<br />&#160;&#160;&#160; super(msg);<br />&#160;&#160;&#160; i = x;<br />&#160; }<br />&#160; public int val() { return i; }<br />&#160; private int i;<br />}</font>
		</p>
		<p>
				<font size="4">本章小结：</font>
		</p>
		<ol>
				<li>
						<font size="4">应用异常控制机制进行异常处理的格式是<br />try{要监控的代码}&#160;<br />catch(XXXException e) {异常处理代码}&#160;<br />finally {必须执行的代码}&#160; </font>
				</li>
				<li>
						<font size="4">不知道有什么异常类好用时可查阅相关包中有哪些XXXException.class文件。而用Exception可捕获任何异常。&#160; </font>
				</li>
				<li>
						<font size="4">在方法声明中使用了throws关键字的必须进行异常控制，否则会报编译错误。&#160; </font>
				</li>
				<li>
						<font size="4">也可以创建自己的异常类。</font>
				</li>
		</ol>
 <img src ="http://www.blogjava.net/onejavaer/aggbug/101649.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/onejavaer/" target="_blank">暗夜精灵</a> 2007-03-03 18:14 <a href="http://www.blogjava.net/onejavaer/articles/101649.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java.util.Properties类</title><link>http://www.blogjava.net/onejavaer/articles/101628.html</link><dc:creator>暗夜精灵</dc:creator><author>暗夜精灵</author><pubDate>Sat, 03 Mar 2007 08:18:00 GMT</pubDate><guid>http://www.blogjava.net/onejavaer/articles/101628.html</guid><wfw:comment>http://www.blogjava.net/onejavaer/comments/101628.html</wfw:comment><comments>http://www.blogjava.net/onejavaer/articles/101628.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/onejavaer/comments/commentRss/101628.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/onejavaer/services/trackbacks/101628.html</trackback:ping><description><![CDATA[		<p>Properties 类已不是新东西了，它在 Java 编程的早期就有了，并且几乎没有什么变化。J2SE 的 Tiger 版本增强了这个类，不仅可以用它在单独一行中指定用等号分隔的多个键-值对，还可以用XML 文件装载和保存这些键-值对。在 驯服 Tiger的这一期文章中，John Zukowski 展示了如何驾驭这匹新一代的&#8220;役马&#8221;。请在本文对应的讨论论坛上与作者及其他读者分享您对本文的想法（您也可以单击文章顶部或底部的 讨论来访问该论坛）。 </p>
		<p>&#160;&#160;&#160;&#160;&#160; J2SE 1.5 以前的版本要求直接使用 XML 解析器来装载配置文件并存储设置。虽然这并非是一件困难的事情，并且解析器是平台的标准部分，但是额外的工作总是有点让人烦。最近更新的 java.util.Properties 类现在提供了一种为程序装载和存储设置的更容易的方法： loadFromXML(InputStream is) 和 storeToXML(OutputStream os, String comment) 方法。 </p>
		<p>Properties 基本知识<br />如果不熟悉 java.util.Properties 类，那么现在告诉您它是用来在一个文件中存储键-值对的，其中键和值是用等号分隔的，如清单 1 所示。 </p>
		<p>清单 1. 一组属性示例</p>
		<p>foo=bar<br />fu=baz</p>
		<p>&#160;</p>
		<p>
				<br />将清单 1 装载到 Properties 对象中后，您就可以找到两个键（ foo 和 fu ）和两个值（ foo 的 bar 和 fu 的 baz ）了。这个类支持带 \u 的嵌入 Unicode 字符串，但是这里重要的是每一项内容都当作 String 。 </p>
		<p>清单 2 显示了如何装载属性文件并列出它当前的一组键和值。只需传递这个文件的 InputStream 给 load() 方法，就会将每一个键-值对添加到 Properties 实例中。然后用 list() 列出所有属性或者用 getProperty() 获取单独的属性。 </p>
		<p>清单 2. 装载属性</p>
		<p>import java.util.*;<br />import java.io.*;</p>
		<p>public class LoadSample {<br />&#160; public static void main(String args[]) throws Exception {<br />&#160;&#160;&#160; Properties prop = new Properties();<br />&#160;&#160;&#160; FileInputStream fis = <br />&#160;&#160;&#160;&#160;&#160; new FileInputStream("sample.properties");<br />&#160;&#160;&#160; prop.load(fis);<br />&#160;&#160;&#160; prop.list(System.out);<br />&#160;&#160;&#160; System.out.println("\nThe foo property: " +<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; prop.getProperty("foo"));<br />&#160; }<br />}</p>
		<p>&#160;</p>
		<p>
				<br />运行 LoadSample 程序生成如清单 3 所示的输出。注意 list() 方法的输出中键-值对的顺序与它们在输入文件中的顺序不一样。 Properties 类在一个散列表（hashtable，事实上是一个 Hashtable 子类）中储存一组键-值对，所以不能保证顺序。 </p>
		<p>清单 3. LoadSample 的输出</p>
		<p>-- listing properties --<br />fu=baz<br />foo=bar</p>
		<p>The foo property: bar</p>
		<p>&#160;</p>
		<p>
				<br />XML 属性文件<br />这里没有什么新内容。 Properties 类总是这样工作的。不过，新的地方是从一个 XML 文件中装载一组属性。它的 DTD 如清单 4 所示。 </p>
		<p>清单 4. 属性 DTD</p>
		<p>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;!-- DTD for properties --&gt;<br />&lt;!ELEMENT properties ( comment?, entry* ) &gt;<br />&lt;!ATTLIST properties version CDATA #FIXED "1.0"&gt;<br />&lt;!ELEMENT comment (#PCDATA) &gt;<br />&lt;!ELEMENT entry (#PCDATA) &gt;<br />&lt;!ATTLIST entry key CDATA #REQUIRED&gt;</p>
		<p>&#160;</p>
		<p>
				<br />如果不想细读 XML DTD，那么可以告诉您它其实就是说在外围 &lt;properties&gt; 标签中包装的是一个 &lt;comment&gt; 标签，后面是任意数量的 &lt;entry&gt; 标签。对每一个 &lt;entry&gt; 标签，有一个键属性，输入的内容就是它的值。清单 5 显示了 清单 1中的属性文件的 XML 版本是什么样子的。 </p>
		<p>清单 5. XML 版本的属性文件</p>
		<p>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;!DOCTYPE properties SYSTEM "<a href="http://java.sun.com/dtd/properties.dtd">http://java.sun.com/dtd/properties.dtd</a>"&gt;<br />&lt;properties&gt;<br />&lt;comment&gt;Hi&lt;/comment&gt;<br />&lt;entry key="foo"&gt;bar&lt;/entry&gt;<br />&lt;entry key="fu"&gt;baz&lt;/entry&gt;<br />&lt;/properties&gt;</p>
		<p>&#160;</p>
		<p>
				<br />如果清单 6 所示，读取 XML 版本的 Properties 文件与读取老格式的文件没什么不同。 </p>
		<p>清单 6. 读取 XML Properties 文件</p>
		<p>import java.util.*;<br />import java.io.*;</p>
		<p>public class LoadSampleXML {<br />&#160; public static void main(String args[]) throws Exception {<br />&#160;&#160;&#160; Properties prop = new Properties();<br />&#160;&#160;&#160; FileInputStream fis =<br />&#160;&#160;&#160;&#160;&#160; new FileInputStream("sampleprops.xml");<br />&#160;&#160;&#160; prop.loadFromXML(fis);<br />&#160;&#160;&#160; prop.list(System.out);<br />&#160;&#160;&#160; System.out.println("\nThe foo property: " +<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; prop.getProperty("foo"));<br />&#160; }<br />}</p>
		<p>&#160;</p>
		<p>
				<br />关于资源绑定的说明<br />虽然 java.util.Properties 类现在除了支持键-值对，还支持属性文件作为 XML 文件，不幸的是，没有内置的选项可以将 ResourceBundle 作为一个 XML 文件处理。是的， PropertyResourceBundle 不使用 Properties 对象来装载绑定，不过装载方法的使用是硬编码到类中的，而不使用较新的 loadFromXML() 方法。 </p>
		<p>
				<br />运行清单 6 中的程序产生与原来的程序相同的输出，如 清单 2所示。 </p>
		<p>保存 XML 属性<br />新的 Properties 还有一个功能是将属性存储到 XML 格式的文件中。虽然 store() 方法仍然会创建一个类似 清单 1 所示的文件，但是现在可以用新的 storeToXML() 方法创建如 清单 5 所示的文件。只要传递一个 OutputStream 和一个用于注释的 String 就可以了。清单 7 展示了新的 storeToXML() 方法。 </p>
		<p>清单 7. 将 Properties 存储为 XML 文件</p>
		<p>import java.util.*;<br />import java.io.*;</p>
		<p>public class StoreXML {<br />&#160; public static void main(String args[]) throws Exception {<br />&#160;&#160;&#160; Properties prop = new Properties();<br />&#160;&#160;&#160; prop.setProperty("one-two", "buckle my shoe");<br />&#160;&#160;&#160; prop.setProperty("three-four", "shut the door");<br />&#160;&#160;&#160; prop.setProperty("five-six", "pick up sticks");<br />&#160;&#160;&#160; prop.setProperty("seven-eight", "lay them straight");<br />&#160;&#160;&#160; prop.setProperty("nine-ten", "a big, fat hen");<br />&#160;&#160;&#160; FileOutputStream fos =<br />&#160;&#160;&#160;&#160;&#160; new FileOutputStream("rhyme.xml");<br />&#160;&#160;&#160; prop.storeToXML(fos, "Rhyme");<br />&#160;&#160;&#160; fos.close();<br />&#160; }<br />}</p>
		<p>&#160;</p>
		<p>
				<br />运行清单 7 中的程序产生的输出如清单 8 所示。</p>
		<p>清单 8. 存储的 XML 文件</p>
		<p>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;!DOCTYPE properties SYSTEM "<a href="http://java.sun.com/dtd/properties.dtd">http://java.sun.com/dtd/properties.dtd</a>"&gt;<br />&lt;properties&gt;<br />&lt;comment&gt;Rhyme&lt;/comment&gt;<br />&lt;entry key="seven-eight"&gt;lay them straight&lt;/entry&gt;<br />&lt;entry key="five-six"&gt;pick up sticks&lt;/entry&gt;<br />&lt;entry key="nine-ten"&gt;a big, fat hen&lt;/entry&gt;<br />&lt;entry key="three-four"&gt;shut the door&lt;/entry&gt;<br />&lt;entry key="one-two"&gt;buckle my shoe&lt;/entry&gt;<br />&lt;/properties&gt;</p>
		<p>&#160;</p>
		<p>
				<br />结束语<br />使用 XML 文件还是使用老式的 a=b 类型的文件完全取决于您自己。老式文件从内存的角度看肯定是轻量级的。不过，由于 XML 的普遍使用，人们会期望 XML 格式流行起来，因为它已经被广泛使用了，只不过没有用到 Properties 对象。选择完全在您。分析软件包 private XMLUtils 类的源代码以获得关于所使用的 XML 解析的更多信息。</p>
		<p>&#160;</p>
		<p>&#160;</p>
		<p>&#160;</p>
		<p>PTest.java<br />import java.io.FileInputStream;<br />import java.io.IOException;<br />import java.io.InputStream;<br />import java.util.Properties;<br />/**<br />&#160;* 实现properties文件的读取<br />&#160;* @author bbflyerwww<br />&#160;* @date 2006-08-02<br />&#160;*/<br />public class PTest {<br />&#160;&#160;&#160; public static void main(String[] args) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; try {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; long start = System.currentTimeMillis();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; InputStream is = new FileInputStream("conf.properties");<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Properties p = new Properties();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; p.load(is);<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; is.close();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println("SIZE : " + p.size());<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println("homepage : " + p.getProperty("homepage"));<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println("author : " + p.getProperty("author"));<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println("school : " + p.getProperty("school"));<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println("date : " + p.getProperty("date"));<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; long end = System.currentTimeMillis(); <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println("Cost : " + (end - start));<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } catch (IOException ioe) {<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ioe.printStackTrace();<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160; }<br />}</p>
 <img src ="http://www.blogjava.net/onejavaer/aggbug/101628.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/onejavaer/" target="_blank">暗夜精灵</a> 2007-03-03 16:18 <a href="http://www.blogjava.net/onejavaer/articles/101628.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate二级缓存</title><link>http://www.blogjava.net/onejavaer/articles/101587.html</link><dc:creator>暗夜精灵</dc:creator><author>暗夜精灵</author><pubDate>Sat, 03 Mar 2007 02:16:00 GMT</pubDate><guid>http://www.blogjava.net/onejavaer/articles/101587.html</guid><wfw:comment>http://www.blogjava.net/onejavaer/comments/101587.html</wfw:comment><comments>http://www.blogjava.net/onejavaer/articles/101587.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/onejavaer/comments/commentRss/101587.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/onejavaer/services/trackbacks/101587.html</trackback:ping><description><![CDATA[1。hibernate一级缓存为session维护的。二级缓存为sessionfactory维护。<br />2。一级缓存持久化的是OID唯一的对象，所以不会存在并发访问的问题。二级缓存存在并发访问问题。所以二级缓存根据访问和修改的频率以及是否集群分为4个等级。总体上说，一级缓存保存在内存中，二级可以保存在内存或硬盘中，为散列保存。<br />3。一级缓存为必须的，二级为可插入的缓存，其功能为第三方提供。<br />4。二级缓存保存的为很少修改的对象，因为会存在并发访问问题，所以尽量减少对兑现的修改操作，减少写入的脏数据。<br />5。一级缓存为session全程存在，二级缓存可以设定过期时间。<br />6。需要在hibernate.cfg.xml中设定使用二级缓存。还需要在指定的映射文件中，设定需要被缓存的实体对象。<br />7。假如映射文件对象所对应的属性为set类型，还需要再次指明被缓存，这样只会使set类型的属性也就是getItems()取出的被缓存。而其所对应的实体并未被缓存，如需要，需要在xml中指明。 <img src ="http://www.blogjava.net/onejavaer/aggbug/101587.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/onejavaer/" target="_blank">暗夜精灵</a> 2007-03-03 10:16 <a href="http://www.blogjava.net/onejavaer/articles/101587.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java性能的优化</title><link>http://www.blogjava.net/onejavaer/articles/101545.html</link><dc:creator>暗夜精灵</dc:creator><author>暗夜精灵</author><pubDate>Fri, 02 Mar 2007 13:46:00 GMT</pubDate><guid>http://www.blogjava.net/onejavaer/articles/101545.html</guid><wfw:comment>http://www.blogjava.net/onejavaer/comments/101545.html</wfw:comment><comments>http://www.blogjava.net/onejavaer/articles/101545.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/onejavaer/comments/commentRss/101545.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/onejavaer/services/trackbacks/101545.html</trackback:ping><description><![CDATA[		<p style="FONT-WEIGHT: bold; FONT-SIZE: 26px">Java性能的优化（上）</p>
		<hr style="COLOR: #000000; HEIGHT: 1px" />
		<p>
		</p>
		<div style="FONT-SIZE: 12px">黄伟峰 <br /><br /><br /><br /><br />Java在九十年代中期出现以后，在赢得赞叹的同时，也引来了一些批评。赢得的赞叹主要是Java的跨平台的操作性，即所谓的&#8221;Write Once,Run Anywhere&#8221;.但由于Java的性能和运行效率同C相比，仍然有很大的差距，从而引来了很多的批评。 <br />对于服务器端的应用程序，由于不大涉及到界面设计和程序的频繁重启，Java的性能问题看似不大明显，从而一些Java的技术，如JSP,Se rvlet,EJB等在服务器端编程方面得到了很大的应用，但实际上，Java的性能问题在服务器端依然存在。下面我将分四个方面来讨论Java的性能和执行效率以及提高J ava性能的一些方法。 <br />一．关于性能的基本知识 <br />1．性能的定义 <br />在我们讨论怎样提高Java的性能之前，我们需要明白&#8220;性能&#8220;的真正含义。我们一般定义如下五个方面作为评判性能的标准。 <br />1） 运算的性能----哪一个算法的执行性能最好 <br />2） 内存的分配----程序需要分配多少内存，运行时的效率和性能最高。 <br />3） 启动的时间----程序启动需要多少时间。 <br />4） 程序的可伸缩性-----程序在用户负载过重的情况下的表现。 <br />5） 性能的认识------用户怎样才能认识到程序的性能。 <br />对于不同的应用程序，对性能的要求也不同。例如，大部分的应用程序在启动时需要较长的时间，从而对启动时间的要求有所降低；服务器端的应用程序通常都分配有较大的内存空间，所以对内存的要求也有所降低。但是，这并不是所这两方面的性能可以被忽略。其次，算法的性能对于那些把商务逻辑运用到事务性操作的应用程序来讲非常重要。总的来讲，对应用程序的要求将决定对各个性能的优先级。 <br />2．怎样才能提高JAVA的性能 <br />提高JAVA的性能，一般考虑如下的四个主要方面： <br />（1） 程序设计的方法和模式 <br />一个良好的设计能提高程序的性能，这一点不仅适用于JAVA，也适用也任何的编程语言。因为它充分利用了各种资源，如内存，CPU,高速缓存，对象缓冲池及多线程，从而设计出高性能和可伸缩性强的系统。 <br />当然，为了提高程序的性能而改变原来的设计是比较困难的，但是，程序性能的重要性常常要高于设计上带来的变化。因此，在编程开始之前就应该有一个好的设计模型和方法。 <br />（2） JAVA布署的环境。 <br />JAVA布署的环境就是指用来解释和执行JAVA字节码的技术，一般有如下五种。即解释指令技术(Interpreter Technology)，及时编译的技术(Just In Time Compilier Technology), 适应性优化技术（Adaptive Optimization Technology）, 动态优化，提前编译为机器码的技术（Dynamic Optimization,Ahead Of Time Technology）和编译为机器码的技术（Translator Technology）. <br />这些技术一般都通过优化线程模型，调整堆和栈的大小来优化JAVA的性能。在考虑提高JAVA的性能时，首先要找到影响JAVA性能的瓶颈（B ottleNecks），在确认了设计的合理性后，应该调整JAVA布署的环境，通过改变一些参数来提高JAVA应用程序的性能。具体内容见第二节。 <br />（3） JAVA应用程序的实现 <br />当讨论应用程序的性能问题时，大多数的程序员都会考虑程序的代码，这当然是对的，当更重要的是要找到影响程序性能的瓶颈代码。为了找到这些瓶颈代码，我们一般会使用一些辅助的工具，如J probe,Optimizit,Vtune以及一些分析的工具如TowerJ Performance等。这些辅助的工具能跟踪应用程序中执行每个函数或方法所消耗掉的时间，从而改善程序的性能。 <br />(4) 硬件和操作系统 <br />为了提高JAVA应用程序的性能，而采用跟快的CPU和更多的内存，并认为这是提高程序性能的唯一方法，但事实并非如此。实践经验和事实证明，只有遭到了应用程序性能的瓶颈，从而采取适当得方法，如设计模式，布署的环境，操作系统的调整，才是最有效的。 <br />3．程序中通常的性能瓶颈。 <br />所有的应用程序都存在性能瓶颈，为了提高应用程序的性能，就要尽可能的减少程序的瓶颈。以下是在JAVA程序中经常存在的性能瓶颈。 <br /><br /><br />了解了这些瓶颈后，就可以有针对性的减少这些瓶颈，从而提高JAVA应用程序的性能 <br />4. 提高JAVA程序性能的步骤 <br />为了提高JAVA程序的性能，需要遵循如下的六个步骤。 <br />a) 明确对性能的具体要求 <br />在实施一个项目之前，必须要明确该项目对于程序性能的具体要求，如：这个应用程序要支持5000个并发的用户，并且响应时间要在5秒钟之内。但同时也要明白对于性能的要求不应该同对程序的其他要求冲突。 <br />b) 了解当前程序的性能 <br />你应该了解你的应用程序的性能同项目所要求性能之间的差距。通常的指标是单位时间内的处理数和响应时间，有时还会比较CPU和内存的利用率。 <br />c) 找到程序的性能瓶颈 <br />为了发现程序中的性能瓶颈，通常会使用一些分析工具，如：TowerJ Application Performance Analyzer或VTune来察看和分析程序堆栈中各个元素的消耗时间，从而正确的找到并改正引起性能降低的瓶颈代码，从而提高程序的性能。这些工具还能发现诸如过多的异常处理，垃圾回收等潜在的问题。 <br />d) 采取适当的措施来提高性能 <br />找到了引起程序性能降低的瓶颈代码后，我们就可以用前面介绍过的提高性能的四个方面，即设计模式，JAVA代码的实现，布署JAVA的环境和操作系统来提高应用程序的性能。具体内容将在下面的内容中作详细说明。 <br />e) 只进行某一方面的修改来提高性能 <br />一次只改变可能引起性能降低的某一方面，然后观察程序的性能是否有所提高，而不应该一次改变多个方面，因为这样你将不知道到底哪个方面的改变提高了程序的性能，哪个方面没有，即不能知道程序瓶颈在哪。 <br />f) 返回到步骤c,继续作类似的工作，一直达到要求的性能为止。 <br /><br />二． JAVA布署的环境和编译技术 <br />　开发JAVA应用程序时，首先把JAVA的源程序编译为与平台无关的字节码。这些字节码就可以被各种基于JVM的技术所执行。这些技术主要分为两个大类。即基于解释的技术和基于提前编译为本地码的技术。其示意图如下： <br /><br /><br />具体可分为如下的五类：　　 <br />a) 解释指令技术 <br />其结构图和执行过程如下： <br /><br /><br />　JAVA的编译器首先把JAVA源文件编译为字节码。这些字节码对于JAVA虚拟机(JVM)来讲就是机器的指令码。然后，JAVA的解释器不断的循环取出字节码进行解释并执行。 <br />　这样做的优点是可以实现JAVA语言的跨平台，同时生成的字节码也比较紧凑。JAVA的一些优点，如安全性，动态性都得保持；但缺点是省生成的字节码没有经过什么优化，同全部编译好的本地码相比，速度比较慢。 <br />b) 及时编译技术（Just In Time） <br />　　及时编译技术是为了解决指令解释技术效率比较低，速度比较慢的情况下提出的，其结构图如下所示。 <br /><br /><br />其主要变化是在JAVA程序执行之前，又JIT编译器把JAVA的字节码编译为机器码。从而在程序运行时直接执行机器码，而不用对字节码进行解释。同时对代码也进行了部分的优化。 <br />这样做的优点是大大提高了JAVA程序的性能。同时，由于编译的结果并不在程序运行间保存，因此也节约了存储空间了加载程序的时间；缺点是由于J IT编译器对所有的代码都想优化，因此也浪费了很多的时间。 <br />IBM和SUN公司都提供了相关的JIT产品。 <br />c) 适应性优化技术（Adaptive Optimization Technology） <br />同JIT技术相比，适应性优化技术并不对所有的字节码进行优化。它会跟踪程序运行的成个过程，从而发现需要优化的代码，对代码进行动态的优化。对优化的代码，采取8 0/20的策略。从理论上讲，程序运行的时间越长，代码就越优化。其结构图如下： <br /><br /><br />其优点是适应性优化技术充分利用了程序执行时的信息，发行程序的性能瓶颈，从而提高程序的性能；其缺点是在进行优化时可能会选择不当，发而降低了程序的性能。 <br />其主要产品又IBM,SUN的HotSpot. <br />d) 动态优化，提前编译为机器码的技术（Dynamic Optimization,Ahead Of Time） <br />动态优化技术充分利用了JAVA源码编译，字节码编译，动态编译和静态编译的技术。其输入时JAVA的原码或字节码，而输出是经过高度优化的可执行代码和个来动态库的混合( Window中是DLL文件，UNIX中是共享库.a .so文件)。其结构如下： <br /><br /><br />其优点是能大大提高程序的性能；缺点是破坏了JAVA的可移植性，也对JAVA的安全带来了一定的隐患。 <br /></div>
		<div style="FONT-SIZE: 12px">
				<p style="FONT-WEIGHT: bold; FONT-SIZE: 26px">Java性能的优化（下）&#160;&#160;</p>
				<hr style="COLOR: #000000; HEIGHT: 1px" />
				<p>
				</p>
				<div style="FONT-SIZE: 12px">黄伟峰 <br />&#160;<br /><br /><br /><br />三．优化JAVA程序设计和编码，提高JAVA程序性能的一些方法。 <br />通过使用一些前面介绍过的辅助性工具来找到程序中的瓶颈，然后就可以对瓶颈部分的代码进行优化。一般有两种方案：即优化代码或更改设计方法。我们一般会选择后者，因为不去调用以下代码要比调用一些优化的代码更能提高程序的性能。而一个设计良好的程序能够精简代码，从而提高性能。 <br />下面将提供一些在JAVA程序的设计和编码中，为了能够提高JAVA程序的性能，而经常采用的一些方法和技巧。 <br />1．对象的生成和大小的调整。 <br />JAVA程序设计中一个普遍的问题就是没有好好的利用JAVA语言本身提供的函数，从而常常会生成大量的对象（或实例）。由于系统不仅要花时间生成对象，以后可能还需花时间对这些对象进行垃圾回收和处理。因此，生成过多的对象将会给程序的性能带来很大的影响。 <br />例1：关于String ,StringBuffer，+和append <br />JAVA语言提供了对于String类型变量的操作。但如果使用不当，会给程序的性能带来影响。如下面的语句： <br />String name=new String(&#8220;HuangWeiFeng&#8221;); <br />System.out.println(name+&#8221;is my name&#8221;); <br />看似已经很精简了，其实并非如此。为了生成二进制的代码，要进行如下的步骤和操作。 <br />（1） 生成新的字符串 new String(STR_1); <br />（2） 复制该字符串。 <br />（3） 加载字符串常量&#8221;HuangWeiFeng&#8221;(STR_2); <br />（4） 调用字符串的构架器（Constructor）; <br />（5） 保存该字符串到数组中（从位置0开始） <br />（6） 从java.io.PrintStream类中得到静态的out变量 <br />（7） 生成新的字符串缓冲变量new StringBuffer(STR_BUF_1); <br />（8） 复制该字符串缓冲变量 <br />（9） 调用字符串缓冲的构架器（Constructor）; <br />（10） 保存该字符串缓冲到数组中（从位置1开始） <br />（11） 以STR_1为参数，调用字符串缓冲(StringBuffer)类中的append方法。 <br />（12） 加载字符串常量&#8221;is my name&#8221;(STR_3); <br />（13） 以STR_3为参数，调用字符串缓冲(StringBuffer)类中的append方法。 <br />（14） 对于STR_BUF_1执行toString命令。 <br />（15） 调用out变量中的println方法，输出结果。 <br />由此可以看出，这两行简单的代码，就生成了STR_1,STR_2,STR_3,STR_4和STR_BUF_1五个对象变量。这些生成的类的实例一般都存放在堆中。堆要对所有类的超类，类的实例进行初始化，同时还要调用类极其每个超类的构架器。而这些操作都是非常消耗系统资源的。因此，对对象的生成进行限制，是完全有必要的。 <br />经修改，上面的代码可以用如下的代码来替换。 <br />StringBuffer name=new StringBuffer(&#8220;HuangWeiFeng&#8221;); <br />System.out.println(name.append(&#8220;is my name.&#8221;).toString()); <br />系统将进行如下的操作。 <br />(1) 生成新的字符串缓冲变量new StringBuffer(STR_BUF_1); <br />(2) 复制该字符串缓冲变量 <br />(3) 加载字符串常量&#8221;HuangWeiFeng&#8221;(STR_1); <br />(4) 调用字符串缓冲的构架器（Constructor）; <br />(5) 保存该字符串缓冲到数组中（从位置1开始） <br />(6) 从java.io.PrintStream类中得到静态的out变量 <br />(7) 加载STR_BUF_1; <br />(8) 加载字符串常量&#8221;is my name&#8221;(STR_2); <br />(9) 以STR_2为参数，调用字符串缓冲(StringBuffer)实例中的append方法。 <br />(10) 对于STR_BUF_1执行toString命令。(STR_3) <br />(11)调用out变量中的println方法，输出结果。 <br />由此可以看出，经过改进后的代码只生成了四个对象变量：STR_1,STR_2,STR_3和STR_BUF_1.你可能觉得少生成一个对象不会对程序的性能有很大的提高。但下面的代码段2 的执行速度将是代码段1的2倍。因为代码段1生成了八个对象，而代码段2只生成了四个对象。 <br />代码段1： <br />String name= new StringBuffer(&#8220;HuangWeiFeng&#8221;); <br />name+=&#8221;is my&#8221;; <br />name+=&#8221;name&#8221;; <br />代码段2： <br />StringBuffer name=new StringBuffer(&#8220;HuangWeiFeng&#8221;); <br />name.append(&#8220;is my&#8221;); <br />name.append(&#8220;name.&#8221;).toString(); <br />因此，充分的利用JAVA提供的库函数来优化程序，对提高JAVA程序的性能时非常重要的.其注意点主要有如下几方面； <br />（1） 尽可能的使用静态变量（Static Class Variables） <br />如果类中的变量不会随他的实例而变化，就可以定义为静态变量，从而使他所有的实例都共享这个变量。 <br />例： <br />public class foo <br />{ <br />SomeObject so=new SomeObject(); <br />} <br />就可以定义为： <br />public class foo <br />{ <br />static SomeObject so=new SomeObject(); <br />} <br />（2） 不要对已生成的对象作过多的改变。 <br />对于一些类(如：String类)来讲，宁愿在重新生成一个新的对象实例，而不应该修改已经生成的对象实例。 <br />例： <br />String name=&#8221;Huang&#8221;; <br />name=&#8221;Wei&#8221;; <br />name=&#8221;Feng&#8221;; <br />上述代码生成了三个String类型的对象实例。而前两个马上就需要系统进行垃圾回收处理。如果要对字符串进行连接的操作，性能将得更差。因为系统将不得为此生成更多得临时变量。如上例1 所示。 <br />（3） 生成对象时，要分配给它合理的空间和大小 <br />JAVA中的很多类都有它的默认的空间分配大小。对于StringBuffer类来讲，默认的分配空间大小是16个字符。如果在程序中使用StringBu ffer的空间大小不是16个字符，那么就必须进行正确的初始化。 <br />（4） 避免生成不太使用或生命周期短的对象或变量。 <br />对于这种情况，因该定义一个对象缓冲池。以为管理一个对象缓冲池的开销要比频繁的生成和回收对象的开销小的多。 <br />（5） 只在对象作用范围内进行初始化。 <br />JAVA允许在代码的任何地方定义和初始化对象。这样，就可以只在对象作用的范围内进行初始化。从而节约系统的开销。 <br />例： <br />SomeObject so=new SomeObject(); <br />If(x==1) then <br />{ <br />Foo=so.getXX(); <br />} <br />可以修改为： <br />if(x==1) then <br />{ <br />SomeObject so=new SomeObject(); <br />Foo=so.getXX(); <br />} <br />2．异常(Exceptions) <br />JAVA语言中提供了try/catch来发方便用户捕捉异常，进行异常的处理。但是如果使用不当，也会给JAVA程序的性能带来影响。因此，要注意以下两点。 <br />(1) 避免对应用程序的逻辑使用try/catch <br />如果可以用if,while等逻辑语句来处理，那么就尽可能的不用try/catch语句 <br />(2) 重用异常 <br />在必须要进行异常的处理时，要尽可能的重用已经存在的异常对象。以为在异常的处理中，生成一个异常对象要消耗掉大部分的时间。 <br />3. 线程(Threading) <br />一个高性能的应用程序中一般都会用到线程。因为线程能充分利用系统的资源。在其他线程因为等待硬盘或网络读写而 时，程序能继续处理和运行。但是对线程运用不当，也会影响程序的性能。 <br />例2：正确使用Vector类 <br />Vector主要用来保存各种类型的对象（包括相同类型和不同类型的对象）。但是在一些情况下使用会给程序带来性能上的影响。这主要是由V ector类的两个特点所决定的。第一，Vector提供了线程的安全保护功能。即使Vector类中的许多方法同步。但是如果你已经确认你的应用程序是单线程，这些方法的同步就完全不必要了。第二，在V ector查找存储的各种对象时，常常要花很多的时间进行类型的匹配。而当这些对象都是同一类型时，这些匹配就完全不必要了。因此，有必要设计一个单线程的，保存特定类型对象的类或集合来替代V ector类.用来替换的程序如下（StringVector.java）： <br />public class StringVector <br />{ <br />private String [] data; <br />private int count; <br />public StringVector() { this(10); // default size is 10 } <br />public StringVector(int initialSize) <br />{ <br />data = new String[initialSize]; <br />} <br />public void add(String str) <br />{ <br />// ignore null strings <br />if(str == null) { return; } <br />ensureCapacity(count + 1); <br />data[count++] = str; <br />} <br /><br />private void ensureCapacity(int minCapacity) <br />{ <br />int oldCapacity = data.length; <br />if (minCapacity &gt; oldCapacity) <br />{ <br />String oldData[] = data; <br />int newCapacity = oldCapacity * 2; <br />data = new String[newCapacity]; <br />System.arraycopy(oldData, 0, data, 0, count); <br />} <br />} <br />public void remove(String str) <br />{ <br />if(str == null) { return // ignore null str } <br />for(int i = 0; i &lt; count; i++) <br />{ <br />// check for a match <br />if(data[i].equals(str)) <br />{ <br />System.arraycopy(data,i+1,data,i,count-1); // copy data <br />// allow previously valid array element be gc'd <br />data[--count] = null; <br />return; <br />} <br />} <br />} <br />public final String getStringAt(int index) { <br />if(index &lt; 0) { return null; } <br />else if(index &gt; count) <br />{ <br />return null; // index is &gt; # strings <br />} <br />else { return data[index]; // index is good } <br />} <br />/* * * * * * * * * * * * * * * *StringVector.java * * * * * * * * * * * * * * * * */ <br />因此，代码： <br />Vector Strings=new Vector(); <br />Strings.add(&#8220;One&#8221;); <br />Strings.add(&#8220;Two&#8221;); <br />String Second=(String)Strings.elementAt(1); <br />可以用如下的代码替换： <br />StringVector Strings=new StringVector(); <br />Strings.add(&#8220;One&#8221;); <br />Strings.add(&#8220;Two&#8221;); <br />String Second=Strings.getStringAt(1); <br />这样就可以通过优化线程来提高JAVA程序的性能。用于测试的程序如下（TestCollection.java）: <br />import java.util.Vector; <br />public class TestCollection <br />{ <br />public static void main(String args []) <br />{ <br />TestCollection collect = new TestCollection(); <br />if(args.length == 0) <br />{ <br />System.out.println( <br />"Usage: java TestCollection [ vector | stringvector ]"); <br />System.exit(1); <br />} <br />if(args[0].equals("vector")) <br />{ <br />Vector store = new Vector(); <br />long start = System.currentTimeMillis(); <br />for(int i = 0; i &lt; 1000000; i++) <br />{ <br />store.addElement("string"); <br />} <br />long finish = System.currentTimeMillis(); <br />System.out.println((finish-start)); <br />start = System.currentTimeMillis(); <br />for(int i = 0; i &lt; 1000000; i++) <br />{ <br />String result = (String)store.elementAt(i); <br />} <br />finish = System.currentTimeMillis(); <br />System.out.println((finish-start)); <br />} <br />else if(args[0].equals("stringvector")) <br />{ <br />StringVector store = new StringVector(); <br />long start = System.currentTimeMillis(); <br />for(int i = 0; i &lt; 1000000; i++) { store.add("string"); } <br />long finish = System.currentTimeMillis(); <br />System.out.println((finish-start)); <br />start = System.currentTimeMillis(); <br />for(int i = 0; i &lt; 1000000; i++) { <br />String result = store.getStringAt(i); <br />} <br />finish = System.currentTimeMillis(); <br />System.out.println((finish-start)); <br />} <br />} <br />} <br />/* * * * * * * * * * * * * * * *TestCollection.java * * * * * * * * * * * * * * * * */ <br />测试的结果如下（假设标准的时间为１，越小性能越好）： <br /><br /><br />关于线程的操作，要注意如下几个方面。 <br />(1) 防止过多的同步 <br />如上所示，不必要的同步常常会造成程序性能的下降。因此，如果程序是单线程，则一定不要使用同步。 <br />(2) 同步方法而不要同步整个代码段 <br />　　　对某个方法或函数进行同步比对整个代码段进行同步的性能要好。 <br />(3) 对每个对象使用多&#8221;锁&#8221;的机制来增大并发。 <br />一般每个对象都只有一个&#8221;锁&#8221;，这就表明如果两个线程执行一个对象的两个不同的同步方法时，会发生&#8221;死锁&#8221;。即使这两个方法并不共享任何资源。为了避免这个问题，可以对一个对象实行&#8221;多锁&#8221;的机制。如下所示： <br />class foo <br />{ <br />private static int var1; <br />private static Object lock1=new Object(); <br />private static int var2; <br />private static Object lock2=new Object(); <br />public static void increment1() <br />{ <br />synchronized(lock1) <br />{ <br />var1++; <br />} <br />} <br />public static void increment2() <br />{ <br />synchronized(lock2) <br />{ <br />var2++; <br />} <br />} <br />} <br />4．输入和输出(I/O) <br />输入和输出包括很多方面，但涉及最多的是对硬盘，网络或数据库的读写操作。对于读写操作，又分为有缓存和没有缓存的；对于数据库的操作，又可以有多种类型的J DBC驱动器可以选择。但无论怎样，都会给程序的性能带来影响。因此，需要注意如下几点： <br />(1) 使用输入输出缓冲 <br />　　　尽可能的多使用缓存。但如果要经常对缓存进行刷新（flush）,则建议不要使用缓存。 <br />(2) 输出流(Output Stream)和Unicode字符串 <br />　　　当时用Output Stream和Unicode字符串时，Write类的开销比较大。因为它要实现Unicode到字节(byte)的转换.因此，如果可能的话,在使用Write类之前就实现转换或用O utputStream类代替Writer类来使用。 <br />(3) 当需序列化时使用transient <br />　　　当序列化一个类或对象时，对于那些原子类型（atomic）或可以重建的原素要表识为transient类型。这样就不用每一次都进行序列化。如果这些序列化的对象要在网络上传输，这一小小的改变对性能会有很大的提高。　　 <br />(4) 使用高速缓存（Cache） <br />　　　对于那些经常要使用而又不大变化的对象或数据，可以把它存储在高速缓存中。这样就可以提高访问的速度。这一点对于从数据库中返回的结果集尤其重要。 <br />(5) 使用速度快的JDBC驱动器（Driver） <br />　　　JAVA对访问数据库提供了四种方法。这其中有两种是JDBC驱动器。一种是用JAVA外包的本地驱动器；另一种是完全的JAVA驱动器。具体要使用哪一种得根据J AVA布署的环境和应用程序本身来定。 <br />5.一些其他的经验和技巧 <br />(1) 使用局部变量 <br />(2) 避免在同一个类中动过调用函数或方法(get或set)来设置或调用变量。 <br />(3) 避免在循环中生成同一个变量或调用同一个函数（参数变量也一样） <br />(4) 尽可能的使用static,final,private等关键字 <br />(5) 当复制大量数据时，使用System.arraycopy()命令。 <br /><br /></div>
				<p>
				</p>
				<hr style="COLOR: #000000; HEIGHT: 1px" />
		</div>
 <img src ="http://www.blogjava.net/onejavaer/aggbug/101545.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/onejavaer/" target="_blank">暗夜精灵</a> 2007-03-02 21:46 <a href="http://www.blogjava.net/onejavaer/articles/101545.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>equals() 和 hashCode() </title><link>http://www.blogjava.net/onejavaer/articles/101536.html</link><dc:creator>暗夜精灵</dc:creator><author>暗夜精灵</author><pubDate>Fri, 02 Mar 2007 11:41:00 GMT</pubDate><guid>http://www.blogjava.net/onejavaer/articles/101536.html</guid><wfw:comment>http://www.blogjava.net/onejavaer/comments/101536.html</wfw:comment><comments>http://www.blogjava.net/onejavaer/articles/101536.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/onejavaer/comments/commentRss/101536.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/onejavaer/services/trackbacks/101536.html</trackback:ping><description><![CDATA[		<p>&#160;我们知道，equals()函数是用来做比较的。java中的比较有两种：一种是内存地址的比较，一种是内容的比较。而比较个体也有两种：一种是简单类型（这类简单说来无所谓内存地址的比较或者内容比较的区别）；还有一种是对象的比较，本文中说的主要是后者</p>
		<p>在java中，（对象）内存地址的比较，是通过==完成的。比如&#160;</p>
		<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 95%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
				<div>
						<img id="_16_26_Open_Image" onclick="this.style.display='none'; document.getElementById('_16_26_Open_Text').style.display='none'; document.getElementById('_16_26_Closed_Image').style.display='inline'; document.getElementById('_16_26_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
						<img id="_16_26_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_16_26_Closed_Text').style.display='none'; document.getElementById('_16_26_Open_Image').style.display='inline'; document.getElementById('_16_26_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" />
						<span style="COLOR: #0000ff">if</span>
						<span style="COLOR: #000000">(obj1&#160;</span>
						<span style="COLOR: #000000">==</span>
						<span style="COLOR: #000000">&#160;obj2)</span>
						<span id="_16_26_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span>
						<span id="_16_26_Open_Text">
								<span style="COLOR: #000000">{<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;...<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
						</span>
				</div>
		</div>
		<p>这样的语句中，我们认为，如果obj1和obj2的内存地址相同，则返回true</p>
		<p>而equals()通常是比较内容的。这里说&#8220;通常&#8221; ，是因为在最根本的Object类中，equal()函数做的是地址的比较。而在其他几乎所有的类中，equals()都经过重载，进行内容的比较。</p>
		<p>而在说equals()的时候我们还涉及hashCode()是因为在有些应用中（比如，HashMap的key是对象），必须在重载equals()的同时重载hashCode()。<strong>因为java中默认(Object)的hashCode是根据对象的地址计算得到的。</strong></p>
		<p>我们通常不会注意到这个问题，因为我们通常所使用的<em>key</em>都是简单类型，或者是String, Long等一些特殊的对象（其特殊性请参看笔者在写java 浅拷贝和深拷贝时的讨论），这时候，这个问题被我们无意间绕过了</p>
		<p>有人已经概括了这种我们忽略了的情况：&#8220;如果你想将一个对象A放入另一个收集（集合）对象B里，或者使用这个对象A为查找一个元对象在收集对 象B里位置的钥匙（key），并支持是否容纳（isContains()），删除收集对象B里的元对象（remove()?）这样的操作，那么，equals()和hashCode()函数必须开发者自己定义。&#8221; （括号为笔者添加）</p>
		<p>为了便于理解，举一段程序为例：</p>
		<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 95%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
				<div>
						<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #0000ff">import</span>
						<span style="COLOR: #000000">&#160;java.util.</span>
						<span style="COLOR: #000000">*</span>
						<span style="COLOR: #000000">;<br /><img id="_39_646_Open_Image" onclick="this.style.display='none'; document.getElementById('_39_646_Open_Text').style.display='none'; document.getElementById('_39_646_Closed_Image').style.display='inline'; document.getElementById('_39_646_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="_39_646_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_39_646_Closed_Text').style.display='none'; document.getElementById('_39_646_Open_Image').style.display='inline'; document.getElementById('_39_646_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000">&#160;</span>
						<span style="COLOR: #0000ff">class</span>
						<span style="COLOR: #000000">&#160;Person</span>
						<span id="_39_646_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span>
						<span id="_39_646_Open_Text">
								<span style="COLOR: #000000">{<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" /><br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" /></span>
								<span style="COLOR: #0000ff">int</span>
								<span style="COLOR: #000000">&#160;id;<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />String&#160;name;<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" /><br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" /></span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000">define&#160;getter&#160;and&#160;setter&#160;here,&#160;omited</span>
								<span style="COLOR: #008000">
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />
								</span>
								<span style="COLOR: #000000">
										<br />
										<img id="_139_180_Open_Image" onclick="this.style.display='none'; document.getElementById('_139_180_Open_Text').style.display='none'; document.getElementById('_139_180_Closed_Image').style.display='inline'; document.getElementById('_139_180_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" />
										<img id="_139_180_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_139_180_Closed_Text').style.display='none'; document.getElementById('_139_180_Open_Image').style.display='inline'; document.getElementById('_139_180_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align="top" />
								</span>
								<span style="COLOR: #0000ff">public</span>
								<span style="COLOR: #000000">&#160;Person(</span>
								<span style="COLOR: #0000ff">int</span>
								<span style="COLOR: #000000">&#160;id,&#160;String&#160;name)</span>
								<span id="_139_180_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span>
								<span id="_139_180_Open_Text">
										<span style="COLOR: #000000">{<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;</span>
										<span style="COLOR: #0000ff">this</span>
										<span style="COLOR: #000000">.id&#160;</span>
										<span style="COLOR: #000000">=</span>
										<span style="COLOR: #000000">&#160;id;<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;</span>
										<span style="COLOR: #0000ff">this</span>
										<span style="COLOR: #000000">.name&#160;</span>
										<span style="COLOR: #000000">=</span>
										<span style="COLOR: #000000">&#160;name;<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />}</span>
								</span>
								<span style="COLOR: #000000">
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />
										<br />
										<img id="_214_357_Open_Image" onclick="this.style.display='none'; document.getElementById('_214_357_Open_Text').style.display='none'; document.getElementById('_214_357_Closed_Image').style.display='inline'; document.getElementById('_214_357_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" />
										<img id="_214_357_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_214_357_Closed_Text').style.display='none'; document.getElementById('_214_357_Open_Image').style.display='inline'; document.getElementById('_214_357_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align="top" />
								</span>
								<span style="COLOR: #0000ff">public</span>
								<span style="COLOR: #000000">&#160;</span>
								<span style="COLOR: #0000ff">boolean</span>
								<span style="COLOR: #000000">&#160;equals(Object&#160;o)</span>
								<span id="_214_357_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span>
								<span id="_214_357_Open_Text">
										<span style="COLOR: #000000">{<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span>
										<span style="COLOR: #0000ff">if</span>
										<span style="COLOR: #000000">(</span>
										<span style="COLOR: #0000ff">this</span>
										<span style="COLOR: #000000">==</span>
										<span style="COLOR: #000000">o)&#160;</span>
										<span style="COLOR: #0000ff">return</span>
										<span style="COLOR: #000000">&#160;</span>
										<span style="COLOR: #0000ff">true</span>
										<span style="COLOR: #000000">;<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;</span>
										<span style="COLOR: #0000ff">if</span>
										<span style="COLOR: #000000">(o&#160;</span>
										<span style="COLOR: #0000ff">instanceof</span>
										<span style="COLOR: #000000">&#160;Person)<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;</span>
										<span style="COLOR: #0000ff">return</span>
										<span style="COLOR: #000000">&#160;(</span>
										<span style="COLOR: #0000ff">this</span>
										<span style="COLOR: #000000">.id&#160;</span>
										<span style="COLOR: #000000">==</span>
										<span style="COLOR: #000000">&#160;((Person)o).id)&#160;</span>
										<span style="COLOR: #000000">&amp;&amp;</span>
										<span style="COLOR: #000000">&#160;(</span>
										<span style="COLOR: #0000ff">this</span>
										<span style="COLOR: #000000">.name.equals(((Person)o).name));<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&#160;&#160;&#160;&#160;}</span>
								</span>
								<span style="COLOR: #000000">
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />
										<br />
										<img id="_360_416_Open_Image" onclick="this.style.display='none'; document.getElementById('_360_416_Open_Text').style.display='none'; document.getElementById('_360_416_Closed_Image').style.display='inline'; document.getElementById('_360_416_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" />
										<img id="_360_416_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_360_416_Closed_Text').style.display='none'; document.getElementById('_360_416_Open_Image').style.display='inline'; document.getElementById('_360_416_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align="top" />
								</span>
								<span id="_360_416_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span>
								<span id="_360_416_Open_Text">
										<span style="COLOR: #008000">/*</span>
										<span style="COLOR: #008000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />public&#160;int&#160;hashCode(){<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;return&#160;id*37;<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />}<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" /></span>
										<span style="COLOR: #008000">*/</span>
								</span>
								<span style="COLOR: #000000">
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />
										<br />
										<img id="_458_644_Open_Image" onclick="this.style.display='none'; document.getElementById('_458_644_Open_Text').style.display='none'; document.getElementById('_458_644_Closed_Image').style.display='inline'; document.getElementById('_458_644_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" />
										<img id="_458_644_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; document.getElementById('_458_644_Closed_Text').style.display='none'; document.getElementById('_458_644_Open_Image').style.display='inline'; document.getElementById('_458_644_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif" align="top" />
								</span>
								<span style="COLOR: #0000ff">public</span>
								<span style="COLOR: #000000">&#160;</span>
								<span style="COLOR: #0000ff">static</span>
								<span style="COLOR: #000000">&#160;</span>
								<span style="COLOR: #0000ff">void</span>
								<span style="COLOR: #000000">&#160;main(String&#160;args[])&#160;</span>
								<span id="_458_644_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span>
								<span id="_458_644_Open_Text">
										<span style="COLOR: #000000">{<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;Person&#160;p1&#160;</span>
										<span style="COLOR: #000000">=</span>
										<span style="COLOR: #000000">&#160;</span>
										<span style="COLOR: #0000ff">new</span>
										<span style="COLOR: #000000">&#160;Person(</span>
										<span style="COLOR: #000000">1</span>
										<span style="COLOR: #000000">,</span>
										<span style="COLOR: #000000">"</span>
										<span style="COLOR: #000000">aaa</span>
										<span style="COLOR: #000000">"</span>
										<span style="COLOR: #000000">);<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;Person&#160;p2&#160;</span>
										<span style="COLOR: #000000">=</span>
										<span style="COLOR: #000000">&#160;</span>
										<span style="COLOR: #0000ff">new</span>
										<span style="COLOR: #000000">&#160;Person(</span>
										<span style="COLOR: #000000">1</span>
										<span style="COLOR: #000000">,</span>
										<span style="COLOR: #000000">"</span>
										<span style="COLOR: #000000">aaa</span>
										<span style="COLOR: #000000">"</span>
										<span style="COLOR: #000000">);<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;Map&#160;map&#160;</span>
										<span style="COLOR: #000000">=</span>
										<span style="COLOR: #000000">&#160;</span>
										<span style="COLOR: #0000ff">new</span>
										<span style="COLOR: #000000">&#160;HashMap();<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" /><br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;map.put(p2,p1);<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;Person&#160;value&#160;</span>
										<span style="COLOR: #000000">=</span>
										<span style="COLOR: #000000">&#160;(Person)map.get(p1);<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />&#160;&#160;&#160;&#160;System.out.println(value.name);<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&#160;&#160;}</span>
								</span>
								<span style="COLOR: #000000">
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
						</span>
				</div>
		</div>
		<p>这段代码的结果是什么？答案是nullPointerExcetpion.</p>
		<p>而把hashCode()的注释去除，程序就可以返回正确的结果了。为什么呢？因为：</p>
		<p>Map.put(key,value)时根据key.hashCode生成一个内部hash值，根据这个hash值将对象存放在一个table中</p>
		<p>Map.get(key)会比较key.hashCode和equals方法，当且仅当这两者相等时，才能正确定位到table。而我们说过，默认的java是对地址进行比较的。</p>
 <img src ="http://www.blogjava.net/onejavaer/aggbug/101536.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/onejavaer/" target="_blank">暗夜精灵</a> 2007-03-02 19:41 <a href="http://www.blogjava.net/onejavaer/articles/101536.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA正则表达式--Pattern和Matcher</title><link>http://www.blogjava.net/onejavaer/articles/101126.html</link><dc:creator>暗夜精灵</dc:creator><author>暗夜精灵</author><pubDate>Wed, 28 Feb 2007 05:47:00 GMT</pubDate><guid>http://www.blogjava.net/onejavaer/articles/101126.html</guid><wfw:comment>http://www.blogjava.net/onejavaer/comments/101126.html</wfw:comment><comments>http://www.blogjava.net/onejavaer/articles/101126.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/onejavaer/comments/commentRss/101126.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/onejavaer/services/trackbacks/101126.html</trackback:ping><description><![CDATA[		<p>现在JDK1.4里终于有了自己的正则表达式API包，JAVA程序员可以免去找第三方提供的正则表达式库的周折了，我们现在就马上来了解一下这个SUN提供的&#173;迟来恩物- <br />-对我来说确实如此。 <br />1.简介： <br />java.util.regex是一个<b style="COLOR: black; BACKGROUND-COLOR: #99ff99">用</b>正则表达式所订制的模式来对字符串进行匹配工作的类库包。 <br /></p>
		<p>它包括两个类：Pattern和Matcher Pattern <br />一个Pattern是一个正则表达式经编译后的表现模式。 <br />Matcher <br />一个Matcher对象是一个状态机器，它依据Pattern对象做为匹配模式对字符串展开匹配检查。 <br /></p>
		<p>首先一个Pattern实例订制了一个所用语法与PERL的类似的正则表达式经编译后的模式，然后一个Matcher实例在这个给定的Pattern实例的模式&#173;控制下进行字符串的匹配工作。 <br /></p>
		<p>以下我们就分别来看看这两个类： <br /></p>
		<p>2.Pattern类: <br />Pattern的方法如下： static Pattern compile(String regex) <br />将给定的正则表达式编译并赋予给Pattern类 <br />static Pattern compile(String regex, int flags) <br />同上，但增加flag参数的指定，可选的flag参数包括：CASE <br />INSENSITIVE,MULTILINE,DOTALL,UNICODE CASE， CANON EQ <br />int flags() <br />返回当前Pattern的匹配flag参数. <br />Matcher matcher(CharSequence input) <br />生成一个给定命名的Matcher对象 <br />static boolean matches(String regex, CharSequence input) <br />编译给定的正则表达式并且对输入的字串以该正则表达式为模开展匹配,该方法适合于该正则表达式只会使用一次的情况，也就是只进行一次匹配工作，因为这种情况下并&#173;不需要生成一个Matcher实例。 <br /></p>
		<p>String pattern() <br />返回该Patter对象所编译的正则表达式。 <br />String[] split(CharSequence input) <br />将目标字符串按照Pattern里所包含的正则表达式为模进行分割。 <br /></p>
		<p>String[] split(CharSequence input, int limit) <br />作用同上，增加参数limit目的在于要指定分割的段数，如将limi设为2，那么目标字符串将根据正则表达式分为割为两段。 <br /></p>
		<p>一个正则表达式，也就是一串有特定意义的字符，必须首先要编译成为一个Pattern类的实例，这个Pattern对象将会使用matcher()方法来生成一&#173;个Matcher实例，接着便可以使用该 <br />Matcher实例以编译的正则表达式为基础对目标字符串进行匹配工作，多个Matcher是可以共用一个Pattern对象的。 <br /></p>
		<p>现在我们先来看一个简单的例子，再通过分析它来了解怎样生成一个Pattern对象并且编译一个正则表达式，最后根据这个正则表达式将目标字符串进行分割： <br /></p>
		<p>import java.util.regex.*; <br />public class Replacement{ <br />public static void main(String[] args) throws Exception { <br />// 生成一个Pattern,同时编译一个正则表达式 <br />Pattern p = Pattern.compile("[/]+"); <br />//<b style="COLOR: black; BACKGROUND-COLOR: #99ff99">用</b>Pattern的split()方法把字符串按"/"分割 <br />String[] result = p.split( <br />"Kevin has seen《LEON》seveal times,because it is a good film." <br />+"/ <br />凯文已经看过《这个杀手不太冷》几次了，因为它是一部" <br />+"好电影。/名词:凯文。"); <br />for (int i=0; i&lt;result.length; i++) <br />System.out.println(result[i]); <br /></p>
		<p>
		</p>
		<div class="qt" id="qhide_100340" style="DISPLAY: block">} <br />} <br /><br /></div>输出结果为： <br /><p>Kevin has seen《LEON》seveal times,because it is a good film. <br />凯文已经看过《这个杀手不太冷》几次了，因为它是一部好电影。 <br />名词:凯文。 <br /></p><p>很明显，该程序将字符串按"/"进行了分段，我们以下再使用 <br />split(CharSequence input, int <br />limit)方法来指定分段的段数，程序改动为： <br />tring[] result = p.split("Kevin has seen《LEON》seveal times,because <br />it is a good film./ <br />凯文已经看过《这个杀手不太冷》几次了，因为它是一部好电影。/名词:凯文。"，2); <br /></p><p>这里面的参数"2"表明将目标语句分为两段。 <br /></p><p>输出结果则为： <br /></p><p>Kevin has seen《LEON》seveal times,because it is a good film. <br />凯文已经看过《这个杀手不太冷》几次了，因为它是一部好电影。/名词:凯文。 <br /></p><p>由上面的例子，我们可以比较出java.util.regex包在构造Pattern对象以及编译指定的正则表达式的实现手法与我们在上一篇中所介绍的Jaka&#173;rta-<b style="COLOR: black; BACKGROUND-COLOR: #a0ffff">ORO</b><br />包在完成同样工作时的差别，<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">Jakarta</b>-<b style="COLOR: black; BACKGROUND-COLOR: #a0ffff">ORO</b><br />包要先构造一个PatternCompiler类对象接着生成一个Pattern对象，再将正则表达式<b style="COLOR: black; BACKGROUND-COLOR: #99ff99">用</b>该PatternCompiler类的compile(&#173;)方法来将所需的正则表达式编译赋予Pattern类： <br /></p><p>PatternCompiler orocom=new Perl5Compiler(); <br /></p><p>Pattern pattern=orocom.compile("REGULAR EXPRESSIONS"); <br /></p><p>PatternMatcher matcher=new Perl5Matcher(); <br /></p><p>但是在java.util.regex包里，我们仅需生成一个Pattern类，直接使用它的compile()方法就可以达到同样的效果: <br />Pattern p = Pattern.compile("[/]+"); <br /></p><p>因此似乎java.util.regex的构造法比<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">Jakarta</b>-<b style="COLOR: black; BACKGROUND-COLOR: #a0ffff">ORO</b>更为简洁并容易理解。 <br /></p><p>3.Matcher类: <br />Matcher方法如下： Matcher appendReplacement(StringBuffer sb, <br />String replacement) <br />将当前匹配子串替换为指定字符串，并且将替换后的子串以及其之前到上次匹配子串之后的字符串段添加到一个StringBuffer对象里。 <br /></p><p>StringBuffer appendTail(StringBuffer sb) <br />将最后一次匹配工作后剩余的字符串添加到一个StringBuffer对象里。 <br /></p><p>int end() <br />返回当前匹配的子串的最后一个字符在原目标字符串中的索引位置 <br />。 <br />int end(int group) <br />返回与匹配模式里指定的组相匹配的子串最后一个字符的位置。 <br /></p><p>boolean find() <br />尝试在目标字符串里查找下一个匹配子串。 <br />boolean find(int start) <br />重设Matcher对象，并且尝试在目标字符串里从指定的位置开始查找下一个匹配的子串。 <br /></p><p>String group() <br />返回当前查找而获得的与组匹配的所有子串内容 <br />String group(int group) <br />返回当前查找而获得的与指定的组匹配的子串内容 <br />int groupCount() <br />返回当前查找所获得的匹配组的数量。 <br />boolean lookingAt() <br />检测目标字符串是否以匹配的子串起始。 <br />boolean matches() <br />尝试对整个目标字符展开匹配检测，也就是只有整个目标字符串完全匹配时才返回真值。 <br /></p><p>Pattern pattern() <br />返回该Matcher对象的现有匹配模式，也就是对应的Pattern <br />对象。 <br />String replaceAll(String replacement) <br />将目标字符串里与既有模式相匹配的子串全部替换为指定的字符串。 <br /></p><p>String replaceFirst(String replacement) <br />将目标字符串里第一个与既有模式相匹配的子串替换为指定的字符串。 <br /></p><p>Matcher reset() <br />重设该Matcher对象。 <br />Matcher reset(CharSequence input) <br />重设该Matcher对象并且指定一个新的目标字符串。 <br />int start() <br />返回当前查找所获子串的开始字符在原目标字符串中的位置。 <br /></p><p>int start(int group) <br />返回当前查找所获得的和指定组匹配的子串的第一个字符在原目标字符串中的位置。 <br /></p><p>（光看方法的解释是不是很不好理解？不要急，待会结合例子就比较容易明白了） <br /></p><p>一个Matcher实例是被用来对目标字符串进行基于既有模式（也就是一个给定的Pattern所编译的正则表达式）进行匹配查找的，所有往Matcher的输&#173;入都是通过CharSequence接口提供的，这样做的目的在于可以支持对从多元化的数据源所提供的数据进行匹配工作。 <br /></p><p>我们分别来看看各方法的使用： <br /></p><p>★matches()/lookingAt ()/find()： <br />一个Matcher对象是由一个Pattern对象调用其matcher()方法而生成的，一旦该Matcher对象生成,它就可以进行三种不同的匹配查找操作&#173;： <br /></p><p>matches()方法尝试对整个目标字符展开匹配检测，也就是只有整个目标字符串完全匹配时才返回真值。 <br /></p><p>lookingAt <br />()方法将检测目标字符串是否以匹配的子串起始。 <br />find()方法尝试在目标字符串里查找下一个匹配子串。 <br /></p><p>以上三个方法都将返回一个布尔值来表明成功与否。 <br /></p><p>★replaceAll ()/appendReplacement()/appendTail()： <br />Matcher类同时提供了四个将匹配子串替换成指定字符串的方法： <br /></p><p>replaceAll() <br />replaceFirst() <br />appendReplacement() <br />appendTail() <br /></p><p>replaceAll()与replaceFirst()的用法都比较简单，请看上面方法的解释。我们主要重点了解一下appendReplacement()&#173;和appendTail()方法。 <br /></p><p>appendReplacement(StringBuffer sb, String replacement) <br />将当前匹配子串替换为指定字符串，并且将替换后的子串以及其之前到上次匹配子串之后的字符串段添加到一个StringBuffer对象里，而appendTai&#173;l(StringBuffer <br />sb) <br />方法则将最后一次匹配工作后剩余的字符串添加到一个StringBuffer对象里。 <br /></p><p>例如，有字符串fatcatfatcatfat,假设既有正则表达式模式为"cat"，第一次匹配后调用appendReplacement(sb,"dog"&#173;),那么这时StringBuffer <br />sb的内容为fatdog，也就是fatcat中的cat被替换为dog并且与匹配子串前的内容加到sb里，而第二次匹配后调用appendReplaceme&#173;nt(sb,"dog")，那么sb的内容就变为fatdogfatdog，如果最后再调用一次appendTail（sb）,那么sb最终的内容将是fatd&#173;ogfatdogfat。 <br /></p><p>还是有点模糊？那么我们来看个简单的程序： <br />//该例将把句子里的"Kelvin"改为"Kevin" <br />import java.util.regex.*; <br />public class MatcherTest{ <br />public static void main(String[] args) <br />throws Exception { <br />//生成Pattern对象并且编译一个简单的正则表达式"Kelvin" <br />Pattern p = Pattern.compile("Kevin"); <br />//<b style="COLOR: black; BACKGROUND-COLOR: #99ff99">用</b>Pattern类的matcher()方法生成一个Matcher对象 <br />Matcher m = p.matcher("Kelvin Li and Kelvin Chan are both working in <br />Kelvin Chen's KelvinSoftShop company"); <br />StringBuffer sb = new StringBuffer(); <br />int i=0; <br />//使用find()方法查找第一个匹配的对象 <br />boolean result = m.find(); <br />//使用循环将句子里所有的kelvin找出并替换再将内容加到sb里 <br />while(result) { <br />i++; <br />m.appendReplacement(sb, "Kevin"); <br />System.out.println("第"+i+"次匹配后sb的内容是："+sb); <br />//继续查找下一个匹配对象 <br />result = m.find(); <br /></p><div class="qt" id="qhide_100341" style="DISPLAY: block">} <br /><br /></div>//最后调用appendTail()方法将最后一次匹配后的剩余字符串加到sb里； <br />m.appendTail(sb); <br />System.out.println("调用m.appendTail(sb)后sb的最终内容是:"+ <br />sb.toString()); <br /><p></p><div class="qt" id="qhide_100342" style="DISPLAY: block">} <br />} <br /><br /></div>最终输出结果为： <br />第1次匹配后sb的内容是：Kevin <br />第2次匹配后sb的内容是：Kevin Li and Kevin <br />第3次匹配后sb的内容是：Kevin Li and Kevin Chan are both <br />working in Kevin <br />第4次匹配后sb的内容是：Kevin Li and Kevin Chan are both <br />working in Kevin Chen's Kevin <br />调用m.appendTail(sb)后sb的最终内容是：Kevin Li and Kevin Chan <br />are both working in Kevin Chen's KevinSoftShop company. <br /><p>看了上面这个例程是否对appendReplacement()，appendTail()两个方法的使用更清楚呢，如果还是不太肯定最好自己动手写几行代码测&#173;试一下。 <br /></p><p>★group()/group(int group)/groupCount()： <br />该系列方法与我们在上篇介绍的<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">Jakarta</b>-<b style="COLOR: black; BACKGROUND-COLOR: #a0ffff">ORO</b>中的MatchResult <br />.group()方法类似(有关<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">Jakarta</b>-<b style="COLOR: black; BACKGROUND-COLOR: #a0ffff">ORO</b>请参考上篇的内容)，都是要返回与组匹配的子串内容，下面代码将很好解释其用法： <br /></p><p>import java.util.regex.*; <br /></p><p>public class GroupTest{ <br />public static void main(String[] args) <br />throws Exception { <br />Pattern p = Pattern.compile("(ca)(t)"); <br />Matcher m = p.matcher("one cat,two cats in the yard"); <br />StringBuffer sb = new StringBuffer(); <br />boolean result = m.find(); <br />System.out.println("该次查找获得匹配组的数量为："+m.groupCount()); <br />for(int i=1;i&lt;=m <br /></p><p></p><div class="qt" id="qhide_100343" style="DISPLAY: block">} <br />} <br /><br /></div>输出为： <br />该次查找获得匹配组的数量为：2 <br />第1组的子串内容为：ca <br />第2组的子串内容为：t <br /><p>Matcher对象的其他方法因比较好理解且由于篇幅有限，请读者自己编程验证。 <br /></p><p>4．一个检验Email地址的小程序： <br />最后我们来看一个检验Email地址的例程，该程序是用来检验一个输入的EMAIL地址里所包含的字符是否合法，虽然这不是一个完整的EMAIL地址检验程序，&#173;它不能检验所有可能出现的情况，但在必要时您可以在其基础上增加所需功能。 <br /></p><p>import java.util.regex.*; <br />public class Email { <br />public static void main(String[] args) throws Exception { <br />String input = args[0]; <br />//检测输入的EMAIL地址是否以 <br />非法符号"."或"@"作为起始字符 <br />Pattern p = Pattern.compile("^\.|^\@"); <br />Matcher m = p.matcher(input); <br />if (m <br />//检测是否以"www."为起始 <br />p = Pattern.compile("^www\."); <br />m = p.matcher(input); <br />if (m <br />//检测是否包含非法字符 <br />p = Pattern.compile("[^A-Za-z0-9\.\@_\-~#]+"); <br />m = p.matcher(input); <br />StringBuffer sb = new StringBuffer(); <br />boolean result = m.find(); <br />boolean deletedIllegalChars = false; <br />while(result) { <br />//如果找到了非法字符那么就设下标记 <br />deletedIllegalChars = true; <br />//如果里面包含非法字符如冒号双引号等，那么就把他们消去，加到SB里面 <br />m.appendReplacement(sb, ""); <br />result = m.find(); <br /></p><div class="qt" id="qhide_100344" style="DISPLAY: block">} <br /><br /></div>m.appendTail(sb); <br />input = sb.toString(); <br />if (deletedIllegalChars) { <br />System.out.println("输入的EMAIL地址里包含有冒号、逗号等非法字符，请修改"); <br />System.out.println("您现在的输入为: "+args[0]); <br />System.out.println("修改后合法的地址应类似: "+input); <br /><p></p><div class="qt" id="qhide_100345" style="DISPLAY: block">} <br />} <br />} <br /><br /></div>例如，我们在命令行输入：java Email www.ke<a href="http://groups.google.com/groups/unlock?msg=0a6b45f04e227b1a&amp;_done=/group/javakb/browse_thread/thread/71037c48df752e29/0a6b45f04e227b1a%3Flnk%3Dst%26q%3DJakarta%2BORO%2B%25E7%2594%25A8%26rnum%3D1" target="_parent"><font color="#0000cc">...</font></a>@163.net <br /><p>那么输出结果将会是：EMAIL地址不能以'www.'起始 <br /></p><p>如果输入的EMAIL为@k<a href="http://groups.google.com/groups/unlock?msg=0a6b45f04e227b1a&amp;_done=/group/javakb/browse_thread/thread/71037c48df752e29/0a6b45f04e227b1a%3Flnk%3Dst%26q%3DJakarta%2BORO%2B%25E7%2594%25A8%26rnum%3D1" target="_parent"><font color="#0000cc">...</font></a>@163.net <br /></p><p>则输出为：EMAIL地址不能以'.'或'@'作为起始字符 <br /></p><p>当输入为：cgjmail<a href="http://groups.google.com/groups/unlock?msg=0a6b45f04e227b1a&amp;_done=/group/javakb/browse_thread/thread/71037c48df752e29/0a6b45f04e227b1a%3Flnk%3Dst%26q%3DJakarta%2BORO%2B%25E7%2594%25A8%26rnum%3D1" target="_parent"><font color="#0000cc">...</font></a>@163.net <br /></p><p>那么输出就是： <br /></p><p>输入的EMAIL地址里包含有冒号、逗号等非法字符，请修改 <br />您现在的输入为: cgjmail<a href="http://groups.google.com/groups/unlock?msg=0a6b45f04e227b1a&amp;_done=/group/javakb/browse_thread/thread/71037c48df752e29/0a6b45f04e227b1a%3Flnk%3Dst%26q%3DJakarta%2BORO%2B%25E7%2594%25A8%26rnum%3D1" target="_parent"><font color="#0000cc">...</font></a>@163.net <br />修改后合法的地址应类似: cgjm<a href="http://groups.google.com/groups/unlock?msg=0a6b45f04e227b1a&amp;_done=/group/javakb/browse_thread/thread/71037c48df752e29/0a6b45f04e227b1a%3Flnk%3Dst%26q%3DJakarta%2BORO%2B%25E7%2594%25A8%26rnum%3D1" target="_parent"><font color="#0000cc">...</font></a>@163.net <br /></p><p>5．总结： <br />本文介绍了jdk1.4.0-beta3里正则表达式库--java.util.regex中的类以及其方法，如果结合与上一篇中所介绍的<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">Jakarta</b>-OR&#173;O <br />API作比较，读者会更容易掌握该API的使用，当然该库的性能将在未来的日子里不断扩展，希望获得最新信息的读者最好到及时到SUN的网站去了解。 <br /></p><p>6．结束语： <br />本来计划再多写一篇介绍一下需付费的正则表达式库中较具代表性的作品，但觉得既然有了免费且优秀的正则表达式库可以使用，何必还要去找需付费的呢，相信很多读者&#173;也是这么想的:，所以有兴趣了解更多其他的第三方正则表达式库的朋友可以自己到网上查找或者到我在参考资料里提供的网址去看看。 <br /></p><p>参考资料 <br /></p><p>java.util.regex的帮助文档 <br />Dana Nourie 和Mike McCloskey所写的Regular Expressions and the <br />Java&#8482; Programming Language <br />需要更多的第三方正则表达式资源以及基于它们所开发的应用程序请看<a href="http://www.meurrens.org/ip-Links/java/regex/index.html" target="_blank"><font color="#0000cc">http://www.meurrens.org/ip-Links/java/regex/index.html</font></a><br /></p><p>关于作者 <br />陈广佳 Kevin <br />Chen,汕头大学电子信息工程系工科学士，台湾大新出版社珠海区开发部，现正围绕中日韩电子资料使用JAVA开发电子词典等相关项目。可通过E-mail:c&#173;gjm<a href="http://groups.google.com/groups/unlock?msg=0a6b45f04e227b1a&amp;_done=/group/javakb/browse_thread/thread/71037c48df752e29/0a6b45f04e227b1a%3Flnk%3Dst%26q%3DJakarta%2BORO%2B%25E7%2594%25A8%26rnum%3D1" target="_parent"><font color="#0000cc">...</font></a>@163.net于他联系。</p> <img src ="http://www.blogjava.net/onejavaer/aggbug/101126.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/onejavaer/" target="_blank">暗夜精灵</a> 2007-02-28 13:47 <a href="http://www.blogjava.net/onejavaer/articles/101126.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>整清 java 中的 类、抽象类、接口、继承、对象</title><link>http://www.blogjava.net/onejavaer/articles/100858.html</link><dc:creator>暗夜精灵</dc:creator><author>暗夜精灵</author><pubDate>Tue, 27 Feb 2007 01:43:00 GMT</pubDate><guid>http://www.blogjava.net/onejavaer/articles/100858.html</guid><wfw:comment>http://www.blogjava.net/onejavaer/comments/100858.html</wfw:comment><comments>http://www.blogjava.net/onejavaer/articles/100858.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/onejavaer/comments/commentRss/100858.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/onejavaer/services/trackbacks/100858.html</trackback:ping><description><![CDATA[		<p>
				<font color="#a52a2a">
						<font color="#006400">本文以一条龙的形式一次性解决问题。</font>
						<br />
						<br />类是广泛的概念，表示一个有共同性质的群体。如：人类。<br /><br />代码：<br />&#160;&#160;&#160;&#160;&#160;&#160;<font color="#a52a2a"> //&#160;声明一个类&#8220;Human&#8221;</font><font color="#000000"><br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;<font size="2">&#160;&#160;&#160;&#160; <strong>class&#160;Human{<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;private&#160;String&#160;name;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; public&#160;String&#160;getName(){<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return&#160;name;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;public&#160;void&#160;setName(String&#160;value){<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;this.name&#160;=&#160;value;<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //......<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</strong></font></font><br /><br /><font color="#a52a2a">对象指的是具体的一个实实在在的东西。如、张三、李四。<br /></font><br />代码：<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;<font color="#000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</font><font color="#a52a2a">&#160;&#160; <strong><font color="#000000" size="2">Human&#160;zhangsan&#160;=&#160;new&#160;Human();</font></strong><br /><br /></font>图：<br />&#160;&#160;&#160;&#160; <img title="ren" height="308" alt="人.png" src="http://www.blogjava.net/images/blogjava_net/lusm/人.png" width="576" border="0" /><br /><br />图中我们怎么创建张三和李四呢？？我们前面的代码好像还没涉及，恩好，看下面<br /><font color="#000000"><br /><font size="2"><strong>Human&#160;human&#160;=&#160;new&#160;Human();</strong><br /></font><br /><font color="#a52a2a">程序执行到这里之后，java虚拟机将会在内存中创建一个&#160;Human&#160;对象，并将这个对象的引用赋给&#160;human&#160;变量。</font><br /></font><br />接着：<font color="#000000"><strong><font size="2">human.setName("张三"); human.setName("李四");</font></strong><font color="#a52a2a">好了对象（实例）创建好了，呵呵</font>！<br /><br /><font color="#a52a2a">图：<br /></font>&#160;&#160;&#160;&#160;&#160; <img title="人1" height="280" alt="人1.png" src="http://www.blogjava.net/images/blogjava_net/lusm/人1.png" width="564" border="0" /><br /></font><br /><font color="#a52a2a">&#8220;人&#8221;是一个<font color="#ff0000">基类</font>，则&#8220;男人&#8221;是&#8220;人&#8221;的一个<font color="#ff0000">子类</font>。如果&#8220;张三&#8221;是一个&#8220;男人&#8221;，也就是说&#8220;张三&#8221;是&#8220;男人&#8221;的一个对象，那么显然&#8220;张三&#8221;也是&#8220;人&#8221;这个基类的一个对象。<br /></font>&#160;&#160;&#160;<strong><font color="#000000"></font></strong><strong><font color="#000000" size="2">class nanren&#160;extends&#160; human(String args[ ]){<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;//.............<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</font></strong><br /><br />方法是类的行为，如人会笑、会坐、会走路 一样。<br /><br />图：<br />&#160;&#160;&#160;&#160;&#160; <img title="人2" height="280" alt="人2.png" src="http://www.blogjava.net/images/blogjava_net/lusm/人2.png" width="564" border="0" /><br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<br />&#160;</font>
				<font color="#a52a2a">代码：<br /></font>
				<font color="#a52a2a">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<font size="2">&#160;&#160; <strong><font color="#000000">zhangsan.go();zhangsan.xiao();zhangsan.shuijiao();zhangsan.qita();</font></strong></font><br /><br /><font color="#000000"><font color="#a52a2a">接口只定义了一些方法，而没有实现这些方法，它规定了实现接口的类必须具备的方法（能力），<font color="#ff0000">它只是一个规定</font>。</font><br /></font><br />我们规定：只要是人就可以走路、笑、睡觉、做其他的事，于是我们用代码实现这个规定<br /><font color="#000000"><strong><font size="2">public&#160;interface&#160;you_are_human{<br />public&#160;void&#160;go();<br />public&#160;void&#160;xiao();<br />public void shuijiao();<br />public void qita();<br />}</font></strong><br /><font color="#a52a2a">这时，张三想做人，但他只想拥有走路和笑的能力。首先，他必须声明自己是人，也就是前面对人的规定，<br />然后想做什么由他自己决定：<br /><br /></font><strong><font size="2">public&#160;class&#160;zhangsan extends&#160;Human&#160;implements&#160;you_are_human{<br />public&#160;void&#160;go(){<br />//&#160;......<br />}<br />public&#160;void&#160;xiao(){<br />//&#160;......<br />}<br />}</font></strong></font><br />使用的时候：<br /><font color="#000000" size="2"><strong>you_are_human&#160;&#160;zhangsan&#160;=&#160;new&#160;you_are_human();<br /><br /></strong></font></font>
				<strong>
						<font size="2">zhangsan.go();<br /><br />zhangsan.xiao();</font>
				</strong>
				<font color="#a52a2a">
						<br />
						<br />那有的人就会问，这和前面我定义类有什么区别；<br /><br />这是因为：java的类的继承是从上到下的，爷爷1 》老爸1 》儿子1</font>
		</p>
		<p>
				<font color="#a52a2a">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 爷爷2&#160;&#160; 》老爸2&#160; 》&#160;儿子2<br />&#160;&#160;&#160;&#160;&#160;而不能是：爷爷2&#160; 》&#160;儿子1<br /><br />这样就乱套了&#160;，是不，闹笑话；所以，类规定了不继承关系，防止乱套，使结构变得清晰。<br /><br />所以，当我们使用树型结构时，使用类。<br /><br /><br /></font>
		</p>
		<p>
				<font color="#a52a2a">由于，在生活中还有许多这样的情况，如，张三是中国人，那张三他也是美国人双重身份。<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 再如，李四是java工程师,也是厨师。<br />那怎么办？？<br /><br />我们可以这么做：<br /></font>
				<font color="#a52a2a">规定多个身份</font>
				<font color="#a52a2a">
						<font color="#000000">
								<strong>
										<br />
										<font size="2">public&#160;interface zhengjian{<br />interface China(){<br />public&#160;void&#160;China_L(){<br />//.................<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;&#160;&#160; }<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}<br />interface&#160; USA(){<br />public&#160; void&#160;USA_L(){<br />//...........<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</font>
								</strong>
								<font size="2">
										<br />
								</font>
						</font>
				</font>
				<font color="#000000" size="2">}<br /></font>
				<font color="#a52a2a">
						<br />
						<strong>
								<font color="#000000" size="2">public&#160;class&#160;zhangsan extends&#160;zhengjian&#160;implements&#160;Chna , USA{<br />public&#160;void&#160;China_L(){<br />//&#160;......<br />}<br />public&#160;void&#160;USA_L(){<br />//&#160;......<br />}<br />}</font>
						</strong>
						<br />
						<br />当张三去美国时，老美叫他拿个绿证来看：<br /><br /><strong><font color="#000000" size="2">zhangsan.USA_L();</font></strong><br /><br /></font>
		</p>
		<p>
				<font color="#a52a2a">
				</font>
		</p>
		<p>
				<font color="#a52a2a">呵呵，再举个例子大家就清楚了：<br /><br />HP有&#8220;三星&#8221;和&#8220;IBM&#8221;两种，我通常而言不可能一个HP是既是&#8220;三星&#8221;又是&#8220;IBM&#8221;的吧~~~~~~~~类<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#8220;家庭式&#8221;和&#8220;办公式&#8221;两种，但往往我们能买到拥有两种款式相结合厂品是吧&#160;&#160;&#160; ~~~~~~~~~~~接口<br /><br />中国人说起来，<u>类有点&#8220;封建世袭制&#8221;，接口有点&#8220;违反常理乱伦&#8221;，呵呵<img height="20" src="http://www.blogjava.net/Emoticons/QQ/lol.gif" width="20" border="0" />开个玩笑</u>。<br /><br />这样说完大家再去看些相关文章就会觉得很容易了 呵呵<img height="20" src="http://www.blogjava.net/Emoticons/QQ/icon17.gif" width="20" border="0" /><br /><br />剩下抽象类就简单了，那是抽象类（<font color="#000000"><font color="#a52a2a">abstract</font>）</font>他还是类（class)，只不过是抽象的罢了。<br /><br />抽象类<font color="#000000"><font color="#a52a2a">对某具体类型的部分实现------抽象类是对具体的抽象方法特征包括：<font color="#ff0000">方法的名字、参数的数目、参数的类型。<br /><br />不包括：返回类型、参数名字、和抛出的异常。<br /></font><br /><a href="http://www.qqread.com/keywords/java.html" target="_blank"><font color="#a52a2a">java</font></a><font color="#a52a2a">接口（抽象类）用来声明一个新的类型,<font color="#a52a2a">Java设计师应当主要使用接口和抽象类将软件单位与内部和外部<u>耦合</u>(软件工程中内容)起来。<br /><br /></font><font color="#a52a2a">在理想的情况下，一个具体类应当只实现接口和抽象类中声明的方法，而不应当给出多余的方法！<br /><br /></font><font color="#a52a2a">抽象类仅提供一个类的部分实现。抽象类可以有实例变量、以及一个或多个构造函数。<br /><br /></font>人这个概念够抽象了吧！<br /><font color="#000000">public&#160; abstract &#160; class&#160;&#160; Human{...}&#160;&#160;<br /><font color="#a52a2a"><br />男人也是</font>&#160;<br />public&#160;&#160; abstract &#160; class&#160;&#160;man{...}&#160;&#160;&#160; </font><br /></font><br /></font><font color="#a52a2a">有一点必须讲清：<font color="#ff0000">接口不能继承抽象类，</font><font color="#a52a2a">接口只能继承实实在在的类，<br /><br />如，我可以为某个HP厂品（类）规定一种规范（接口），但由于各个厂家推陈出新，所以，我很难对某一类型厂品规定，&#8220;家庭型hp&#8221;就很难下个结论（接口）。<br /></font><br /><br /><font color="#006400"><strong>从软件优化角度来考虑类和接口问题。类class条理清楚内聚性好，用于软件模块内部实现（汽车的内部机<br /><br />械）；接口interface很灵活耦合性好，用于模块外部实现（如，汽车操作板的按钮）。从而实现强内聚、松耦合<br /><br />的软件设计思想。</strong></font><br /></font></font></font>
		</p>
 <img src ="http://www.blogjava.net/onejavaer/aggbug/100858.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/onejavaer/" target="_blank">暗夜精灵</a> 2007-02-27 09:43 <a href="http://www.blogjava.net/onejavaer/articles/100858.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>include指令和include动作的区别是什么?</title><link>http://www.blogjava.net/onejavaer/articles/80979.html</link><dc:creator>暗夜精灵</dc:creator><author>暗夜精灵</author><pubDate>Mon, 13 Nov 2006 13:23:00 GMT</pubDate><guid>http://www.blogjava.net/onejavaer/articles/80979.html</guid><wfw:comment>http://www.blogjava.net/onejavaer/comments/80979.html</wfw:comment><comments>http://www.blogjava.net/onejavaer/articles/80979.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/onejavaer/comments/commentRss/80979.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/onejavaer/services/trackbacks/80979.html</trackback:ping><description><![CDATA[		<hr />
&#160;&#160;&#160; include指令和include动作都能实现将外部文档包含到JSP文档中的功能，名称也很相似，非常容易混淆。include指令和include动作到底有什么分别，哪一种方式会更好呢？<br /><strong>1.include指令<br /></strong>&#160;&#160;&#160; include可以在JSP页面转换成Servlet之前，将JSP代码插入其中。它的主要优点是功能强大，所包含的代码可以含有总体上影响主页面的JSP构造，比如属性、方法的定义和文档类型的设定。它的缺点是难于维护只要被包含的页面发生更改，就得更改主页面，这是因为主页面不会自动地查看被包含的页面是否发生更改。<br />include指令的语法格式如下<br /><font style="BACKGROUND-COLOR: #808080">&#160;</font><font style="BACKGROUND-COLOR: #808080">&#160;&#160; &lt;%@ include file="Relative Url"%&gt;<br /></font><br /><strong>2.include动作<br />&#160; </strong>jsp:include动作是在主页面被请求时，将次级页面的输出包含进来。尽管被包含的页面的输出中不能含有JSP，但这些页面可以是其他资源所产生的结果。服务器按照正常的方式对指向被包含资源的URL进行解释，因而这个URL可以是Servlet或JSP页面。服务器以通常的方式运行被包含的页面，将产生的输出放到主页面中，这种方式与RequestDispatcher类的include方法一致。它的优点是在被包含的页面发生更改时，无须对主页面做出修改。它的缺点是所包含的是次级页面的输出，而非次级页面的实际代码，所以在被包含的页面中不能使用任何有可能在整体上影响主页面的JSP构造。<br />&#160; jsp:include动作的完整语法如下<br />&#160;<font style="BACKGROUND-COLOR: #a9a9a9"></font><font style="BACKGROUND-COLOR: #808080">&lt;jsp:include page="Relative path to resource" flush="true"&gt;<br /><font style="BACKGROUND-COLOR: #ffffff">&#160; 其中jsp:include之间不能有空格，page属性指定被包含的页面，这个属性是必需的，是指向某种资源的相对URL。如果这个相对URL不是以/开头，则将其解释为相对于主页面的路径；如果是以/开头，是这个URL被解释为相对于当前WEB应用的根目录，而不是服务器的根目录，这是因为该URL是由服务器来解释的，不是由用户的浏览器来解释的。像下面这行代码，是由用户的浏览器进行解释的，因此会按照相对于服务器的根目录进行解释。<br />&#160; flush属性是一个可选的次级属性，默认值为false，它指定在将页面包含进来之前是否应该清空主页面的输出流。<br />&#160;&#160;&#160;注意：在JSP1.1中，flush是必需的属性，而且聚会只能是true。<br /><strong>3.两者的区别和比较</strong><br />&#160;&#160; jsp:include动作和include指令之间的根本性的不同在于它们被调用的时间。jsp:include动作在请求期间被激活，而include指令在页面转换期间被激活。<br />&#160;&#160; 两者之间的差异决定着它们在使用上的区别。使用include指令的页面要比使用jsp:include动作的页面难于维护。前面已经说过，使用JSP指令，如果包含的JSP页面发生变化，那么用到这个页面的所有页面都需要手动更新。在JSP服务器的相关规范中并没要求能够检测出包含的文件什么时候发生改变，实际上大多数服务器页都有去实现这种机制。这样就会导致十分严重的维护问题，需要记住所有包含某一个页面的其他页面，或者重新编译所有的页面，以使更改能够生效。在这点上，jsp:include就体现出了十分巨大的优势，它在每次请求时重新把资源包含进来。在实现文件包含上，应该尽可能地使用jsp:include动作。<br />&#160;&#160; jsp:include动作直比于include指令在维护上有着明显优势，而include指令仍然能够得以存在，自然在其他方面有特殊的优势。这个优势就是include指令的功能更强大，执行速度也稍快。include指令允许所包含的文件中含有影响主页面的JSP代码，比如响应报送的设置和属性方法的定义。以下表格就是两种包含方式的对比:<br /></font></font><table class="MsoTableGrid8" style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; mso-border-alt: solid navy .75pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .75pt solid navy; mso-border-insidev: .75pt solid navy" cellspacing="0" cellpadding="0" border="1"><tbody><tr style="mso-yfti-irow: -1; mso-yfti-firstrow: yes"><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: navy 1pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: navy; PADDING-BOTTOM: 0cm; BORDER-LEFT: navy 1pt solid; WIDTH: 142pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; mso-border-alt: solid navy .75pt; mso-shading: white; mso-pattern: solid navy" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-yfti-cnfc: 1" align="center"><b><span lang="EN-US" style="COLOR: white"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?><o:p>&#160;</o:p></span></b></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: navy 1pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: navy; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; mso-border-alt: solid navy .75pt; mso-shading: white; mso-pattern: solid navy; mso-border-left-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-yfti-cnfc: 1" align="center"><b><span lang="EN-US" style="COLOR: white">include</span></b><b><span style="COLOR: white; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">指令</span><span lang="EN-US" style="COLOR: white"><o:p></o:p></span></b></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: navy 1pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: navy; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; mso-border-alt: solid navy .75pt; mso-shading: white; mso-pattern: solid navy; mso-border-left-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-yfti-cnfc: 9" align="center"><b><span lang="EN-US" style="COLOR: white">jsp:include</span></b><b><span style="COLOR: white; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">动作</span><span lang="EN-US" style="COLOR: white"><o:p></o:p></span></b></p></td></tr><tr style="mso-yfti-irow: 0"><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: navy 1pt solid; WIDTH: 142pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语法格式</span><span lang="EN-US"><o:p></o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US">&lt;%@ include file=&#8221;..&#8221;%&gt;<o:p></o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-yfti-cnfc: 8" align="center"><span lang="EN-US" style="mso-bidi-font-weight: bold">&lt;jsp:include page=&#8221;..&#8221;&gt;<o:p></o:p></span></p></td></tr><tr style="mso-yfti-irow: 1"><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: navy 1pt solid; WIDTH: 142pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">发生作用的时间</span><span lang="EN-US"><o:p></o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">页面转换期间</span><span lang="EN-US"><o:p></o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-yfti-cnfc: 8" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">请求期间</span><span lang="EN-US" style="mso-bidi-font-weight: bold"><o:p></o:p></span></p></td></tr><tr style="mso-yfti-irow: 2"><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: navy 1pt solid; WIDTH: 142pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包含的内容</span><span lang="EN-US"><o:p></o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件的实际内容</span><span lang="EN-US"><o:p></o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-yfti-cnfc: 8" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">页面的输出</span><span lang="EN-US" style="mso-bidi-font-weight: bold"><o:p></o:p></span></p></td></tr><tr style="mso-yfti-irow: 3"><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: navy 1pt solid; WIDTH: 142pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">转换成的</span><span lang="EN-US">Servlet<o:p></o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">主页面和包含页面转换为一个</span><span lang="EN-US">Servlet <o:p></o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-yfti-cnfc: 8" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">主页面和包含页面转换为独立的</span><span lang="EN-US" style="mso-bidi-font-weight: bold">Servlet<o:p></o:p></span></p></td></tr><tr style="mso-yfti-irow: 4"><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: navy 1pt solid; WIDTH: 142pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">影响主页面</span><span lang="EN-US"><o:p></o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以</span><span lang="EN-US"><o:p></o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-yfti-cnfc: 8" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">不可以</span><span lang="EN-US" style="mso-bidi-font-weight: bold"><o:p></o:p></span></p></td></tr><tr style="mso-yfti-irow: 5"><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: navy 1pt solid; WIDTH: 142pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><o:p>&#160;</o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US">include</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">指令</span><span lang="EN-US"><o:p></o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-yfti-cnfc: 8" align="center"><span lang="EN-US" style="mso-bidi-font-weight: bold">jsp:include</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">动作</span><span lang="EN-US" style="mso-bidi-font-weight: bold"><o:p></o:p></span></p></td></tr><tr style="mso-yfti-irow: 6"><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: navy 1pt solid; WIDTH: 142pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">发生更改时是否需要显式更改主页面</span><span lang="EN-US"><o:p></o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">需要</span><span lang="EN-US"><o:p></o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-yfti-cnfc: 8" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">不需要</span><span lang="EN-US" style="mso-bidi-font-weight: bold"><o:p></o:p></span></p></td></tr><tr style="mso-yfti-irow: 7"><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: navy 1pt solid; WIDTH: 142pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">编译时间</span><span lang="EN-US"><o:p></o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">较慢－资源必须被解析</span><span lang="EN-US"><o:p></o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-yfti-cnfc: 8" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">较快</span><span lang="EN-US" style="mso-bidi-font-weight: bold"><o:p></o:p></span></p></td></tr><tr style="mso-yfti-irow: 8"><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: navy 1pt solid; WIDTH: 142pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">执行时间</span><span lang="EN-US"><o:p></o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">稍快</span><span lang="EN-US"><o:p></o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-yfti-cnfc: 8" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">较慢－每次资源必须被解析</span><span lang="EN-US" style="mso-bidi-font-weight: bold"><o:p></o:p></span></p></td></tr><tr style="mso-yfti-irow: 9; mso-yfti-lastrow: yes"><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: navy 1pt solid; WIDTH: 142pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-yfti-cnfc: 2" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">灵活性</span><span lang="EN-US" style="mso-bidi-font-weight: bold"><o:p></o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-yfti-cnfc: 2" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">较差－页面名称固定</span><span lang="EN-US" style="mso-bidi-font-weight: bold"><o:p></o:p></span></p></td><td style="BORDER-RIGHT: navy 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #e0dfe3; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #e0dfe3; WIDTH: 142.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: navy 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid navy .75pt; mso-border-left-alt: solid navy .75pt; mso-border-top-alt: solid navy .75pt" valign="top" width="189"><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center; mso-yfti-cnfc: 10" align="center"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-weight: bold">更好－页面可以动态指定</span><span lang="EN-US" style="mso-bidi-font-weight: bold"><o:p></o:p></span></p></td></tr></tbody></table><br />&#160;&#160; 了解到jsp:include动作和include指令各自的功能和区别，在使用时，就可以通过考虑各方面的因素，来决定使用哪一种方式。尽管各自都有一定的优缺点，在实际使用中，还是应优先考虑使用jsp:include动作，这是因为它在代码维护上的优势远胜过其在功能上的不足。 <img src ="http://www.blogjava.net/onejavaer/aggbug/80979.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/onejavaer/" target="_blank">暗夜精灵</a> 2006-11-13 21:23 <a href="http://www.blogjava.net/onejavaer/articles/80979.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Web服务器开发环境下的线程安全问题</title><link>http://www.blogjava.net/onejavaer/articles/74100.html</link><dc:creator>暗夜精灵</dc:creator><author>暗夜精灵</author><pubDate>Mon, 09 Oct 2006 08:23:00 GMT</pubDate><guid>http://www.blogjava.net/onejavaer/articles/74100.html</guid><wfw:comment>http://www.blogjava.net/onejavaer/comments/74100.html</wfw:comment><comments>http://www.blogjava.net/onejavaer/articles/74100.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/onejavaer/comments/commentRss/74100.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/onejavaer/services/trackbacks/74100.html</trackback:ping><description><![CDATA[		<p>Servlet是在多线程环境下的。即可能有多个请求发给一个servelt实例，每个请求是一个线程。 <br />struts下的action也类似，同样在多线程环境下。可以参考struts user guide: http://struts.apache.org/struts-action/userGuide/building_controller.html 中的Action Class Design Guidelines一节: Write code for a multi-threaded environment - Our controller servlet creates only one instance of your Action class, and uses this one instance to service all requests. Thus, you need to write thread-safe Action classes. Follow the same guidelines you would use to write thread-safe Servlets. <br />译:为多线程环境编写代码。我们的controller servlet指挥创建你的Action 类的一个实例，用此实例来服务所有的请求。因此，你必须编写线程安全的Action类。遵循与写线程安全的servlet同样的方针。 <br /><br />1.什么是线程安全的代码 <br />在多线程环境下能正确执行的代码就是线程安全的。 <br />安全的意思是能正确执行，否则后果是程序执行错误，可能出现各种异常情况。</p>
		<p>2.如何编写线程安全的代码 <br />很多书籍里都详细讲解了如何这方面的问题，他们主要讲解的是如何同步线程对共享资源的使用的问题。主要是对synchronized关键字的各种用法，以及锁的概念。 <br />Java1.5中也提供了如读写锁这类的工具类。这些都需要较高的技巧，而且相对难于调试。 <br /><br />但是，线程同步是不得以的方法,是比较复杂的,而且会带来性能的损失。等效的代码中，不需要同步在编写容易度和性能上会更好些。 <br />我这里强调的是什么代码是始终为线程安全的、是不需要同步的。如下: <br />1)常量始终是线程安全的，因为只存在读操作。 <br />2)对构造器的访问(new 操作)是线程安全的，因为每次都新建一个实例，不会访问共享的资源。 <br />3)最重要的是:局部变量是线程安全的。因为每执行一个方法，都会在独立的空间创建局部变量，它不是共享的资源。局部变量包括方法的参数变量。 <br />struts user guide里有： <br />Only Use Local Variables - The most important principle that aids in thread-safe coding is to use only local variables, not instance variables , in your Action class. <br />译:只使用用局部变量。--编写线程安全的代码最重要的原则就是，在Action类中只使用局部变量，不使用实例变量。</p>
		<p>
				<br />总结： <br />在Java的Web服务器环境下开发，要注意线程安全的问题。最简单的实现方式就是在Servlet和Struts Action里不要使用类变量、实例变量，但可以使用类常量和实例常量。 <br />如果有这些变量，可以将它们转换为方法的参数传入，以消除它们。 <br />注意一个容易混淆的地方：被Servlet或Action调用的类中(如值对象、领域模型类)中是否可以安全的使用实例变量？如果你在每次方法调用时 <br />新建一个对象，再调用它们的方法，则不存在同步问题---因为它们不是多个线程共享的资源，只有共享的资源才需要同步---而Servlet和Action的实例对于多个线程是共享的。 <br />换句话说，Servlet和Action的实例会被多个线程同时调用，而过了这一层,如果在你自己的代码中没有另外启动线程，且每次调用后续业务对象时都是先新建一个实例再调用，则都是线程安全的。</p>
 <img src ="http://www.blogjava.net/onejavaer/aggbug/74100.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/onejavaer/" target="_blank">暗夜精灵</a> 2006-10-09 16:23 <a href="http://www.blogjava.net/onejavaer/articles/74100.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java.util.ArrayList 详解</title><link>http://www.blogjava.net/onejavaer/articles/72934.html</link><dc:creator>暗夜精灵</dc:creator><author>暗夜精灵</author><pubDate>Sat, 30 Sep 2006 00:14:00 GMT</pubDate><guid>http://www.blogjava.net/onejavaer/articles/72934.html</guid><wfw:comment>http://www.blogjava.net/onejavaer/comments/72934.html</wfw:comment><comments>http://www.blogjava.net/onejavaer/articles/72934.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/onejavaer/comments/commentRss/72934.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/onejavaer/services/trackbacks/72934.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: java.util.ArrayList																																																		&#160;&#160; 				数组和数组列表之间有着重大的区别。数组是				Java				语言的一个特征，对于每个元素类型				T				，都有数组类型				T[];				然而，	...&nbsp;&nbsp;<a href='http://www.blogjava.net/onejavaer/articles/72934.html'>阅读全文</a><img src ="http://www.blogjava.net/onejavaer/aggbug/72934.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/onejavaer/" target="_blank">暗夜精灵</a> 2006-09-30 08:14 <a href="http://www.blogjava.net/onejavaer/articles/72934.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSP生成静态页实践及其设计思想</title><link>http://www.blogjava.net/onejavaer/articles/72910.html</link><dc:creator>暗夜精灵</dc:creator><author>暗夜精灵</author><pubDate>Fri, 29 Sep 2006 14:29:00 GMT</pubDate><guid>http://www.blogjava.net/onejavaer/articles/72910.html</guid><wfw:comment>http://www.blogjava.net/onejavaer/comments/72910.html</wfw:comment><comments>http://www.blogjava.net/onejavaer/articles/72910.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/onejavaer/comments/commentRss/72910.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/onejavaer/services/trackbacks/72910.html</trackback:ping><description><![CDATA[引子：<br />我们以两个大型网站为例作比较：<br />51job和智联招聘（先声明我不是为他们作广告，仅以他们为例作技术上的比较）<br />51job采用的是比较&#8220;先进&#8221;的php技术，而智联用的是比较落后的asp.但我们可能会明显的感觉到51job的反应速度相比智联招聘实在是太慢了，为什么会这样？细心的人可能会察觉到了。智联虽然用的是asp,但他采用了另一种更巧妙的技术--asp生成静态页技术。所有的动态页基本上都转换成了html静态页，不用访问数据库，当然反应快了。<br />下面我们讨论一下jsp怎么转换成html??<br />首先要做一个模板。后缀不限，但一般都用*.template例子 
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">html</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">head</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">title</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">#title#</span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">title</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">meta&#160;http</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">equiv</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Content-Type</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&#160;content</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">text/html;&#160;charset=gb2312</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">LINK&#160;href</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">../css.css</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&#160;rel</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">stylesheet&#160;type</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">text</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">css</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">head</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">body</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">P&#160;align</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">center</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#title#</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">BR</span><span style="COLOR: #000000">&gt;&lt;</span><span style="COLOR: #000000">BR</span><span style="COLOR: #000000">&gt;&lt;</span><span style="COLOR: #000000">BR</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />作者：#author#</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">BR</span><span style="COLOR: #000000">&gt;&lt;</span><span style="COLOR: #000000">BR</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">BR</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#content#</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">BR</span><span style="COLOR: #000000">&gt;&lt;</span><span style="COLOR: #000000">BR</span><span style="COLOR: #000000">&gt;&lt;</span><span style="COLOR: #000000">BR</span><span style="COLOR: #000000">&gt;&lt;</span><span style="COLOR: #000000">BR</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">P</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">body</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">html</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div>做一个处理模板的类或者jsp文件、(为说明问题我们从简单入手以一个jsp文件为例)<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">filePath&#160;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&#160;request.getRealPath(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">WEB-INF/templates/template.htm</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&#160;out.print(filePath);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&#160;String&#160;templateContent</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">""</span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&#160;FileInputStream&#160;fileinputstream&#160;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&#160;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&#160;FileInputStream(filePath);</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">读取模块文件</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&#160;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&#160;lenght&#160;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&#160;fileinputstream.available();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&#160;</span><span style="COLOR: #0000ff">byte</span><span style="COLOR: #000000">&#160;bytes[]&#160;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&#160;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&#160;</span><span style="COLOR: #0000ff">byte</span><span style="COLOR: #000000">[lenght];<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&#160;fileinputstream.read(bytes);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&#160;fileinputstream.close();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&#160;templateContent&#160;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&#160;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&#160;String(bytes);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&#160;out.print(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">以下是模板内容：&lt;br&gt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">templateContent</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;br&gt;&#160;以下是置换以后的html内容&lt;br&gt;&lt;hr&gt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&#160;templateContent</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">templateContent.replaceAll(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">#title#</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,title);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&#160;templateContent</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">templateContent.replaceAll(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">#author#</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,editer);</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">替换掉模块中相应的地方</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&#160;templateContent</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">templateContent.replaceAll(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">#content#</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,content);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&#160;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&#160;根据时间得文件名</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&#160;Calendar&#160;calendar&#160;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&#160;Calendar.getInstance();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&#160;String&#160;fileame&#160;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&#160;String.valueOf(calendar.getTimeInMillis())&#160;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">.html</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&#160;fileame&#160;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&#160;request.getRealPath(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">fileame;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">生成的html文件保存路径</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&#160;out.print(templateContent);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&#160;FileOutputStream&#160;fileoutputstream&#160;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&#160;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&#160;FileOutputStream(fileame);</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">建立文件输出流</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">&#160;</span><span style="COLOR: #0000ff">byte</span><span style="COLOR: #000000">&#160;tag_bytes[]&#160;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&#160;templateContent.getBytes();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&#160;fileoutputstream.write(tag_bytes);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&#160;fileoutputstream.close();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div>嗯，核心技术就是这样了，如果大家要求的性能更高，可以改用freemarker做模板。freemarker的使用方法可以参阅另一篇文章《<a class="singleposttitle" id="viewpost1_TitleUrl" href="/zhanglijun33/archive/2006/07/20/freemarker.html"><font color="#333333">Freemarker 模板工具的作用及使用</font></a>》<br /><br />引自：<a href="/zhanglijun33/archive/2006/07/28/60568.aspx"><font color="#4371a6">http://www.blogjava.net/zhanglijun33/archive/2006/07/28/60568.aspx</font></a> <img src ="http://www.blogjava.net/onejavaer/aggbug/72910.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/onejavaer/" target="_blank">暗夜精灵</a> 2006-09-29 22:29 <a href="http://www.blogjava.net/onejavaer/articles/72910.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>