??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲中文字幕AV每天更新,亚洲熟妇无码一区二区三区,久久亚洲高清观看http://www.tkk7.com/wangxq/articles/107127.html扭{乑֝扭{乑֝Thu, 29 Mar 2007 01:42:00 GMThttp://www.tkk7.com/wangxq/articles/107127.htmlhttp://www.tkk7.com/wangxq/comments/107127.htmlhttp://www.tkk7.com/wangxq/articles/107127.html#Feedback0http://www.tkk7.com/wangxq/comments/commentRss/107127.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/107127.html  java实现Ҏ(gu)件的各种操作
 
 1。新建目?/span>
<%@ page contentType="text/html;charset=gb2312"%>
<%
String filePath="c:/aaa/";
filePath=filePath.toString();//
中文转换
java.io.File myFilePath=new java.io.File(filePath);
if(!myFilePath.exists())
myFilePath.mkdir();
%>
  2。新建文?/span>
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.io.*" %>
<%
String filePath="c:/
哈哈.txt";
filePath=filePath.toString();
File myFilePath=new File(filePath);
if(!myFilePath.exists())
myFilePath.createNewFile();
FileWriter resultFile=new FileWriter(myFilePath);
PrintWriter myFile=new PrintWriter(resultFile);
String strContent = "
中文试".toString();
myFile.println(strContent);
resultFile.close();
%>
 3。删除文?/span>
<%@ page contentType="text/html;charset=gb2312"%>
<%
String filePath="c:/
支出证明?/span>.xls";
filePath=filePath.toString();
java.io.File myDelFile=new java.io.File(filePath);
myDelFile.delete();
%>
 4。文件拷?/span>
<%@ page contentType="text/html; charset=gb2312" %>
<%@ page import="java.io.*" %>
<%
int bytesum=0;
int byteread=0; 
file://?/span>到流?/span>
InputStream inStream=new FileInputStream("c:/aaa.doc");
FileOutputStream fs=new FileOutputStream( "d:/aaa.doc");byte[]  buffer =new  byte[1444];
int length;
while ((byteread=inStream.read(buffer))!=-1)
 {
   out.println("<DT><B>"+byteread+"</B></DT>");
   bytesum+=byteread;
   System.out.println(bytesum);
   fs.write(buffer,0,byteread);
 } 
inStream.close();
%>
 5。整个文件夹拯
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.io.*" %>
<%String url1="C:/aaa";
  String url2="d:/java/";
  (new File(url2)).mkdirs();
 File[] file=(new File(url1)).listFiles();
 for(int i=0;i<file.length;i++){
  if(file[i].isFile()){
   file[i].toString();
   FileInputStream input=new FileInputStream(file[i]);
   FileOutputStream output=new FileOutputStream(url2+"/"+(file[i].getName()).toString());
   byte[] b=new byte[1024*5];
    int len;
    while((len=input.read(b))!=-1){
    output.write(b,0,len);
    }
    output.flush();
    output.close();
    input.close();
  }
 }
%>
 6。文件下?/span>
<%@ page contentType="text/html; charset=gb2312" %>
<%@ page import="java.io.*" %>
<%
  String fileName = "zsc104.swf".toString();
//?/span>
到流?/span>
InputStream inStream=new FileInputStream("c:/zsc104.swf");
//?/span>
|输出的格式
  response.reset();
  response.setContentType("bin");
  response.addHeader("Content-Disposition","attachment; filename=\"" + fileName + "\"");
//?/span>
环取出流中的数据
  byte[] b = new byte[100];
  int len;
  while((len=inStream.read(b)) >0)
  response.getOutputStream().write(b,0,len);  
  inStream.close();
%>
 7。数据库字段中的文g下蝲
<%@ page contentType="text/html; charset=gb2312" %>
<%@ page import="java.sql.*"%>
<%@ page import="java.lang.*" %>
<%@ page import="java.io.*" %>
<%@ page import="com.jspsmart.upload.*" %>
<%@ page import="DBstep.iDBManager2000.*"%>
<%
int bytesum=0;
int byteread=0;
//?/span>
开数据?/span>
ResultSet result=null;
String Sql=null;
PreparedStatement prestmt=null; 
DBstep.iDBManager2000 DbaObj=new DBstep.iDBManager2000();
DbaObj.OpenConnection();
//?/span>
得数据库中的数据
Sql="select  *  from  t_local_zhongzhuan ";
result=DbaObj.ExecuteQuery(Sql);
result.next();
file://?/span>数据库中的数据读到流?/span>
InputStream inStream=result.getBinaryStream("content");
FileOutputStream fs=new FileOutputStream( "c:/dffdsafd.doc");
byte[]  buffer =new  byte[1444];
int length;
while ((byteread=inStream.read(buffer))!=-1)
  {
     out.println("<DT><B>"+byteread+"</B></DT>");
     bytesum+=byteread;
     System.out.println(bytesum);
     fs.write(buffer,0,byteread);
     }
%>
 8。把|页保存成文?/span>
<%@ page import="java.text.*"%>
<%@ page import="java.util.*"%>
<%@ page import="java.io.*"%>
<%@ page import="java.net.*"%>
<%
 URL stdURL = null;
 BufferedReader stdIn = null;
 PrintWriter stdOut = null;
 try {
  stdURL = new URL("http://www.163.com");
 }
 catch (MalformedURLException e) {
   throw e;
 }
try {
   stdIn = new BufferedReader(new InputStreamReader(stdURL.openStream()));
   stdOut = new PrintWriter(new BufferedWriter(new FileWriter("c:/163.html")));
 }
 catch (IOException e) {
 }
 /***?/span>URL指定的页面以的形式dQ写成指定的文g***/
 try {
   String strHtml = "";
   while((strHtml = stdIn.readLine())!=null) {
   stdOut.println(strHtml);
   }
 }
 catch (IOException e) {
   throw e;
 }
 finally {
   try {
     if(stdIn != null)
       stdIn.close();
     if(stdOut != null)
       stdOut.close();
   }
   catch (Exception e) {
     System.out.println(e);
   }
 }
%>
 9。直接下载网上的文g
<%@ page import="java.io.*"%>
<%@ page import="java.net.*"%&


扭{乑֝ 2007-03-29 09:42 发表评论
]]>
File的加?/title><link>http://www.tkk7.com/wangxq/articles/47569.html</link><dc:creator>扭{乑֝</dc:creator><author>扭{乑֝</author><pubDate>Tue, 23 May 2006 00:54:00 GMT</pubDate><guid>http://www.tkk7.com/wangxq/articles/47569.html</guid><wfw:comment>http://www.tkk7.com/wangxq/comments/47569.html</wfw:comment><comments>http://www.tkk7.com/wangxq/articles/47569.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/wangxq/comments/commentRss/47569.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/wangxq/services/trackbacks/47569.html</trackback:ping><description><![CDATA[有时候,我们需要以独占的方式访问某个文Ӟ因此Q需要在打开文gӞҎ(gu)件上锁,以防其他人或q程也访问该文g。Java本n提供?jin)俩U锁文g的方式:(x)<br />方式一Q用RandomAccessFilecL作文?br />RandomAccessFile的openҎ(gu)Q提供了(jin)参数Q实C独占的方式打开文gQ?br />new RandomAccessFile(file, "rws")<br />其中的“rws”参CQrw代表d方式Qs代表同步方式Q也是锁。这U方式打开的文Ӟ是独占方式?br /><br />方式二:(x)用文仉道QF(tun)ileChannelQ的锁功?br /><br />如:(x)<br /><br />RandomAccessFile raf = new RandomAccessFile(new File("c:\\test.txt"), "rw");<br /><br />FileChannel fc = raf.getChannel();<br />FileLock fl = fc.tryLock();<br /><br />if (fl.isValid()) {<br />System.out.println("get the lock!");<br /><br />但这俩种方式Q都只能通过RandomAccessFile讉K文gQ如果只能通过InputStream来访问文Ӟ如用DOM分析XML文gQ怎么办呢Q?br />其实QFileInputStream对象Q也提供?jin)getChannelҎ(gu)Q只是缺省的getChannelҎ(gu)Q不能锁住文Ӟ所以,如果需要,必自己重写一个getChannelҎ(gu)Q如Q?br />public FileChannel getChannel(FileInputStream fileIn, FileDescriptor fd) {<br />FileChannel channel = null;<br />synchronized (fileIn) {<br />channel = FileChannelImpl.open(fd, true, true, fileIn);<br />return channel;<br />}<br />}<br /><br />其实Q主要是打开文g的第三个参数控制?jin)对文g的操作模式,如果讄为falseQ就不能锁住文gQ缺省的getChannelҎ(gu)Q就是falseQ因此,不能锁住文g?br /><img src ="http://www.tkk7.com/wangxq/aggbug/47569.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/wangxq/" target="_blank">扭{乑֝</a> 2006-05-23 08:54 <a href="http://www.tkk7.com/wangxq/articles/47569.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>eclipse技?/title><link>http://www.tkk7.com/wangxq/articles/47057.html</link><dc:creator>扭{乑֝</dc:creator><author>扭{乑֝</author><pubDate>Fri, 19 May 2006 06:43:00 GMT</pubDate><guid>http://www.tkk7.com/wangxq/articles/47057.html</guid><wfw:comment>http://www.tkk7.com/wangxq/comments/47057.html</wfw:comment><comments>http://www.tkk7.com/wangxq/articles/47057.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/wangxq/comments/commentRss/47057.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/wangxq/services/trackbacks/47057.html</trackback:ping><description><![CDATA[ <p class="MsoNormal" style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align="left"> <b> <span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done">fromQ?a >http://www.99college.com/ReadNews.asp?NewsID=6628&BigClassName=JAVA&SmallClassName=%E5%B7%A5%E5%85%B7%E6%8C%87%E5%8D%97&SpecialID=22</a><br />热键:(x)<span lang="EN-US" twffan="done"><br /></span></span> </b> <span lang="EN-US" style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done">Template</span> <span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done">Q?span lang="EN-US" twffan="done">Alt + /<br /></span>修改处:(x)H口<span lang="EN-US" twffan="done">-></span>喜好讑֮<span lang="EN-US" twffan="done">-></span>工作?span lang="EN-US" twffan="done">-></span>按键<span lang="EN-US" twffan="done">-></span>~辑<span lang="EN-US" twffan="done">-></span>内容辅助?span lang="EN-US" twffan="done"><br /></span>个h?fn)惯Q?span lang="EN-US" twffan="done">Shift+SPACE(</span>I白<span lang="EN-US" twffan="done">)</span>?span lang="EN-US" twffan="done"><br /></span>易说明:(x)~辑E序代码Ӟ?span lang="EN-US" twffan="done">sysout +Template</span>启动键,?span lang="EN-US" twffan="done"><br /></span>?x)自动出玎ͼ?x)<span lang="EN-US" twffan="done">System.out.println(); </span>?span lang="EN-US" twffan="done"><br /></span><b>讑֮<span lang="EN-US" twffan="done">Template</span>的格式:(x)H口<span lang="EN-US" twffan="done">-></span>喜好讑֮<span lang="EN-US" twffan="done">->Java-></span>~辑?span lang="EN-US" twffan="done">-></span>模板?/b><span lang="EN-US" twffan="done"><br /><br /></span>E序代码自动排版Q?span lang="EN-US" twffan="done">Ctrl+Shift+F<br /></span>修改处:(x)H口<span lang="EN-US" twffan="done">-></span>喜好讑֮<span lang="EN-US" twffan="done">-></span>工作?span lang="EN-US" twffan="done">-></span>按键<span lang="EN-US" twffan="done">-></span>E序代码<span lang="EN-US" twffan="done">-></span>格式?span lang="EN-US" twffan="done"><br /></span>个h?fn)惯Q?span lang="EN-US" twffan="done">Alt+Z</span>?span lang="EN-US" twffan="done"><br /></span>自动排版讑֮Q窗?span lang="EN-US" twffan="done">-></span>喜好讑֮<span lang="EN-US" twffan="done">->Java-></span>E序代码格式制作E序?span lang="EN-US" twffan="done"><br /></span>样式面<span lang="EN-US" twffan="done">-></span>插?span lang="EN-US" twffan="done">tab(</span>而非I格?span lang="EN-US" twffan="done">)</span>以内~,该选项取消N?span lang="EN-US" twffan="done"><br /></span>Q下面空格数目填<span lang="EN-US" twffan="done">4</span>Q这样在自动~排时会(x)以空?span lang="EN-US" twffan="done">4</span>作羃排?span lang="EN-US" twffan="done"><br /><br /></span>快速执行程序:(x)<span lang="EN-US" twffan="done">Ctrl + F11<br /></span>个h?fn)惯Q?span lang="EN-US" twffan="done">ALT+X<br /></span>修改处:(x)H口<span lang="EN-US" twffan="done">-></span>喜好讑֮<span lang="EN-US" twffan="done">-></span>工作?span lang="EN-US" twffan="done">-></span>按键<span lang="EN-US" twffan="done">-></span>执行<span lang="EN-US" twffan="done">-></span>启动前一ơ的启动作业?span lang="EN-US" twffan="done"><br /></span>易说明:(x)W一ơ执行时Q它?x)询问(zhn)执行模式Q?span lang="EN-US" twffan="done"><br /></span>讄好后Q以后只要按q个热键Q它?yu)׃?x)快速执行?span lang="EN-US" twffan="done"><br /><alt+z(>< SPAN>排版?span lang="EN-US" twffan="done">)</span>?span lang="EN-US" twffan="done">ATL+X(</span>执行<span lang="EN-US" twffan="done">)>..</span>我觉得很手<span lang="EN-US" twffan="done">^___^<br /><br /></span>自动汇入所需要的cdQ?span lang="EN-US" twffan="done">Ctrl+Shift+O<br /></span>易说明:(x)<span lang="EN-US" twffan="done"><br /></span>假设我们没有<span lang="EN-US" twffan="done">Import</span>McdӞ当我们在E序里打入:(x)</alt+z(></span><span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?><o:p></o:p></span></span> </p> <p class="MsoNormal" style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align="left"> <span lang="EN-US" style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done">BufferedReader buf =<br />new BufferedReader(new InputStreamReader(System.in));</span> <span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="BACKGROUND: white; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align="left"> <span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done">此时<span lang="EN-US" twffan="done">Eclipse</span>?x)警C没有汇入cdQ这时我们只要按?span lang="EN-US" twffan="done">Ctrl+Shift+O<br /></span>Q它?yu)׃?x)自动帮我?span lang="EN-US" twffan="done">Import</span>cd?span lang="EN-US" twffan="done"><br /><br /></span>查看使用cd的原始码Q?span lang="EN-US" twffan="done">Ctrl+</span>鼠标左键点击<span lang="EN-US" twffan="done"><br /></span>易说明:(x)可以看到(zhn)所使用cd的原始码?span lang="EN-US" twffan="done"><br /><br /></span>选取的文字批注v来:(x)<span lang="EN-US" twffan="done">Ctrl+/<br /></span>易说明:(x)<span lang="EN-US" twffan="done">Debug</span>时很方便?span lang="EN-US" twffan="done"><br /></span>修改处:(x)H口<span lang="EN-US" twffan="done">-></span>喜好讑֮<span lang="EN-US" twffan="done">-></span>工作?span lang="EN-US" twffan="done">-></span>按键<span lang="EN-US" twffan="done">-></span>E序代码<span lang="EN-US" twffan="done">-></span>Ҏ(gu)<span lang="EN-US" twffan="done"><br /><br /></span>视景切换Q?span lang="EN-US" twffan="done">Ctrl+F8<br /></span>个h?fn)惯Q?span lang="EN-US" twffan="done">Alt+S</span>?span lang="EN-US" twffan="done"><br /></span>修改处:(x)H口<span lang="EN-US" twffan="done">-></span>喜好讑֮<span lang="EN-US" twffan="done">-></span>工作?span lang="EN-US" twffan="done">-></span>按键<span lang="EN-US" twffan="done">-></span>H口<span lang="EN-US" twffan="done">-></span>下一个视景?span lang="EN-US" twffan="done"><br /></span>易说明:(x)可以方便我们快速切换编辑、除错等视景?span lang="EN-US" twffan="done"><br /><br /></span><b>密技:(x)</b><span lang="EN-US" twffan="done"><br /></span>一?span lang="EN-US" twffan="done">Eclipse</span>可同时切换,英文、繁体、简体显C:(x)<span lang="EN-US" twffan="done"><br />1.</span>首先要先安装完中文化包?span lang="EN-US" twffan="done"><br />2.</span>在桌面的快捷方式后面加上参数卛_Q?span lang="EN-US" twffan="done"><br /></span>英文<span lang="EN-US" twffan="done">-> -nl "zh_US"<br /></span>J体<span lang="EN-US" twffan="done">-> -nl "zh_TW"<br /></span>?span lang="EN-US" twffan="done">-> -nl "zh_CN"</span>?span lang="EN-US" twffan="done"><br />(</span>其它语系以此cL<span lang="EN-US" twffan="done">)<br /></span>像我<span lang="EN-US" twffan="done">2.1.2</span>中文化后Q我在我桌面?span lang="EN-US" twffan="done">Eclipse</span>快捷方式加入参数<span lang="EN-US" twffan="done">-n1 "zh_US"</span>?span lang="EN-US" twffan="done"><br />"C:\Program Files\eclipse\eclipse.exe" -n "zh_US"<br /></span>接口׃(x)变回英文语系噜?span lang="EN-US" twffan="done"><br /><br /></span>利用<span lang="EN-US" twffan="done">Eclipse</span>Q在<span lang="EN-US" twffan="done">Word</span>~辑文书时可不必程序代码重新编排:(x)<span lang="EN-US" twffan="done"><br /></span>?span lang="EN-US" twffan="done">Eclipse</span>E序~辑区的E序代码整个复制下来<span lang="EN-US" twffan="done">(Ctrl+C)</span>Q直接脓(chung)<span lang="EN-US" twffan="done">(Ctrl+V)</span>?span lang="EN-US" twffan="done"><br />Word</span>?span lang="EN-US" twffan="done">WordPad</span>上,(zhn)将?x)发现?span lang="EN-US" twffan="done">Word</span>里的E序代码格式Q跟<span lang="EN-US" twffan="done">Eclipse<br /></span>所讑֮的完全一P包括字型、羃排、关键词颜色。我曾试q?span lang="EN-US" twffan="done">JBuilder<br /></span>?span lang="EN-US" twffan="done">GEL</span>?span lang="EN-US" twffan="done">NetBeans...</span>使用复制贴上Ӟ只有~排格式一P字型、颜<span lang="EN-US" twffan="done"><br /></span>色等都不?x)改变?span lang="EN-US" twffan="done"><br /><br /></span><b>外挂:(x)</b><span lang="EN-US" twffan="done"><br /></span>外挂安装Q将外挂包下载回来后Q将其解压羃后,(zhn)会(x)发现<span lang="EN-US" twffan="done">features</span>?span lang="EN-US" twffan="done"><br />plugins</span>q?span lang="EN-US" twffan="done">2</span>个数据夹Q将里面的东襉K复制或移动到<span lang="EN-US" twffan="done">Eclipse</span>?span lang="EN-US" twffan="done">features<br /></span>?span lang="EN-US" twffan="done">plugins</span>数据夹内后,重新启动<span lang="EN-US" twffan="done">Eclipse</span>卛_?span lang="EN-US" twffan="done"><br /><br /></span>?span lang="EN-US" twffan="done">Eclipse</span>可以?span lang="EN-US" twffan="done">JBuilderX</span>一样用拖拉方式徏?span lang="EN-US" twffan="done">GUI</span>的外挂:(x)<span lang="EN-US" twffan="done"><br />1.Jigloo SWT/Swing GUI Builder </span>Q?span lang="EN-US" twffan="done"><br /></span></span> <span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done"> <a target="_blank"> <span style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done">http://cloudgarden.com/jigloo/index.html</span> </a> <br /> </span> <span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done">下蝲此版本:(x)<span lang="EN-US" twffan="done">Jigloo plugin for Eclipse (using Java 1.4 or 1.5)<br /></span>安装后即可由档案<span lang="EN-US" twffan="done">-></span>新徏<span lang="EN-US" twffan="done">-></span>其它<span lang="EN-US" twffan="done">->GUI Form</span>选取要徏构的<span lang="EN-US" twffan="done">GUI</span>cd?span lang="EN-US" twffan="done"><br /><br />2.Eclipse Visual Editor Project</span>Q?span lang="EN-US" twffan="done"><br /></span></span> <span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done"> <a target="_blank"> <span style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done">http://www.eclipse.org/vep/</span> </a> <br /> </span> <span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done">炚w下?span lang="EN-US" twffan="done">Download Page</span>Q再炚w?span lang="EN-US" twffan="done">Latest Release 0.5.0</span>q入下蝲?span lang="EN-US" twffan="done"><br /></span>除了(jin)<span lang="EN-US" twffan="done">VE-runtime-0.5.0.zip</span>要下载外Q以下这<span lang="EN-US" twffan="done">2</span>个也要:(x)<span lang="EN-US" twffan="done"><br />EMF build 1.1.1: (build page) (download zip) <br />GEF Build 2.1.2: (build page) (download zip) <br /><br />3.0 M8</span>版本Q请下蝲Q?span lang="EN-US" twffan="done"><br />EMF build I200403250631<br />GEF Build I20040330<br />VE-runtime-1.0M1<br /><br /></span>安装成功后,便可?span lang="EN-US" twffan="done">File->New->Visual Class</span>开?span lang="EN-US" twffan="done">UI</span>设计?span lang="EN-US" twffan="done"><br /></span>安装成功后,卛_由新?span lang="EN-US" twffan="done">->Java->AWT</span>?span lang="EN-US" twffan="done">Swing</span>里选择<span lang="EN-US" twffan="done"><br /></span>所要徏构的<span lang="EN-US" twffan="done">GUI</span>cd开始进行设计?span lang="EN-US" twffan="done">VE</span>必须配合着对应<span lang="EN-US" twffan="done"><br /></span>版本Q才能正怋用,否则即安装成功Q用上仍会(x)<span lang="EN-US" twffan="done"><br /></span>有问题?span lang="EN-US" twffan="done"><br /><br /></span>使用<span lang="EN-US" twffan="done">Eclipse</span>来开?span lang="EN-US" twffan="done">JSP</span>E序Q?span lang="EN-US" twffan="done"><br /></span>外挂名称Q?span lang="EN-US" twffan="done">lomboz(</span>下蝲面<span lang="EN-US" twffan="done">)<br /></span></span> <span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done"> <a target="_blank"> <span style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done">http://forge.objectweb.org/project/showfiles.php?group_id=97</span> </a> <br /> </span> <span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done">请选择适合自己版本?span lang="EN-US" twffan="done">lomboz</span>下蝲Q?span lang="EN-US" twffan="done">lomboz.212.p1.zip</span>表示<span lang="EN-US" twffan="done">2.1.2</span>版,<span lang="EN-US" twffan="done"><br />lomboz.3m7.zip</span>表示<span lang="EN-US" twffan="done">M7</span>版本<span lang="EN-US" twffan="done">....</span>以此cL?span lang="EN-US" twffan="done"><br />lomboz</span>安装以及(qing)讄教学Q?span lang="EN-US" twffan="done"><br /></span></span> <span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done"> <a target="_blank"> <span style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done">Eclipse</span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">开发JSP-</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">教学文g</span> </span> </a> <br /> <br /> <b> <span style="COLOR: black" twffan="done">Java</span> </b> </span> <b> <span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done">?span lang="EN-US" twffan="done">exe</span>:(x)</span> </b> <span lang="EN-US" style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done"> <br /> </span> <span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done">实现方式Q?span lang="EN-US" twffan="done">Eclipse</span>搭配<span lang="EN-US" twffan="done">JSmooth(</span>免费<span lang="EN-US" twffan="done">)</span>?span lang="EN-US" twffan="done"><br />1.</span>先由<span lang="EN-US" twffan="done">Eclipse</span>制作包含<span lang="EN-US" twffan="done">Manifest</span>?span lang="EN-US" twffan="done">JAR</span>?span lang="EN-US" twffan="done"><br /></span></span> <span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done"> <a target="_blank"> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">制作教学</span> </span> </a> <br /> <span style="COLOR: black" twffan="done">2.</span> </span> <span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done">使用<span lang="EN-US" twffan="done">JSmooth</span>做好的<span lang="EN-US" twffan="done">JAR</span>包装?span lang="EN-US" twffan="done">EXE</span>?span lang="EN-US" twffan="done"><br />JSmooth</span>下蝲面Q?span lang="EN-US" twffan="done"><br /></span></span> <span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done"> <a target="_blank"> <span style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done">http://jsmooth.sourceforge.net/index.php</span> </a> <br /> <span style="COLOR: black" twffan="done">3.</span> </span> <span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done">制作完成?span lang="EN-US" twffan="done">exe</span>文gQ可在有装置<span lang="EN-US" twffan="done">JRE</span>?span lang="EN-US" twffan="done">Windows</span>上执行?span lang="EN-US" twffan="done"><br /><br /><b>Eclipse-Java</b></span><b>~辑器最佌定:(x)</b><span lang="EN-US" twffan="done"><br /></span>~辑器字型设定:(x)工作?span lang="EN-US" twffan="done">-></span>字型<span lang="EN-US" twffan="done">->Java</span>~辑器文字字型?span lang="EN-US" twffan="done"><br />(</span>讑֮<span lang="EN-US" twffan="done">Courier New -regular 10)<br /><br /></span>~辑器相兌定:(x)H口<span lang="EN-US" twffan="done">-></span>喜好讑֮<span lang="EN-US" twffan="done">->Java-></span>~辑?span lang="EN-US" twffan="done"><br /><br /></span>外观Q显C受强调对U显C的Ҏ(gu)受强调显C现行行?span lang="EN-US" twffan="done"><br /></span>昄打印边距Q将其勾选,<span lang="EN-US" twffan="done">Tab</span>宽度?span lang="EN-US" twffan="done">4</span>Q打印编距字D设<span lang="EN-US" twffan="done">80</span>?span lang="EN-US" twffan="done"><br /></span>E序代码协助Q采预设卛_?span lang="EN-US" twffan="done"><br /></span>语法Q可讑֮关键词、字W串{等的显C颜艌Ӏ?span lang="EN-US" twffan="done"><br /></span>附注Q采预设卛_?span lang="EN-US" twffan="done"><br /></span>输入Q全部字D都N?span lang="EN-US" twffan="done"><br /></span>动说明Q采预设卛_?span lang="EN-US" twffan="done"><br /></span>DQ采预设卛_?span lang="EN-US" twffan="done"><br /><br /></span><b>使自动排版排出来的效果,最W合<span lang="EN-US" twffan="done">Java</span>设计惯例的设定:(x)</b><span lang="EN-US" twffan="done"><br /></span>自动排版讑֮Q窗?span lang="EN-US" twffan="done">-></span>喜好讑֮<span lang="EN-US" twffan="done">->Java-></span>E序代码制作格式?span lang="EN-US" twffan="done"><br /><br /></span>换行Q全部不N?span lang="EN-US" twffan="done"><br /></span>分行Q行长度上限设:(x)<span lang="EN-US" twffan="done">80</span>?span lang="EN-US" twffan="done"><br /></span>样式Q只强制{型后插入I白N?span lang="EN-US" twffan="done"><br /></span>内羃I格数目Q设?span lang="EN-US" twffan="done">4</span>?span lang="EN-US" twffan="done"><br /><br /><b>Eclipse</b></span><b>的教学文Ӟ(x)</b><span lang="EN-US" twffan="done"><br /></span></span> <span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done"> <a target="_blank"> <span style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done">Eclipse 3.0</span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">pd热键?- </span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">中英对照解说?(by sungo)</span> </span> </a> <span style="COLOR: black" twffan="done">~New~<br /></span> <a target="_blank"> <span style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done">Window+GCC+CDT</span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">用Eclipse</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">开发C</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">、C++ (by sungo)</span> </span> </a> <span style="COLOR: black" twffan="done">~New~<br /><br /></span> </span> <span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done">其它Q?span lang="EN-US" twffan="done"><br /></span></span> <span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done"> <a target="_blank"> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">扩充Eclipse</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">的Java </span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">开发工?</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">中文)</span> </span> </a> <br /> <a target="_blank"> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">使用Eclipse</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">开发J2EE </span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">应用E序(</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">中文)</span> </span> </a> <br /> <a target="_blank"> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">使用Eclipse</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">q_q行除错(</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">中文)</span> </span> </a> <br /> <a target="_blank"> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">用Eclipse</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">q行XML </span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">开?</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">中文)</span> </span> </a> <br /> <a target="_blank"> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">开发Eclipse</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">外挂E序(</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">中文)</span> </span> </a> <br /> <a target="_blank"> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">国际化?zhn)的Eclipse</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">外挂E序(</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">英文)</span> </span> </a> <br /> <a target="_blank"> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">Swing</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">~辑器加入Eclipse(</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">英文)</span> </span> </a> <br /> <a target="_blank"> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">如何试你的Eclipse plug-in</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">W合国际?jng)场需?</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">英文)</span> </span> </a> <br /> <br /> <b> <span style="COLOR: black" twffan="done">Eclipse</span> </b> </span> <b> <span style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done">的相关网站:(x)</span> </b> <span lang="EN-US" style="COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done"> <br /> </span> <span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" twffan="done"> <a target="_blank"> <span style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done">http://eclipse-plugins.2y.net/eclipse/index.jsp</span> </a> <br /> <a target="_blank"> <span style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done">http://www.eclipseplugincentral.com/</span> </a> <br /> <a target="_blank"> <span style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done">Eclipse</span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">相关教学[</span> </span> <span lang="EN-US" style="COLOR: black; TEXT-DECORATION: none; text-underline: none" twffan="done"> <span lang="EN-US" twffan="done">体]</span> </span> </a> <span style="COLOR: black" twffan="done"> </span> <o:p> </o:p> </span> </p> <img src ="http://www.tkk7.com/wangxq/aggbug/47057.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/wangxq/" target="_blank">扭{乑֝</a> 2006-05-19 14:43 <a href="http://www.tkk7.com/wangxq/articles/47057.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用POI中的HSSF创徏Excel文ghttp://www.tkk7.com/wangxq/articles/46648.html扭{乑֝扭{乑֝Wed, 17 May 2006 08:46:00 GMThttp://www.tkk7.com/wangxq/articles/46648.htmlhttp://www.tkk7.com/wangxq/comments/46648.htmlhttp://www.tkk7.com/wangxq/articles/46648.html#Feedback0http://www.tkk7.com/wangxq/comments/commentRss/46648.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/46648.html 使用POI中的HSSF创徏Excel文g
from: http://www.cn-java.com/target/news.php?news_id=2510

出处 CN-JAVA译Q?孤魂一W    ?/p>


作?孤魂一W?bingo_ge@hotmail.com) 日期Q?003-05-05

介绍:
Jakarta_POI 使用JavadExcel(97-2002)文gQ可以满_部分的需要?br />因ؓ(f)刚好有一个项目用到?jin)这个工P׃(jin)Ҏ(gu)间顺便翻译了(jin)一下POI本n
带的一个Guide.有一些节减和修改Q希望给使用q个目的h一些入门帮助?br />POI 下面有几个自目:HSSF用来实现Excel 的读?以下是HSSF的主?br />http://jakarta.apache.org/poi/hssf/index.html
下面的介l是Z以下地址的翻译:(x)
http://jakarta.apache.org/poi/hssf/quick-guide.html
目前的版本ؓ(f)1.51应该是很长时间之内的一个稳定版Q但HSSF提供的Sample不是Z
1.51所写,所以用的时候需要适当的注?
其实POI下面的几个子目侧重不同d Word 的HDF正在开发当?
XML下的FOP(http://xml.apache.org/fop/index.html)
可以输出pdf文gQ也是比较好的一个工?br />目录:
创徏一个workbook
创徏一个sheet
创徏cells
创徏日期cells
讑֮单元格格?br />
说明Q?br />以下可能需要用到如下的类
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;

创徏workbook

HSSFWorkbook wb = new HSSFWorkbook();
//使用默认的构造方法创建workbook
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
//指定文g?br />wb.write(fileOut);
//输出到文?br />fileOut.close();

创徏一个sheet

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet1 = wb.createSheet("new sheet");
//workbook创徏sheet
HSSFSheet sheet2 = wb.createSheet("second sheet");
//workbook创徏另外的sheet
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();

创徏cells
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
//注意以下的代码很多方法的参数是short 而不是int 所以需要做一ơ类型{?br />HSSFRow row = sheet.createRow((short)0);
//sheet 创徏一?br />HSSFCell cell = row.createCell((short)0);
//行创Z个单元格
cell.setCellValue(1);
//讑֮单元格的?br />//值的cd参数有多中double ,String ,boolean,
row.createCell((short)1).setCellValue(1.2);
row.createCell((short)2).setCellValue("This is a string");
row.createCell((short)3).setCellValue(true);

// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();

创徏日期cells
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");

HSSFRow row = sheet.createRow((short)0);

HSSFCell cell = row.createCell((short)0);
//讑֮gؓ(f)日期
cell.setCellValue(new Date());

HSSFCellStyle cellStyle = wb.createCellStyle();
//指定日期昄格式
cellStyle.setDataFormat(HSSFDataFormat.getFormat("m/d/yy h:mm"));
cell = row.createCell((short)1);
cell.setCellValue(new Date());
//讑֮单元格日期显C格?br />cell.setCellStyle(cellStyle);

FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();


讑֮单元格格?br />单元格格式的讑֮有很多Ş式包括单元格的对齐方式,内容的字体设|,
单元格的背景色等Q因为Ş式比较多Q只举一些例?以下的例子在
POI1.5中可能会(x)有所改变具体查看API.
..........
// Aqua background
HSSFCellStyle style = wb.createCellStyle();
//创徏一个样?br />style.setFillBackgroundColor(HSSFCellStyle.AQUA);
//讑֮此样式的的背景颜色填?br />style.setFillPattern(HSSFCellStyle.BIG_SPOTS);

//样式的填充类型?br />//有多U式样如:
//HSSFCellStyle.BIG_SPOTS
//HSSFCellStyle.FINE_DOTS
//HSSFCellStyle.SPARSE_DOTS{?br />style.setAlignment(HSSFCellStyle.ALIGN_CENTER );
//居中寚w
style.setFillBackgroundColor(HSSFColor.GREEN.index);
//讑֮单元个背景颜?br />style.setFillForegroundColor(HSSFColor.RED.index);
//讄单元格显C颜?br />HSSFCell cell = row.createCell((short) 1);
cell.setCellValue("X");
cell.setCellStyle(style);
参考:(x)http://jakarta.apache.org/poi/hssf/quick-guide.html

http://spaces.msn.com/qiqiboy/blog/

扭{乑֝ 2006-05-17 16:46 发表评论
]]>
_֓文章http://www.tkk7.com/wangxq/articles/39384.html扭{乑֝扭{乑֝Wed, 05 Apr 2006 06:59:00 GMThttp://www.tkk7.com/wangxq/articles/39384.htmlhttp://www.tkk7.com/wangxq/comments/39384.htmlhttp://www.tkk7.com/wangxq/articles/39384.html#Feedback0http://www.tkk7.com/wangxq/comments/commentRss/39384.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/39384.html IBATIS—方便的Java开源持久层框架(O/R Mapping解决Ҏ(gu))
http://www.sman.cn/netfetch/article.asp?id=407

什么是持久化和对象关系映射ORM技?/font>

http://www.volitation.net/Article/print.asp?SelectID=7
Hibernate技术主?/font>
http://www.csdn.net/subject/hibernate/
?sh)子?br />http://www.00083.com/Soft/ShowElite.asp?page=3
值得x的持久化技术:(x) hibernate
http://www.huihoo.com/java/hibernate/index.htm

java中的reflect机制!!!

http://www.tkk7.com/anders0913/archive/2005/11/17/20185.html

Java中的cd机?br />http://www.daima.com.cn/Info/121/Info36999/

Spring Framework 开发参考手?br />http://www.jactiongroup.net/reference/html/index.html

java.util包(二)(j)
http://teach.yuxinhuayuan.com/A200507/2005-07-24/165807.html
【JDK核心(j)API?/td>

http://teach.yuxinhuayuan.com/Dev/Programme/Java/api/
一个中q职a(b)子对应届生谈招聘
http://blog.chinaitlab.com/user1/170241/archives/2006/50082.html

StringcRStringBuffercRMathc?/strong>
http://teach.yuxinhuayuan.com/A200507/2005-07-24/165769.html
深入理解Collections API
http://teach.yuxinhuayuan.com/A200507/2005-07-24/165747.html
使用java.util.Timer
http://teach.yuxinhuayuan.com/A200507/2005-07-24/165745.html
初识Java内部c?br />http://www.frontfree.net/view/article_704.html
JAVA内部cȝ基本特征
http://www.tkk7.com/justinlei/articles/19873.html
static内部c?/strong>
http://www.koyoyo8.com/phpcms/data/2006/0222/article_1118.htm
http://www.chinaspx.com/archive/java/15304.htm

正确使用ArrayList和LinkedList—性能的改q?/strong> 
http://dev.csdn.net/article/19/19387.shtm

qͼ(x)ArrayList的查N度明显优于LinkedListQ但是LinkedList的插入,删除{操作的速度明显优于ArrayListQ?br />HashMap 的查N度高于ArrayListQ?br />
Java Gossip: LinkedList
http://www.jwit.edu.tw/~imitclub/javatech-2/JavaGossip-V2/JavaGossip-V2/LinkedList.htm

JAVA面试?COREJAVA部分
http://www.513pc.net/vc/java/200603/182.html
全面接触Java集合框架[转]
http://blog.tomxp.com/view/453.html

java性能
http://bingchen2005.blogchina.com/3461257.html

JavaU程ȝ
http://java.chinaitlab.com/line/373702.html

JAVA学习(fn)
http://feng5534.blog.my5q.com/



扭{乑֝ 2006-04-05 14:59 发表评论
]]>
Eclipse?qing)其插g介绍和下? -http://www.tkk7.com/wangxq/articles/38250.html扭{乑֝扭{乑֝Thu, 30 Mar 2006 06:13:00 GMThttp://www.tkk7.com/wangxq/articles/38250.htmlhttp://www.tkk7.com/wangxq/comments/38250.htmlhttp://www.tkk7.com/wangxq/articles/38250.html#Feedback0http://www.tkk7.com/wangxq/comments/commentRss/38250.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/38250.html from:http://tonng.blogchina.com/2453816.html TagQ?Eclipse    插g                                          

0.Eclipse下蝲
EMF,GEF - Graphical Editor Framework,UML2,VE - Visual Editor都在q里下蝲
http://www.eclipse.org/downloads/index.php
 
0.5.lomboz J2EE插g,开发JSP,EJB
http://forge.objectweb.org/projects/lomboz
1.MyEclipse J2EE开发插Ӟ支持SERVLET/JSP/EJB/数据库操U늭
http://www.myeclipseide.com
 
2.Properties Editor  ~辑java的属性文Ӟq可以自动存盘ؓ(f)Unicode格式
http://propedit.sourceforge.jp/index_en.html
 
3.Colorer Take  Z癄cd的文件按语法着?
http://colorer.sourceforge.net/
 
4.XMLBuddy ~辑xml文g
http://www.xmlbuddy.com
 
5.Code Folding  加入多种代码折叠功能Q比eclipse自带的更多)(j)
http://www.coffee-bytes.com/servlet/PlatformSupport
 
6.Easy Explorer  从eclipse中访问选定文g、目录所在的文g?
http://easystruts.sourceforge.net/
 
7.Fat Jar 打包插gQ可以方便的完成各种打包dQ可以包含外部的包等
http://fjep.sourceforge.net/
 
8.RegEx Test 试正则表达?
http://brosinski.com/stephan/archives/000028.php
 
9.JasperAssistant 报表插gQ强Q要qQ?
http://www.jasperassistant.com/
 
10.Jigloo GUI Builder QAQӞ的GQテ~辑插g
http://cloudgarden.com/jigloo/
 
11.Profiler 性能跟踪、测量工P能跟t、测量Q程?
http://sourceforge.net/projects/eclipsecolorer/
 
12.AdvanQas 提供对if/else{条件语句的提示和快捷帮助(自动更改l构{)(j)
http://eclipsecolorer.sourceforge.net/advanqas/index.html
 
13.Log4E Log4j插gQ提供各U和Log4j相关的Q务,如ؓ(f)Ҏ(gu)、类d一个logger{?
http://log4e.jayefem.de/index.php/Main_Page
 
14.VSSPlugin VSS插g
http://sourceforge.net/projects/vssplugin
 
15.Implementors 提供跌{C个方法的实现c,而不是接中的功能Q实?Q?
http://eclipse-tools.sourceforge.net/implementors/
 
16.Call Hierarchy 昄一个方法的调用层次Q被哪些Ҏ(gu)调,调了(jin)哪些Ҏ(gu)Q?
http://eclipse-tools.sourceforge.net/call-hierarchy/index.html
 
17.EclipseTidy (g)查和格式化HTML/XML文g
http://eclipsetidy.sourceforge.net/
 
18.Checkclipse (g)查代码的风格、写法是否符合规?
http://www.mvmsoft.de/content/plugins/checkclipse/checkclipse.htm
 
19.Hibernate Synchronizer Hibernate插gQ自动映等
http://www.binamics.com/hibernatesync/
 
20.VeloEclipse  Velocity插g
http://propsorter.sourceforge.net/
 
21.EditorList 方便的列出所有打开的Editor
http://editorlist.sourceforge.net/
 
22.MemoryManager 内存占用率的监视
http://cloudgarden.com/memorymanager/
 
23.swt-designer java的GUI插g
http://www.swt-designer.com/
 
24.TomcatPlugin 支持Tomcat插g
http://www.sysdeo.com/eclipse/tomcatPlugin.html
 
25.XML Viewer
http://tabaquismo.freehosting.net/ignacio/eclipse/xmlview/index.html
 
26.quantum 数据库插?br />http://quantum.sourceforge.net/
 
27.Dbedit 数据库插?br />http://sourceforge.net/projects/dbedit
 
28.clay.core 可视化的数据库插?
http://www.azzurri.jp/en/software/index.jsp
http://www.azzurri.jp/eclipse/plugins
 
29.hiberclipse hibernate插g
http://hiberclipse.sourceforge.net
http://www.binamics.com/hibernatesync
 
30.struts-console Struts插g
http://www.jamesholmes.com/struts/console/
 
31.easystruts Struts插g
http://easystruts.sourceforge.net
 
32.veloedit Velocity插g
http://veloedit.sourceforge.net/
 
33.jalopy 代码整理插g
http://jalopy.sourceforge.net/
 
34.JDepend 包关pd?br />http://andrei.gmxhome.de/jdepend4eclipse/links.html
 
35.Spring IDE Spring插g
http://springide-eclip.sourceforge.net/updatesite/
 
36.doclipse 可以产生xdoclet 的代码提C?br />http://beust.com/doclipse/



扭{乑֝ 2006-03-30 14:13 发表评论
]]>
[转]清除windowspȝ垃圾文ghttp://www.tkk7.com/wangxq/articles/35618.html扭{乑֝扭{乑֝Thu, 16 Mar 2006 04:34:00 GMThttp://www.tkk7.com/wangxq/articles/35618.htmlhttp://www.tkk7.com/wangxq/comments/35618.htmlhttp://www.tkk7.com/wangxq/articles/35618.html#Feedback0http://www.tkk7.com/wangxq/comments/commentRss/35618.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/35618.html 自:(x)http://www.tzblog.cn/user1/1144/archives/2006/13387.html
 
  Z的电(sh)脑系l清除淤塞的垃圾Q轻松流畅上|你是否注意C的电(sh)脑系l磁盘的可用I间正在一天天在减呢Q是不是像老去的猴王一样动作一天比一天迟~呢Q没错!在Windows在安装和使用q程中都?x)生相当多的垃圾文Ӟ包括临时文gQ如Q?.tmp?._mpQ日志文Ӟ*.logQ、(f)时帮助文Ӟ*.gidQ、磁盘检查文Ӟ*.chkQ、(f)时备份文Ӟ如:(x)*.old?.bakQ以?qing)其他?f)时文件?

  特别是如果一D|间不清理IE的(f)时文件夹“Temporary Internet Files”,其中的缓存文件有时会(x)占用上百MB的磁盘空间。这些垃圾文件不仅仅费?jin)宝늚盘I间Q严重时q会(x)使系l运行慢如蜗牛。这点相信你肯定忍受不了(jin)吧!所以应?qing)时清理pȝ的垃圾文件的淤塞Q保持系l的“苗条”n材,L畅上网Q朋友来吧,现在p我们一h快速清除系l垃圑֐Q!

  新徏一个记事本q输入以下的内容Q?/P>

  @echo off
  echo 正在清除pȝ垃圾文gQ请E等......
  del /f /s /q %systemdrive%\*.tmp
  del /f /s /q %systemdrive%\*._mp
  del /f /s /q %systemdrive%\*.log
  del /f /s /q %systemdrive%\*.gid
  del /f /s /q %systemdrive%\*.chk
  del /f /s /q %systemdrive%\*.old
  del /f /s /q %systemdrive%\recycled\*.*
  del /f /s /q %windir%\*.bak
  del /f /s /q %windir%\prefetch\*.*
  rd /s /q %windir%\temp & md %windir%\temp
  del /f /q %userprofile%\cookies\*.*
  del /f /q %userprofile%\recent\*.*
  del /f /s /q "%userprofile%\Local Settings\Temporary Internet Files\*.*"
  del /f /s /q "%userprofile%\Local Settings\Temp\*.*"
  del /f /s /q "%userprofile%\recent\*.*"
  echo 清除pȝ垃圾完成Q?BR>  echo. & pause

  最后将它保存,然后更名为“清除系l垃?bat”!okQ你的垃圾清除器p样制作成功了(jin)Q?/P>

  以后只要双击q行该文Ӟ当屏q提C“清除系l垃圑֮成!p你一个“苗条”的pȝ?jin)!Q到时候再看看你的?sh)脑Q是不是急速如飞呢Q?/P>

扭{乑֝ 2006-03-16 12:34 发表评论
]]>
[转]synchronized详解http://www.tkk7.com/wangxq/articles/35341.html扭{乑֝扭{乑֝Wed, 15 Mar 2006 01:09:00 GMThttp://www.tkk7.com/wangxq/articles/35341.htmlhttp://www.tkk7.com/wangxq/comments/35341.htmlhttp://www.tkk7.com/wangxq/articles/35341.html#Feedback0http://www.tkk7.com/wangxq/comments/commentRss/35341.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/35341.htmlhttp://erichcn.blogdriver.com/erichcn/847568.html

不要重新分配被锁定对象的对象引用

synchronized 关键字锁定对象。对象是?synchronized 代码内部被锁定的Q这一点对此对象以?qing)(zhn)对其对象引用所作的更改意味着什么呢Q对一个对象作同步处理只锁定该对象。但是,必须注意不要重新分配被锁定对象的对象引用。那么如果这样做?x)发生什么情况呢Q请考虑下面q段代码Q它实现?jin)一?StackQ?

class Stack
{
private int StackSize = 10;
private int[] intArr = new int[stackSize];
private int index; //Stack 中的下一个可用位|?

public void push(int val)
{
synchronized(intArr) {
//如果已满Q则重新分配整数数组Q即我们?StackQ?
if (index == intArr.length)
{
stackSize *= 2;
int[] newintArr == new int[stackSize];
System.arraycopy(intArr, 0, newintArr, 0, intArr.length);
intArr = newintArr;
}
intArr[index] == val;
index++;
}
}

public int pop()
{
int retval;
synchronized(intArr) {
if (index > 0)
{
retval = intArr[index-1]; //(g)索|
index--; //q Stack 减少 1 个倹{?
return retval;
}
}
throw new EmptyStackException();
}
//...
}


q段代码用数l实C(jin)一?Stack。创Z(jin)一个初始大ؓ(f) 10 的数l来容纳整数倹{此cdC(jin) push ?pop Ҏ(gu)来模?Stack 的用。在 push Ҏ(gu)中,如果数组中没有更多的I间来容U_入的|则数l被重新分配以创建更多的存储I间。(故意没有?Vector 来实现这个类。Vector 中不能储存基本类型。)(j)

h意,q段代码是要由多个线E进行访问的。push ?pop Ҏ(gu)每次对该cȝ׃n实例数据的访问都是在 synchronized 块内完成的。这样就保证?jin)多个线E不能ƈ发访问此数组而生成不正确的结果?

q段代码有一个主要的~点。它Ҏ(gu)数数l对象作?jin)同步处理,而这个数l被 Stack cȝ intArr 所引用。当 push Ҏ(gu)重新分配此整数数l时Q这个缺点就?x)显露出来。当q种情况发生Ӟ对象引用 intArr 被重新指定ؓ(f)引用一个新的、更大的整数数组对象。请注意Q这是在 push Ҏ(gu)?synchronized 块执行期间发生的。此块针?intArr 变量引用的对象进行了(jin)同步处理。因此,在这D代码内锁定的对象不再被使用。请考虑以下的事件序列:(x)

U程 1 调用 push Ҏ(gu)q获?intArr 对象的锁?


U程 1 被线E?2 抢先?


U程 2 调用 pop Ҏ(gu)。此Ҏ(gu)因试图获取当前线E?1 ?push Ҏ(gu)中持有的同一个锁而阻塞?


U程 1 重新获得控制q新分配数l。intArr 变量现在引用一个不同的变量?


push Ҏ(gu)退出ƈ释放它对原来?intArr 对象的锁?


U程 1 再次调用 push Ҏ(gu)q获得新 intArr 对象的锁?


U程 1 被线E?2 抢先?


U程 2 获得?intArr 对象的对象锁q试图访问其内存?


现在U程 1 持有?intArr 引用的新对象的锁Q线E?2 持有?intArr 引用的旧对象的锁。因Z个线E持有不同的锁,所以它们可以ƈ发执?synchronized push ?pop Ҏ(gu)Q从而导致错误。很明显Q这不是所希望的结果?

q个问题是因 push Ҏ(gu)重新分配被锁定对象的对象引用而造成的。当某个对象被锁定时Q其他线E可能在同一个对象锁上被d。如果将被锁定对象的对象引用重新分配l另一个对象,其他U程的挂起锁则是针对代码中已不再相关的对象的?

(zhn)可以这样修正这D代码,L?intArr 变量的同步,而对 push ?pop Ҏ(gu)q行同步。通过?synchronized 关键字添加ؓ(f)Ҏ(gu)修饰W即可实现这一炏V正的代码如下所C:(x)

class Stack
{
//与前面相?..
public synchronized void push(int val)
{
//如果为空Q则重新分配整数数组Q即我们?StackQ?
if (index == intArr.length)
{
stackSize *= 2;
int[] newintArr = new int[stackSize];
System.arraycopy(intArr, 0, newintArr, 0, intArr.length);
intArr = newintArr;
}
intArr[index]= val;
index++;
}

public synchronized int pop()
{
int retval;
if (index > 0)
{
retval = intArr[index-1];
index--;
return retval;
}
throw new EmptyStackException();
}
}


q个修改更改?jin)实际上获取的锁。获取的锁是针对为其调用Ҏ(gu)的对象的Q而不是锁?intArr 变量所引用的对象。因取的锁不再针?intArr 所引用的对象,所以允总码重新指?intArr 对象引用?/SPAN>
Maximizing concurrency in Java programming
http://www-106.ibm.com/developerworks/ibm/library/it-haggar_concurrency/
Contents:
Avoid unnecessary synchronization
Use volatile to increase concurrency
Summary
Resources
About the author
Rate this article
Subscriptions:
dW newsletters
dW Subscription
(CDs and downloads)

Peter Haggar (haggar@us.ibm.com)
Senior Software Engineer , IBM
1 July 2001

When discussing concurrency, programmers typically look for ways to avoid its common problems. Concurrent access to data via multiple threads of execution, can cause stale, or invalid, reads and writes. In the Java programming language, the solution is to synchronize access to this data via the language's built-in synchronization mechanisms. The synchronized keyword is used to control access to shared data. However, synchronization ensures valid reads and writes of data at the cost of reduced concurrency. Because the Java language's synchronization mechanisms are not very granular, usage of it reduces the concurrency of your programs more than is sometimes needed. Less concurrency can result in poorly behaved and inefficient programs. This article outlines techniques to increase the concurrency of your code while maintaining its correctness. The first step to increasing concurrency is to avoid unnecessary synchronization.

Avoid unnecessary synchronization
The Java language provides synchronization to allow multiple threads of execution to access the same objects safely. Adding unneeded synchronization is as bad as omitting necessary synchronization. Sometimes programmers, in search of thread-safe code, synchronize too many methods. Excess synchronization can lead to code that deadlocks or code that runs slowly. (For more information on the cost of synchronization, see Praxis 34 of Practical Java Programming Language Guide and my last column on bytecode.) One goal of your software is to run efficiently, without deadlocks.

Because of the way the synchronized keyword is implemented, the result is often unnecessary synchronization and less concurrency. For example, consider the following class:
代码:

class Test
{
  private int[] ia1;
  private int[] ia2;
  private double[] da1;
  private double[] da2;

  public synchronized void method1()
  {
    //Access ia1 and ia2
  }
  public synchronized void method2()
  {
    //Access ia1 and ia2
  }
  public synchronized void method3()
  {
    //Access da1 and da2
  }
  public synchronized void method4()
  {
    //Access da1 and da2
  }
  //...
}

This class is certainly thread safe. Each method must be declared synchronized in order to ensure the arrays are not corrupted by multiple threads accessing this object concurrently. For example, because method1 and method2 both access and potentially alter the arrays, ia1 and ia2 , access to them must be synchronized. The same is true of method3 and method4 .

Notice, however, that although method1 and method2 must be synchronized with each other, they do not need to be synchronized with either method3 or method4 . This is because method1 and method2 do not operate on data that method3 and method4 operate. This is also true for method3 and method4 with regard to method1 and method2 .

Unfortunately, this is how instance methods are sometimes synchronized in classes. Synchronization in the Java language is not very granular. Synchronization provides you with only one lock per object. In the previous code, if you create an object of class Test and call method1 on the main thread and method3 on a secondary thread, you pay an unnecessary performance penalty. These methods synchronize with one another even though there is no need for them to do so. Remember that when a method is declared synchronized , the lock obtained is the lock for the object on which the method is invoked. Therefore, both methods attempt to get the same lock.

To fix the problem in the previous code you need multiple locks per object. Because the Java language does not provide this, you must furnish your own mechanism. One way to accomplish this is to create objects as instance data that serve only to provide locks. The previous code is modified using this technique and looks like this:
代码:

class Test
{
  private int[] ia1;
  private int[] ia2;
  private double[] da1;
  private double[] da2;
  private byte[] lock1 = new byte[0];
  private byte[] lock2 = new byte[0];

  public void method1()
  {
   synchronized(lock1) {
      //Access ia1 and ia2
    }
  }
  public void method2()
  {
    synchronized(lock1) {
      //Access ia1 and ia2
    }
  }
  public void method3()
  {
    synchronized(lock2) {
      //Access da1 and da2
    }
  }
  public void method4()
  {
    synchronized(lock2) {
      //Access da1 and da2
    }
  }
  //...
}

Notice that this code no longer has synchronized methods. They are removed and replaced with synchronized blocks. This allows the synchronization to occur on different objects and allows the methods that can safely run concurrently to do so. For example, method1 is able to execute concurrently with method3 or method4 because they access different object locks.

A zero element array is used as the lock objects because such an array is cheaper to create than any other object. Creating a zero element array does not require a constructor call like the creation of Object does. Therefore, it executes faster. In addition, a byte array is used because it is often represented more compactly than an int array.

Care must be taken when using this technique. You must be sure that the methods you think can operate without synchronization are able to do so without causing errors. Debugging multithreaded code can be very time consuming, so it is important not to use this technique casually.

You might wonder why method1 and method2 do not lock both ia1 and ia2 instead of the lock1 object. This could be done, but it is more error prone. When you lock multiple objects, you must make sure to lock them in the same order throughout your code. Failure to do this can result in deadlock. For more on this problem and how to avoid it, see Praxis 52 of Practical Java Programming Language Guide.

Use volatile to increase concurrency
When variables are shared between threads, they must always be accessed properly to ensure that correct and valid values are manipulated. The JVM is guaranteed to treat reads and writes of data of 32 bits or less as atomic. This might lead some programmers to believe that access to shared variables does not need to be synchronized or the variables declared volatile. Consider this code:
代码:

class RealTimeClock
{
  private int clkID;
  private long clockTime;

  public int clockID()
  {
    return clkID;
  }
  public void setClockID(int id)
  {
    clkID = id;
  }

  public long time()
  {
    return clockTime;
  }
  public void setTime(long t)
  {
    clockTime = t;
  }
  //...
}

Now contemplate an implementation that uses the previous code. It might create an object of the RealTimeClock class and two threads. It could then call the methods of this class from the two threads.

The variables clkID and clockTime are stored in main memory. However, the Java language allows threads to keep private working copies of these variables. This enables a more efficient execution of the two threads. For example, when each thread reads and writes these variables, they can do so on the private working copies instead of accessing the variables from main memory. The private working copies are reconciled with main memory only at specific synchronization points.

The clockID and setClockID methods perform only a read and a write, respectively, on data of type int . Therefore, the operation of these methods is automatically atomic. However, given that the clkID variable could be stored in private working memory for each thread, consider the following possible sequence of events:

1. Thread 1 calls the setClockID method, passing a value of 5.
2. Thread 2 calls the setClockID method, passing a value of 10.
3. Thread 1 calls the clockID method, which returns the value 5.

This sequence of events is possible because the clkID variable is not guaranteed to be reconciled with main memory. During step 1, thread 1 places the value 5 in its working memory. When step 2 executes, thread 2 places the value 10 in its working memory. When step 3 executes, thread 1 reads the value from its working memory and returns 5. At no point are the values reconciled with main memory.

There are two ways to fix this problem.

1. Access the clkID variable from a synchronized method or block.
2. Declare the clkID variable volatile.

Either solution requires the clkID variable to be reconciled with main memory. Accessing the clkID variable from a synchronized method or block does not allow that code to execute concurrently, but it does guarantee that the clkID variable in main memory is updated appropriately. Main memory is updated when the object lock is obtained before the protected code executes and when the lock is released after the protected code executes.

Declaring the clkID variable volatile allows the code to execute concurrently and also guarantees that the private working copy of the clkID variable is reconciled with main memory. This reconciliation, however, occurs each time the variable is accessed.

Also consider the time and setTime methods that operate on a variable of type long. These methods can exhibit the same problem described previously. They also have an additional problem. Data of type long is typically represented by bits spread across two 32-bit words. An implementation of the JVM might treat the operation on a -bit value as atomic, but most JVM implementations today do not. Instead, it treats such operations as two distinct 32-bit operations. Consider the following possible sequence of events with the clockTime instance variable:

1. Thread 1 calls the time method.
2. Thread 1 begins to read the clockTime instance variable and reads the first 32 bits.
3. Thread 1 is preempted by thread 2.
4. Thread 2 calls the setTime method. The setTime method performs two writes of 32 bits each to the clockTime instance variable, replacing both 32-bit values with different values.
5. Thread 2 is preempted by thread 1.
6. Thread 1 reads the second 32 bits of the clockTime instance variable and returns the result.

Note: Implementations of JVMs are encouraged to treat -bit operations as atomic but are not required to do so. This is because some popular microprocessors currently do not provide efficient atomic memory transactions on -bit values.

According to this sequence of events, the value returned by the time method is made up of the first 32 bits of the old value of the clockTime instance variable and the second 32 bits of the new value of the same instance variable. The value returned is not correct. This is because of the multiple reads and writes necessary for -bit data in the JVM. The private working memory and main memory issue discussed earlier are also problematic. You have the same two options to fix this problem: Synchronize access to the clockTime variable, or declare it volatile.

It is important to understand that atomic operations do not automatically mean thread-safe operations. In addition, whenever multiple threads share variables, it is important that they are accessed in a synchronized method or block, or that they are declared with the volatile keyword. This ensures that the variables are properly reconciled with main memory, thereby guaranteeing correct values at all times.

Whether you use volatile or synchronized depends on several factors. If concurrency is important and you are not updating many variables, consider using volatile. If you are updating many variables, however, using volatile might be slower than using synchronization. Remember that when variables are declared volatile, they are reconciled with main memory on every access. By contrast, when synchronized is used, the variables are reconciled with main memory only when the lock is obtained and when the lock is released. Consider using synchronized if you are updating many variables and do not want the cost of reconciling each of them with main memory on every access, or you want to eliminate concurrency for another reason.

The following table summarizes the differences between the synchronized and volatile keywords.

volatile and synchronized

synchronized
Advantages: Private working memory is reconciled with main memory when the lock is obtained and when the lock is released.
Disadvantages : Eliminates concurrency.

volatile
Advantages: Allows concurrency.
Disadvantages: Private working memory is reconciled with main memory on each variable access.

Summary
This article demonstrates two techniques for increasing the concurrency of your program while maintaining its accuracy. The volatile keyword and distinct lock objects are used to increase concurrency while maintaining correctness. These techniques should be considered when designing and writing multithreaded code. The more concurrency in your program, the more likely it is to behave as the user expects it to.

Resources

* Practical Java Programming Language Guide, Peter Haggar, Addison-Wesley, 2000, ISBN 0-201-616-7.

* The Java Virtual Machine Specification, Second Edition, Tim Lindholm and Frank Yellin, Addison-Wesley, 1999, ISBN 0-201-43294-3.

About the author
Peter Haggar is a Senior Software Engineer with IBM in Research Triangle Park, North Carolina and the author of the book, Practical Java Programming Language Guide, published by Addison-Wesley. He has a broad range of programming experience, having worked on development tools, class libraries, and operating systems. At IBM, Peter works on emerging Java technology and is currently focused on embedded and real-time Java. Peter is a frequent technical speaker on Java technology at numerous industry conferences. He has worked for IBM for more than 12 years and received a B.S. in Computer Science from Clarkson University in New York. He can be contacted at haggar@us.ibm.com.

Synchronization and the Java Memory Model
http://gee.cs.oswego.edu/dl/cpj/jmm.html
This set of excerpts from section 2.2 includes the main discussions on how the Java Memory Model impacts concurrent programming.

For information about ongoing work on the memory model, see Bill Pugh's Java Memory Model pages.

Consider the tiny class, defined without any synchronization:
代码:

final class SetCheck {
  private int  a = 0;
  private long b = 0;

  void set() {
    a =  1;
    b = -1;
  }

  boolean check() {
    return ((b ==  0) ||
            (b == -1 && a == 1));
  }
}

In a purely sequential language, the method check could never return false. This holds even though compilers, run-time systems, and hardware might process this code in a way that you might not intuitively expect. For example, any of the following might apply to the execution of method set:

* The compiler may rearrange the order of the statements, so b may be assigned before a. If the method is inlined, the compiler may further rearrange the orders with respect to yet other statements.
* The processor may rearrange the execution order of machine instructions corresponding to the statements, or even execute them at the same time.

* The memory system (as governed by cache control units) may rearrange the order in which writes are committed to memory cells corresponding to the variables. These writes may overlap with other computations and memory actions.

* The compiler, processor, and/or memory system may interleave the machine-level effects of the two statements. For example on a 32-bit machine, the high-order word of b may be written first, followed by the write to a, followed by the write to the low-order word of b.

* The compiler, processor, and/or memory system may cause the memory cells representing the variables not to be updated until sometime after (if ever) a subsequent check is called, but instead to maintain the corresponding values (for example in CPU registers) in such a way that the code still has the intended effect.

In a sequential language, none of this can matter so long as program execution obeys as-if-serial semantics. Sequential programs cannot depend on the internal processing details of statements within simple code blocks, so they are free to be manipulated in all these ways. This provides essential flexibility for compilers and machines. Exploitation of such opportunities (via pipelined superscalar CPUs, multilevel caches, load/store balancing, interprocedural register allocation, and so on) is responsible for a significant amount of the massive improvements in execution speed seen in computing over the past decade. The as-if-serial property of these manipulations shields sequential programmers from needing to know if or how they take place. Programmers who never create their own threads are almost never impacted by these issues.

Things are different in concurrent programming. Here, it is entirely possible for check to be called in one thread while set is being executed in another, in which case the check might be "spying" on the optimized execution of set. And if any of the above manipulations occur, it is possible for check to return false. For example, as detailed below, check could read a value for the long b that is neither 0 nor -1, but instead a half-written in-between value. Also, out-of-order execution of the statements in set may cause check to read b as -1 but then read a as still 0.

In other words, not only may concurrent executions be interleaved, but they may also be reordered and otherwise manipulated in an optimized form that bears little resemblance to their source code. As compiler and run-time technology matures and multiprocessors become more prevalent, such phenomena become more common. They can lead to surprising results for programmers with backgrounds in sequential programming (in other words, just about all programmers) who have never been exposed to the underlying execution properties of allegedly sequential code. This can be the source of subtle concurrent programming errors.

In almost all cases, there is an obvious, simple way to avoid contemplation of all the complexities arising in concurrent programs due to optimized execution mechanics: Use synchronization. For example, if both methods in class SetCheck are declared as synchronized, then you can be sure that no internal processing details can affect the intended outcome of this code.

But sometimes you cannot or do not want to use synchronization. Or perhaps you must reason about someone else's code that does not use it. In these cases you must rely on the minimal guarantees about resulting semantics spelled out by the Java Memory Model. This model allows the kinds of manipulations listed above, but bounds their potential effects on execution semantics and additionally points to some techniques programmers can use to control some aspects of these semantics (most of which are discussed in 2.4).

The Java Memory Model is part of The JavaTM Language Specification, described primarily in JLS chapter 17. Here, we discuss only the basic motivation, properties, and programming consequences of the model. The treatment here reflects a few clarifications and updates that are missing from the first edition of JLS.

The assumptions underlying the model can be viewed as an idealization of a standard SMP machine of the sort described in 1.2.4:

For purposes of the model, every thread can be thought of as running on a different CPU from any other thread. Even on multiprocessors, this is infrequent in practice, but the fact that this CPU-per-thread mapping is among the legal ways to implement threads accounts for some of the model's initially surprising properties. For example, because CPUs hold registers that cannot be directly accessed by other CPUs, the model must allow for cases in which one thread does not know about values being manipulated by another thread. However, the impact of the model is by no means restricted to multiprocessors. The actions of compilers and processors can lead to identical concerns even on single-CPU systems.

The model does not specifically address whether the kinds of execution tactics discussed above are performed by compilers, CPUs, cache controllers, or any other mechanism. It does not even discuss them in terms of classes, objects, and methods familiar to programmers. Instead, the model defines an abstract relation between threads and main memory. Every thread is defined to have a working memory (an abstraction of caches and registers) in which to store values. The model guarantees a few properties surrounding the interactions of instruction sequences corresponding to methods and memory cells corresponding to fields. Most rules are phrased in terms of when values must be transferred between the main memory and per-thread working memory. The rules address three intertwined issues:

Atomicity
Which instructions must have indivisible effects. For purposes of the model, these rules need to be stated only for simple reads and writes of memory cells representing fields - instance and static variables, also including array elements, but not including local variables inside methods.
Visibility
Under what conditions the effects of one thread are visible to another. The effects of interest here are writes to fields, as seen via reads of those fields.
Ordering
Under what conditions the effects of operations can appear out of order to any given thread. The main ordering issues surround reads and writes associated with sequences of assignment statements.

When synchronization is used consistently, each of these properties has a simple characterization: All changes made in one synchronized method or block are atomic and visible with respect to other synchronized methods and blocks employing the same lock, and processing of synchronized methods or blocks within any given thread is in program-specified order. Even though processing of statements within blocks may be out of order, this cannot matter to other threads employing synchronization.

When synchronization is not used or is used inconsistently, answers become more complex. The guarantees made by the memory model are weaker than most programmers intuitively expect, and are also weaker than those typically provided on any given JVM implementation. This imposes additional obligations on programmers attempting to ensure the object consistency relations that lie at the heart of exclusion practices: Objects must maintain invariants as seen by all threads that rely on them, not just by the thread performing any given state modification.

The most important rules and properties specified by the model are discussed below.

Atomicity
Accesses and updates to the memory cells corresponding to fields of any type except long or double are guaranteed to be atomic. This includes fields serving as references to other objects. Additionally, atomicity extends to volatile long and double. (Even though non-volatile longs and doubles are not guaranteed atomic, they are of course allowed to be.)

Atomicity guarantees ensure that when a non-long/double field is used in an expression, you will obtain either its initial value or some value that was written by some thread, but not some jumble of bits resulting from two or more threads both trying to write values at the same time. However, as seen below, atomicity alone does not guarantee that you will get the value most recently written by any thread. For this reason, atomicity guarantees per se normally have little impact on concurrent program design.

Visibility
Changes to fields made by one thread are guaranteed to be visible to other threads only under the following conditions:

* A writing thread releases a synchronization lock and a reading thread subsequently acquires that same synchronization lock.

In essence, releasing a lock forces a flush of all writes from working memory employed by the thread, and acquiring a lock forces a (re)load of the values of accessible fields. While lock actions provide exclusion only for the operations performed within a synchronized method or block, these memory effects are defined to cover all fields used by the thread performing the action.

Note the double meaning of synchronized: it deals with locks that permit higher-level synchronization protocols, while at the same time dealing with the memory system (sometimes via low-level memory barrier machine instructions) to keep value representations in synch across threads. This reflects one way in which concurrent programming bears more similarity to distributed programming than to sequential programming. The latter sense of synchronized may be viewed as a mechanism by which a method running in one thread indicates that it is willing to send and/or receive changes to variables to and from methods running in other threads. From this point of view, using locks and passing messages might be seen merely as syntactic variants of each other.

* If a field is declared as volatile, any value written to it is flushed and made visible by the writer thread before the writer thread performs any further memory operation (i.e., for the purposes at hand it is flushed immediately). Reader threads must reload the values of volatile fields upon each access.

* The first time a thread accesses a field of an object, it sees either the initial value of the field or a value since written by some other thread.

Among other consequences, it is bad practice to make available the reference to an incompletely constructed object (see 2.1.2). It can also be risky to start new threads inside a constructor, especially in a class that may be subclassed. Thread.start has the same memory effects as a lock release by the thread calling start, followed by a lock acquire by the started thread. If a Runnable superclass invokes new Thread(this).start() before subclass constructors execute, then the object might not be fully initialized when the run method executes. Similarly, if you create and start a new thread T and then create an object X used by thread T, you cannot be sure that the fields of X will be visible to T unless you employ synchronization surrounding all references to object X. Or, when applicable, you can create X before starting T.

* As a thread terminates, all written variables are flushed to main memory. For example, if one thread synchronizes on the termination of another thread using Thread.join, then it is guaranteed to see the effects made by that thread (see 4.3.2).

Note that visibility problems never arise when passing references to objects across methods in the same thread.

The memory model guarantees that, given the eventual occurrence of the above operations, a particular update to a particular field made by one thread will eventually be visible to another. But eventually can be an arbitrarily long time. Long stretches of code in threads that use no synchronization can be hopelessly out of synch with other threads with respect to values of fields. In particular, it is always wrong to write loops waiting for values written by other threads unless the fields are volatile or accessed via synchronization (see 3.2.6).

The model also allows inconsistent visibility in the absence of synchronization. For example, it is possible to obtain a fresh value for one field of an object, but a stale value for another. Similarly, it is possible to read a fresh, updated value of a reference variable, but a stale value of one of the fields of the object now being referenced.

However, the rules do not require visibility failures across threads, they merely allow these failures to occur. This is one aspect of the fact that not using synchronization in multithreaded code doesn't guarantee safety violations, it just allows them. On most current JVM implementations and platforms, even those employing multiple processors, detectable visibility failures rarely occur. The use of common caches across threads sharing a CPU, the lack of aggressive compiler-based optimizations, and the presence of strong cache consistency hardware often cause values to act as if they propagate immediately among threads. This makes testing for freedom from visibility-based errors impractical, since such errors might occur extremely rarely, or only on platforms you do not have access to, or only on those that have not even been built yet. These same comments apply to multithreaded safety failures more generally. Concurrent programs that do not use synchronization fail for many reasons, including memory consistency problems.

Ordering
Ordering rules fall under two cases, within-thread and between-thread:

* From the point of view of the thread performing the actions in a method, instructions proceed in the normal as-if-serial manner that applies in sequential programming languages.

* From the point of view of other threads that might be "spying" on this thread by concurrently running unsynchronized methods, almost anything can happen. The only useful constraint is that the relative orderings of synchronized methods and blocks, as well as operations on volatile fields, are always preserved.

Again, these are only the minimal guaranteed properties. In any given program or platform, you may find stricter orderings. But you cannot rely on them, and you may find it difficult to test for code that would fail on JVM implementations that have different properties but still conform to the rules.

Note that the within-thread point of view is implicitly adopted in all other discussions of semantics in JLS. For example, arithmetic expression evaluation is performed in left-to-right order (JLS section 15.6) as viewed by the thread performing the operations, but not necessarily as viewed by other threads.

The within-thread as-if-serial property is helpful only when only one thread at a time is manipulating variables, due to synchronization, structural exclusion, or pure chance. When multiple threads are all running unsynchronized code that reads and writes common fields, then arbitrary interleavings, atomicity failures, race conditions, and visibility failures may result in execution patterns that make the notion of as-if-serial just about meaningless with respect to any given thread.

Even though JLS addresses some particular legal and illegal reorderings that can occur, interactions with these other issues reduce practical guarantees to saying that the results may reflect just about any possible interleaving of just about any possible reordering. So there is no point in trying to reason about the ordering properties of such code.

Volatile
In terms of atomicity, visibility, and ordering, declaring a field as volatile is nearly identical in effect to using a little fully synchronized class protecting only that field via get/set methods, as in:
代码:

final class VFloat {
  private float value;

  final synchronized void  set(float f) { value = f; }
  final synchronized float get()        { return value; }
}


Declaring a field as volatile differs only in that no locking is involved. In particular, composite read/write operations such as the "++'' operation on volatile variables are not performed atomically.

Also, ordering and visibility effects surround only the single access or update to the volatile field itself. Declaring a reference field as volatile does not ensure visibility of non-volatile fields that are accessed via this reference. Similarly, declaring an array field as volatile does not ensure visibility of its elements. Volatility cannot be manually propagated for arrays because array elements themselves cannot be declared as volatile.

Because no locking is involved, declaring fields as volatile is likely to be cheaper than using synchronization, or at least no more expensive. However, if volatile fields are accessed frequently inside methods, their use is likely to lead to slower performance than would locking the entire methods.

Declaring fields as volatile can be useful when you do not need locking for any other reason, yet values must be accurately accessible across multiple threads. This may occur when:

* The field need not obey any invariants with respect to others.

* Writes to the field do not depend on its current value.

* No thread ever writes an illegal value with respect to intended semantics.
* The actions of readers do not depend on values of other non-volatile fields.

Using volatile fields can make sense when it is somehow known that only one thread can change a field, but many other threads are allowed to read it at any time. For example, a Thermometer class might declare its temperature field as volatile. As discussed in 3.4.2, a volatile can be useful as a completion flag. Additional examples are illustrated in 4.4, where the use of lightweight executable frameworks automates some aspects of synchronization, but volatile declarations are needed to ensure that result field values are visible across tasks.



扭{乑֝ 2006-03-15 09:09 发表评论
]]>
Java开?Java试工具http://www.tkk7.com/wangxq/articles/35056.html扭{乑֝扭{乑֝Mon, 13 Mar 2006 08:03:00 GMThttp://www.tkk7.com/wangxq/articles/35056.htmlhttp://www.tkk7.com/wangxq/comments/35056.htmlhttp://www.tkk7.com/wangxq/articles/35056.html#Feedback0http://www.tkk7.com/wangxq/comments/commentRss/35056.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/35056.htmlhttp://kb.csdn.net/java/Articles/200601/471cb3e7-12d4-41cf-ac06-4835d0674866.html
JUnit  

JUnit是由 Erich Gamma ?Kent Beck ~写的一个回归测试框Ӟregression testing frameworkQ。Junit试是程序员?gu)试Q即所谓白盒测试,因ؓ(f)E序员知道被试的Y件如何(HowQ完成功能和完成什么样QWhatQ的功能。Junit是一套框Ӟl承TestCasec,可以用Junitq行自动试?jin)?/strong>

http://www.junit.org/

Cactus  

Cactus是一个基于JUnit框架的简单测试框Ӟ用来单元试服务端Java代码。Cactus框架的主要目标是能够单元试服务端的使用Servlet对象的JavaҎ(gu)如HttpServletRequest,HttpServletResponse,HttpSession{?/strong>

http://jakarta.apache.org/cactus/

Abbot  

Abbot是一个用来测试Java GUIs的框架。用单的ZXML的脚本或者Java代码Q你可以开始一个GUI?/strong>

http://abbot.sourceforge.net/

JUnitPerf  

Junitperf实际是junit的一个decoratorQ通过~写用于junitperf的单元测试,我们也可使测试过E自动化?/strong>

http://www.clarkware.com/software/JUnitPerf.html

DbUnit  

DbUnit是ؓ(f)数据库驱动的目提供的一个对JUnit 的扩展,除了(jin)提供一些常用功能,它可以将你的数据库置于一个测试轮回之间的状态?

http://dbunit.sourceforge.net/

Mockrunner  

Mockrunner用在J2EE环境中进行应用程序的单元试。它不仅支持Struts actions, servletsQ过滤器和标{q包括一个JDBC和一个JMS试框架Q可以用于测试基于EJB的应用程序?/strong>

http://mockrunner.sourceforge.net/index.html

DBMonster  

DBMonster是一个用生成随机数据来测试SQL数据库的压力试工具?/strong>

http://dbmonster.kernelpanic.pl/

MockEJB  

MockEJB是一个不需要EJB容器pq行EJBq进行测试的轻量U框架?/strong>

http://mockejb.sourceforge.net/

StrutsTestCase  

StrutsTestCase 是Junit TestCasecȝ扩展Q提供基于Struts框架的代码测试。StrutsTestCase同时提供Mock 对象Ҏ(gu)和CactusҎ(gu)用来实际q行Struts ActionServletQ你可以通过q行servlet引擎来测试。因为StrutsTestCase使用ActionServlet控制器来试你的代码Q因此你不仅可以试Action对象的实玎ͼ而且可以试mappingsQfrom beans以及(qing)forwards声明。StrutsTestCase不启动servlet容器来测试struts应用E序Q容器外试Q也属于Mock对象试Q但是与EasyMock不同的是QEasyMock是提供了(jin)创徏Mock对象的APIQ而StrutsTest则是专门负责试Struts应用E序的Mock对象试框架?

http://strutstestcase.sourceforge.net/

JFCUnit  

JFCUnit使得你能够ؓ(f)Java偏移应用E序~写试例子。它Z用代码打开的窗口上获得句柄提供?jin)支持;为在一个部件层ơ定位部件提供支持;为在部g中发起事Ӟ例如按一个按钮)(j)以及(qing)以线E安全方式处理部件测试提供支持?/strong>

http://jfcunit.sourceforge.net/

JTestCase  

JTestCase 使用XML文g来组l多试案例数据Q声明条Ӟ操作和期望的l果Q,提供?jin)一套易于用的Ҏ(gu)来检索XML中的试案例Q按照数据文件的定义来声明结果?/strong>

http://jtestcase.sourceforge.net/

SQLUnit  

SQLUnit是一个单元测试框Ӟ用于Ҏ(gu)据库存储q程q行回归试。用 Java/JUnit/XML开发?

http://sqlunit.sourceforge.net

JTR  

JTR (Java Test Runner)是一个开源的Z反{控制(IOC)的J2EE试框架。它允许你构建复杂的J2EE试套g(Test Suites)q连到应用服务器执行试,可以包括多个试实例。JTR的licensed是GPL协议?/strong>

http://jtrunner.sourceforge.net/

Marathon  

Marathon是一个针对用Java/Swing开发GUI应用E序的测试框Ӟ它由recorder, runner ?editorl成Q测试脚本是python代码。Marathon的焦Ҏ(gu)攑֜最l用L(fng)试上?/strong>

http://marathonman.sourceforge.net

TestNG  

TestNG是根据JUnit ?NUnit思想而构建的一个测试框Ӟ但是TestNG增加?jin)许多新的功能得它变得更加强大与容易用比如?x)
*支持JSR 175注释QJDK 1.4利用JavaDoc注释同样也支持)(j)
*灉|的Test配置
*支持默认的runtime和logging JDK功能
*强大的执行模型(不再TestSuiteQ?br />*支持独立的测试方法?/strong>

http://testng.org/

Surrogate Test framework  

Surrogate Test framework是一个值得U赞单元试框架Q特别适合于大型,复杂Javapȝ的单元测试。这个框架能与JUnit,MockEJB和各U支持模拟对象(mock object Q的试工具无缝l合。这个框架基于AspectJ技术?/font>

http://surrogate.sourceforge.net

MockCreator  

MockCreator可以为给定的interface或class生成模拟对象QMock objectQ的源码?/strong>

http://mockcreator.sourceforge.net/

jMock  

jMock利用mock objects思想来对Java codeq行试。jMockh以下特点:Ҏ(gu)扩展Q让你快速简单地定义mock objects,因此不必打破E序间的兌Q让你定义灵zȝ越对象之间交互作用而带来测试局限,减少你测试地脆弱性?/strong>

http://www.jmock.org/

EasyMock  

EasyMock为Mock Objects提供接口q在JUnit试中利用Java的proxy设计模式生成它们的实例。EasyMock最适合于测试驱动开发?/strong>

http://www.easymock.org/

The Grinder  

The Grinder是一个负载测试框架。在BSD开源协议下免费使用?/strong>

http://grinder.sourceforge.net/

XMLUnit  

XMLUnit不仅有Java版本的还?Net版本的。Java开发的XMLUnit提供?jin)两个JUnit 扩展cXMLAssert和XMLTestCase,和一l支持的cR这些类可以用来比较两张XML之间的不同之处,展示XML利用XSLT?校验XML,求得XPath表达式在XML中的?遍历XML中的某一节点利DOM展开,

http://xmlunit.sourceforge.net/

Jameleon  

Jameleon一个自动化试工具。它被用来测试各U各L(fng)应用E序Q所以它被设计成插g模式。ؓ(f)?jin)整个试q程变得单Jameleon提供?jin)一个GUI,因此Jameleon实现?jin)一个Swing 插g?/strong>

http://jameleon.sourceforge.net/index.html

J2MEUnit  

J2MEUnit是应用在J2ME应用E序的一个单元测试框架。它ZJUnit.

http://j2meunit.sourceforge.net/

Jetif  

Jetif是一个用UJava实现的回归测试框架。它为JavaE序单元试以及(qing)功能试提供?jin)一个简单而且?伸羃的架构,可以用于个h开发或企业U开发的试。它Ҏ(gu)使用Q功能强大,而且拥有一些企业񔋹试的重要功能。Jetif来源于JUnit, JTestCase以及(qing)TestNG的启发,有几个基本的概念直接来自于JUnitQ?比如说断a机制QTest Listener的概念,因此从JUnit转到Jetif是非常容易的?/font>

http://jetif.sourceforge.net/

GroboUtils  

GroboUtils使得扩展Java试变得可能。它包括用在Java不同斚w试的多个子目。在GroboUtils中最常被到的工具?多线E测?multi-threaded tests),整体单元试(hierarchial unit tests),代码覆盖工具(code coverage tool)?/font>

http://groboutils.sourceforge.net/

Testare  

TESTARE是用来简化分布式应用E序(比如:在SERVLETS,JMS listeners, CORBA ORBs或RMI环境?试开发过E的一个测试框?

https://testare.dev.java.net/



扭{乑֝ 2006-03-13 16:03 发表评论
]]>
【源译】JUnitPerf 使用手册http://www.tkk7.com/wangxq/articles/33231.html扭{乑֝扭{乑֝Thu, 02 Mar 2006 07:49:00 GMThttp://www.tkk7.com/wangxq/articles/33231.htmlhttp://www.tkk7.com/wangxq/comments/33231.htmlhttp://www.tkk7.com/wangxq/articles/33231.html#Feedback0http://www.tkk7.com/wangxq/comments/commentRss/33231.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/33231.html阅读全文

扭{乑֝ 2006-03-02 15:49 发表评论
]]>
【Java开?Java试工具?/title><link>http://www.tkk7.com/wangxq/articles/33219.html</link><dc:creator>扭{乑֝</dc:creator><author>扭{乑֝</author><pubDate>Thu, 02 Mar 2006 07:07:00 GMT</pubDate><guid>http://www.tkk7.com/wangxq/articles/33219.html</guid><wfw:comment>http://www.tkk7.com/wangxq/comments/33219.html</wfw:comment><comments>http://www.tkk7.com/wangxq/articles/33219.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/wangxq/comments/commentRss/33219.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/wangxq/services/trackbacks/33219.html</trackback:ping><description><![CDATA[<div id="6161166" class=postText> <P align=center><span id="6666661" class=style7><span id="6611116" class=style7><STRONG><FONT face=宋体 color=#ff0000 size=4>【Java开?nbsp;Java试工具?/FONT></STRONG></SPAN></SPAN></P><span id="1161166" class=style7><span id="1111161" class=style7> <div id="6116661" class=story> <H2><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0> <A ><FONT color=#003366>JUnit</FONT></A>  <span id="1111166" class=NavigationColor> </SPAN></H2> <P><STRONG>JUnit是由 Erich Gamma ?Kent Beck ~写的一个回归测试框Ӟregression testing frameworkQ。Junit试是程序员?gu)试Q即所谓白盒测试,因ؓ(f)E序员知道被试的Y件如何(HowQ完成功能和完成什么样QWhatQ的功能。Junit是一套框Ӟl承TestCasec,可以用Junitq行自动试?jin)?/STRONG> </P> <P><A ><FONT color=#003366>http://www.junit.org/</FONT></A></P></DIV> <div id="1166161" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>Cactus </FONT></A> <span id="1616611" class=NavigationColor> </SPAN></H2> <P><STRONG>Cactus是一个基于JUnit框架的简单测试框Ӟ用来单元试服务端Java代码。Cactus框架的主要目标是能够单元试服务端的使用Servlet对象的JavaҎ(gu)如HttpServletRequest,HttpServletResponse,HttpSession{?/STRONG></P> <P><A ><FONT color=#003366>http://jakarta.apache.org/cactus/</FONT></A></P></DIV> <div id="6166116" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>Abbot</FONT></A>  <span id="1116661" class=NavigationColor> </SPAN></H2> <P><STRONG>Abbot是一个用来测试Java GUIs的框架。用单的ZXML的脚本或者Java代码Q你可以开始一个GUI?/STRONG></P> <P><A ><FONT color=#003366>http://abbot.sourceforge.net/</FONT></A></P></DIV> <div id="6116661" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>JUnitPerf</FONT></A>  <span id="1611166" class=NavigationColor> </SPAN></H2> <P><STRONG>Junitperf实际是junit的一个decoratorQ通过~写用于junitperf的单元测试,我们也可使测试过E自动化?/STRONG></P> <P><A ><FONT color=#003366>http://www.clarkware.com/software/JUnitPerf.html</FONT></A></P></DIV> <div id="6616616" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>DbUnit</FONT></A>  <span id="6661616" class=NavigationColor> </SPAN></H2> <P><STRONG>DbUnit是ؓ(f)数据库驱动的目提供的一个对JUnit 的扩展,除了(jin)提供一些常用功能,它可以将你的数据库置于一个测试轮回之间的状态?</STRONG></P> <P><A ><FONT color=#003366>http://dbunit.sourceforge.net/</FONT></A></P></DIV> <div id="6166616" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>Mockrunner</FONT></A>  <span id="6666116" class=NavigationColor> </SPAN></H2> <P><STRONG>Mockrunner用在J2EE环境中进行应用程序的单元试。它不仅支持Struts actions, servletsQ过滤器和标{q包括一个JDBC和一个JMS试框架Q可以用于测试基于EJB的应用程序?/STRONG></P> <P><A ><FONT color=#003366>http://mockrunner.sourceforge.net/index.html</FONT></A></P></DIV> <div id="6661161" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>DBMonster</FONT></A>  <span id="1661661" class=NavigationColor> </SPAN></H2> <P><STRONG>DBMonster是一个用生成随机数据来测试SQL数据库的压力试工具?/STRONG></P> <P><A ><FONT color=#003366>http://dbmonster.kernelpanic.pl/</FONT></A></P></DIV> <div id="6611111" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>MockEJB</FONT></A>  <span id="6611616" class=NavigationColor> </SPAN></H2> <P><STRONG>MockEJB是一个不需要EJB容器pq行EJBq进行测试的轻量U框架?/STRONG></P> <P><A ><FONT color=#003366>http://mockejb.sourceforge.net/</FONT></A></P></DIV> <div id="1116666" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>StrutsTestCase</FONT></A>  <span id="1116661" class=NavigationColor> </SPAN></H2> <P><STRONG>StrutsTestCase 是Junit TestCasecȝ扩展Q提供基于Struts框架的代码测试。StrutsTestCase同时提供Mock 对象Ҏ(gu)和CactusҎ(gu)用来实际q行Struts ActionServletQ你可以通过q行servlet引擎来测试。因为StrutsTestCase使用ActionServlet控制器来试你的代码Q因此你不仅可以试Action对象的实玎ͼ而且可以试mappingsQfrom beans以及(qing)forwards声明。StrutsTestCase不启动servlet容器来测试struts应用E序Q容器外试Q也属于Mock对象试Q但是与EasyMock不同的是QEasyMock是提供了(jin)创徏Mock对象的APIQ而StrutsTest则是专门负责试Struts应用E序的Mock对象试框架?</STRONG></P> <P><A ><FONT color=#003366>http://strutstestcase.sourceforge.net/</FONT></A></P></DIV> <div id="1611616" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>JFCUnit</FONT></A>  <span id="6166161" class=NavigationColor> </SPAN></H2> <P><STRONG>JFCUnit使得你能够ؓ(f)Java偏移应用E序~写试例子。它Z用代码打开的窗口上获得句柄提供?jin)支持;为在一个部件层ơ定位部件提供支持;为在部g中发起事Ӟ例如按一个按钮)(j)以及(qing)以线E安全方式处理部件测试提供支持?/STRONG></P> <P><A ><FONT color=#003366>http://jfcunit.sourceforge.net/</FONT></A></P></DIV> <div id="1611161" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>JTestCase</FONT></A>  <span id="6166661" class=NavigationColor> </SPAN></H2> <P><STRONG>JTestCase 使用XML文g来组l多试案例数据Q声明条Ӟ操作和期望的l果Q,提供?jin)一套易于用的Ҏ(gu)来检索XML中的试案例Q按照数据文件的定义来声明结果?/STRONG></P> <P><A ><FONT color=#003366>http://jtestcase.sourceforge.net/</FONT></A></P></DIV> <div id="6611161" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>SQLUnit</FONT></A>  <span id="1611116" class=NavigationColor> </SPAN></H2> <P><STRONG>SQLUnit是一个单元测试框Ӟ用于Ҏ(gu)据库存储q程q行回归试。用 Java/JUnit/XML开发?</STRONG></P> <P><A ><FONT color=#003366>http://sqlunit.sourceforge.net</FONT></A></P></DIV> <div id="1116166" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>JTR</FONT></A>  <span id="6111616" class=NavigationColor> </SPAN></H2> <P><STRONG>JTR (Java Test Runner)是一个开源的Z反{控制(IOC)的J2EE试框架。它允许你构建复杂的J2EE试套g(Test Suites)q连到应用服务器执行试,可以包括多个试实例。JTR的licensed是GPL协议?/STRONG></P> <P><A ><FONT color=#003366>http://jtrunner.sourceforge.net/</FONT></A></P></DIV> <div id="6116116" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>Marathon</FONT></A>  <span id="6661666" class=NavigationColor> </SPAN></H2> <P><STRONG>Marathon是一个针对用Java/Swing开发GUI应用E序的测试框Ӟ它由recorder, runner ?editorl成Q测试脚本是python代码。Marathon的焦Ҏ(gu)攑֜最l用L(fng)试上?/STRONG></P> <P><A ><FONT color=#003366>http://marathonman.sourceforge.net</FONT></A></P></DIV> <div id="6611116" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>TestNG</FONT></A>  <span id="1166161" class=NavigationColor> </SPAN></H2> <P><STRONG>TestNG是根据JUnit ?NUnit思想而构建的一个测试框Ӟ但是TestNG增加?jin)许多新的功能得它变得更加强大与容易用比如?x)<BR>*支持JSR 175注释QJDK 1.4利用JavaDoc注释同样也支持)(j)<BR>*灉|的Test配置<BR>*支持默认的runtime和logging JDK功能<BR>*强大的执行模型(不再TestSuiteQ?BR>*支持独立的测试方法?/STRONG></P> <P><A ><FONT color=#003366>http://testng.org/</FONT></A></P></DIV> <div id="1161666" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>Surrogate Test framework</FONT></A>  <span id="6116161" class=NavigationColor> </SPAN></H2> <H2><span id="6166661" class=NavigationColor></SPAN><FONT size=3>Surrogate Test framework是一个值得U赞单元试框架Q特别适合于大型,复杂Javapȝ的单元测试。这个框架能与JUnit,MockEJB和各U支持模拟对象(mock object Q的试工具无缝l合。这个框架基于AspectJ技术?/FONT></H2> <P><A ><FONT color=#003366>http://surrogate.sourceforge.net</FONT></A></P></DIV> <div id="1161161" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>MockCreator</FONT></A>  <span id="6666616" class=NavigationColor> </SPAN></H2> <P><STRONG>MockCreator可以为给定的interface或class生成模拟对象QMock objectQ的源码?/STRONG></P> <P><A ><FONT color=#003366>http://mockcreator.sourceforge.net/</FONT></A></P></DIV> <div id="1661161" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>jMock</FONT></A>  <span id="6611111" class=NavigationColor> </SPAN></H2> <P><STRONG>jMock利用mock objects思想来对Java codeq行试。jMockh以下特点:Ҏ(gu)扩展Q让你快速简单地定义mock objects,因此不必打破E序间的兌Q让你定义灵zȝ越对象之间交互作用而带来测试局限,减少你测试地脆弱性?/STRONG></P> <P><A ><FONT color=#003366>http://www.jmock.org/</FONT></A></P></DIV> <div id="1111111" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>EasyMock</FONT></A>  <span id="1661111" class=NavigationColor> </SPAN></H2> <P><STRONG>EasyMock为Mock Objects提供接口q在JUnit试中利用Java的proxy设计模式生成它们的实例。EasyMock最适合于测试驱动开发?/STRONG></P> <P><A ><FONT color=#003366>http://www.easymock.org/</FONT></A></P></DIV> <div id="1611166" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>The Grinder</FONT></A>  <span id="6661666" class=NavigationColor> </SPAN></H2> <P><STRONG>The Grinder是一个负载测试框架。在BSD开源协议下免费使用?/STRONG></P> <P><A ><FONT color=#003366>http://grinder.sourceforge.net/</FONT></A></P></DIV> <div id="6661111" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>XMLUnit</FONT></A>  <span id="6666116" class=NavigationColor> </SPAN></H2> <P><STRONG>XMLUnit不仅有Java版本的还?Net版本的。Java开发的XMLUnit提供?jin)两个JUnit 扩展cXMLAssert和XMLTestCase,和一l支持的cR这些类可以用来比较两张XML之间的不同之处,展示XML利用XSLT?校验XML,求得XPath表达式在XML中的?遍历XML中的某一节点利DOM展开,</STRONG></P> <P><A ><FONT color=#003366>http://xmlunit.sourceforge.net/</FONT></A></P></DIV> <div id="6661616" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>Jameleon</FONT></A>  <span id="1116116" class=NavigationColor> </SPAN></H2> <P><STRONG>Jameleon一个自动化试工具。它被用来测试各U各L(fng)应用E序Q所以它被设计成插g模式。ؓ(f)?jin)整个试q程变得单Jameleon提供?jin)一个GUI,因此Jameleon实现?jin)一个Swing 插g?/STRONG></P> <P><A ><FONT color=#003366>http://jameleon.sourceforge.net/index.html</FONT></A></P></DIV> <div id="6616161" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>J2MEUnit</FONT></A>  <span id="1611161" class=NavigationColor> </SPAN></H2> <P><STRONG>J2MEUnit是应用在J2ME应用E序的一个单元测试框架。它ZJUnit.</STRONG></P> <P><A ><FONT color=#003366>http://j2meunit.sourceforge.net/</FONT></A></P></DIV> <div id="1666666" class=story> <H2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> <A ><FONT color=#003366>Jetif</FONT></A>  <span id="6616666" class=NavigationColor> </SPAN></H2> <H2><span id="6166116" class=NavigationColor></SPAN><FONT size=3>Jetif是一个用UJava实现的回归测试框架。它为JavaE序单元试以及(qing)功能试提供?jin)一个简单而且?伸羃的架构,可以用于个h开发或企业U开发的试。它Ҏ(gu)使用Q功能强大,而且拥有一些企业񔋹试的重要功能。Jetif来源于JUnit, JTestCase以及(qing)TestNG的启发,有几个基本的概念直接来自于JUnitQ?比如说断a机制QTest Listener的概念,因此从JUnit转到Jetif是非常容易的?/FONT></H2> <P><A ><FONT color=#003366>http://jetif.sourceforge.net/</FONT></A></P></DIV> <div id="6661666" class=story> <H2><FONT size=2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT> </FONT><A ><FONT color=#003366>GroboUtils</FONT></A>  <span id="6661661" class=NavigationColor> </SPAN></H2> <H2><span id="1661616" class=NavigationColor></SPAN><FONT size=3>GroboUtils使得扩展Java试变得可能。它包括用在Java不同斚w试的多个子目。在GroboUtils中最常被到的工具?多线E测?multi-threaded tests),整体单元试(hierarchial unit tests),代码覆盖工具(code coverage tool)?/FONT></H2> <P><A ><FONT color=#003366>http://groboutils.sourceforge.net/</FONT></A></P></DIV> <div id="1166616" class=story> <H2><FONT size=2><FONT color=#003366><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大?height=14 alt="" src="http://www.open-open.com/image/item.gif" width=13 onload="java_script_:if(this.width>600)this.width=600" border=0></FONT></FONT> <A ><FONT color=#003366>Testare</FONT></A><FONT size=2>  <span id="1666616" class=NavigationColor> </SPAN></FONT></H2> <H2><span id="6666166" class=NavigationColor></SPAN><FONT size=3>TESTARE是用来简化分布式应用E序(比如:在SERVLETS,JMS listeners, CORBA ORBs或RMI环境?试开发过E的一个测试框?</FONT></H2> <P><A ><FONT color=#003366>https://testare.dev.java.net/</FONT></A></P></DIV></SPAN></SPAN><BR><BR> <P id=TBPingURL>Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=568616</P></DIV><img src ="http://www.tkk7.com/wangxq/aggbug/33219.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/wangxq/" target="_blank">扭{乑֝</a> 2006-03-02 15:07 <a href="http://www.tkk7.com/wangxq/articles/33219.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>W一?Cactus + Jetty 试[转]http://www.tkk7.com/wangxq/articles/33117.html扭{乑֝扭{乑֝Thu, 02 Mar 2006 01:09:00 GMThttp://www.tkk7.com/wangxq/articles/33117.htmlhttp://www.tkk7.com/wangxq/comments/33117.htmlhttp://www.tkk7.com/wangxq/articles/33117.html#Feedback0http://www.tkk7.com/wangxq/comments/commentRss/33117.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/33117.htmlhttp://www.cntesting.com/pic/study/JUnitGossip/FirstCactusWithJetty.htm
在Tomcat或?zhn)的目标Container上直接执行测试的好处是,(zhn)即完成?jin)单元测试,也测试?jin)(zhn)的单元?Container的交互,然而比较麻?ch)的是,?zhn)必d每一ơ的修改之後Q重新布|相关的资源、启动Container、运行测试等{,试时较时耗力?br />
Ҏ(gu)单的In-Container单元试Q?zhn)可以使用stub的方式,stub卛_真实pȝ的一部䆾引入(zhn)的E式之中Q让(zhn)的E式可以与这一个部份进行交互,而不一定要整个程式置於系l之中?br />
stub的好处是Q有时?zhn)q不是要试E式与整个系l的行ؓ(f)Qƈ且?zhn)也不是每ơ都可以程式丢到系l之上运行,试想Q?zhn)不能Z(jin)试(zhn)的单元Q而要求真正在服务客户的系l不断的重启?br />
Ҏ(gu)In-Container试采取stub的方式,自然是实现Container的部份功能,q将试|於其中Q在q边(zhn)可以?Jetty [http://jetty.mortbay.org/jetty/index.html]Q它是个Java撰写的HTTP伺服器,本n也是?ContainerQCactus集成?jin)JettyQƈ提供与测试相关的便类别?br />
使用Cactus+Jetty执行试Q在更大的程度上隐藏?jin)测试运行过E的l节Q?zhn)不必兛_(j)Redirector ProxyQ更不一定要兛_(j)TestCase在客L(fng)与伺服端的行为,q行h如同在q作一个JUnit试?br />
使用Cactus+Jettyq行试ӞJetty?x)在试开始前完成启动Q接著进行相x试,然後Jetty?x)自动关闭,q很方便Q另一斚wQ启?Jetty?x)快的多了(jin)?br />
要用Cactus+JettyQ请Cactus下蝲後的lib目录中的commons-logging-xxx.jar?aspectjrt-xxx.jar、cactus-xxx.jar、commons-httpclient-xxx.jar、junit- xxx.jar以及(qing)org.mortbay.jetty-xxx.jar讑֮至CLASSPATH?br />
接著撰写试案例Q?br />

  • LoginServletTest.java
package onlyfun.caterpillar.test;

import junit.framework.Test;
import junit.framework.TestSuite;

import org.apache.cactus.ServletTestCase;
import org.apache.cactus.WebRequest;
import org.apache.cactus.extension.jetty.JettyTestSetup;

import onlyfun.caterpillar.LoginServlet;

public class LoginServletTest extends ServletTestCase {
public static Test suite() {
System.setProperty("cactus.contextURL",
"http://localhost:8080/cactusDemo");
TestSuite suite = new TestSuite();
suite.addTestSuite(LoginServletTest.class);
return new JettyTestSetup(suite);
}

public void beginValidUser(WebRequest webRequest) {
webRequest.addParameter("username", "justin");
webRequest.addParameter("password", "123456");
}

public void testValidUser() {
LoginServlet loginServlet = new LoginServlet();
assertTrue(loginServlet.isValidUser(request));
}

public void beginInValidUser(WebRequest webRequest) {
webRequest.addParameter("username", "guest");
webRequest.addParameter("password", "123456");
}

public void testInValidUser() {
LoginServlet loginServlet = new LoginServlet();
assertFalse(loginServlet.isValidUser(request));
}

public static void main(String[] args) {
junit.textui.TestRunner.run(
LoginServletTest.suite());
}
}

在这边要特别注意的是suite()Ҏ(gu)Q传回了(jin)一个JettyTestSetup实例Q如(zhn)所想的Q这个实例除?jin)运行TestSuite之外Q它q会(x)启动Jetty。接下来依测试案例来完成E式Q?br />
  • LoginServlet.java
package onlyfun.caterpillar;

import javax.servlet.http.*;

public class LoginServlet extends HttpServlet {
public boolean isValidUser(HttpServletRequest request) {
String username = request.getParameter("username");
String password = request.getParameter("password");

if(username == null ||
password == null ||
!username.equals("justin") ||
!password.equals("123456")) {
return false;
}
else {
return true;
}
}
}

然後可以运行测试了(jin)Q以下是试的结果:(x)
09:26:10.625 EVENT  Starting Jetty/4.2.17
09:26:10.843 EVENT  Started ServletHttpContext[/cactusDemo]
09:26:39.203 EVENT  Started SocketListener on 0.0.0.0:8080
09:26:39.203 EVENT  Started org.mortbay.jetty.Server@758fc9
..09:26:40.296 EVENT  Stopping Acceptor 
ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=8080]
09:26:40.296 EVENT  Stopped SocketListener on 0.0.0.0:8080
09:26:40.296 EVENT  Stopped ServletHttpContext[/cactusDemo]
09:26:40.296 EVENT  Stopped org.mortbay.jetty.Server@758fc9

Time: 31.453

OK (2 tests)



q可以参?a >http://kb.csdn.net/java/Articles/200312/2a86aa04-cbf1-4eda-98a4-902b1c974cc7.html
http://www.51testing.com/html/6/23.html

扭{乑֝ 2006-03-02 09:09 发表评论
]]>
转—用模仿对象Mock objectq行单元试http://www.tkk7.com/wangxq/articles/31126.html扭{乑֝扭{乑֝Fri, 17 Feb 2006 01:18:00 GMThttp://www.tkk7.com/wangxq/articles/31126.htmlhttp://www.tkk7.com/wangxq/comments/31126.htmlhttp://www.tkk7.com/wangxq/articles/31126.html#Feedback0http://www.tkk7.com/wangxq/comments/commentRss/31126.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/31126.html使用模仿对象Mock objectq行单元试
NetReptile推荐 [2005-2-12]
出处QIBM DW中国
作者:(x)Alexander Day Chaffe
 

模仿对象QMock objectQ是v中介者作用的对象~写单元试的有用方法。测试对象调用模仿域对象Q它只断a以正的ơ序用期望的参数调用?jin)正的?gu)Q,而不是调用实际域对象。然而,当测试对象必d建域对象Ӟ我们面(f)一个问题。测试对象如何知道创建模仿域对象Q而不是创建实际域对象呢?在本文中QY仉?Alexander Day Chaffee ?William Pietri 演CZU重构技术,该技术根据工厂方法设计模式来创徏模仿对象?/P>

单元试已作Y件开发的“最?jng)_践”被普遍接受。当~写对象Ӟq必L供一个自动化试c,该类包含试该对象性能的方法、用各种参数调用其各U公用(publicQ方法ƈ保q回值是正确的?

当?zhn)正在处理单数据或服务对象Ӟ~写单元试很简单。然而,许多对象依赖基础l构的其它对象或层。当开始测试这些对象时Q实例化q些合作者(collaboratorQ通常是昂늚、不切实际的或效率低的?

例如Q要单元试一个用数据库的对象,安装、配|和发送本地数据库副本、运行测试然后再卸装本地数据库可能很ȝ(ch)。模仿对象提供了(jin)解决q一困难的方法。模仿对象符合实际对象的接口Q但只要有够的代码来“欺骗”测试对象ƈ跟踪其行为。例如,虽然某一特定单元试的数据库q接始终q回相同的硬q接l果Q但可能?x)记录查询。只要正在被试的类的行为如所期望的那P它将不会(x)注意到差异,而单元测试会(x)(g)查是否发Z(jin)正确的查询?

夹在中间的模?/STRONG>


使用模仿对象q行试的常用编码样式是Q?

· 创徏模仿对象的实?

· 讄模仿对象中的状态和期望?

· 模仿对象作为参数来调用域代?

· 验证模仿对象中的一致?

虽然q种模式对于许多情况都非常有效,但模仿对象有时不能被传递到正在试的对象。而设计该对象是ؓ(f)?jin)创建、查找或获得其合作者?

例如Q测试对象可能需要获得对Enterprise JavaBeanQEJBQ组件或q程对象的引用。或者,试对象?x)用具有副作用的对象,如删除文件的File对象Q而在单元试中不希望有这些副作用?

Ҏ(gu)常识Q我们知道这U情形下可以试重构对象Q之更便于试。例如,可以更改Ҏ(gu){֐Q以便传入合作者对象?

?Nicholas Lesiecki 的文章“Test flexibly with AspectJ and mock objects”中Q他指出重构不一定L合意的,也不一定L产生更清晰或更容易理解的代码。在许多情况下,更改Ҏ(gu){֐以合作者成为参数将?x)在?gu)的原始调用者内部生؜淆的、未l试验的代码混ؕ?

问题的关键是该对象“在里面”获得这些对象。Q何解x案都必须应用于这个创Z码的所有出现。ؓ(f)?jin)解册个问题,Lesiecki 使用?jin)查找方式或创徏方式。在q个解决Ҏ(gu)中,执行查找的代码被q回模仿对象的代码自动替换?

因ؓ(f) AspectJ 对于某些情况不是选项Q所以我们在本文中提供了(jin)一个替代方法。因为在Ҏ(gu)上这是重构,所以我们将遵@ Martin Fowler 在他创新的书c“Refactoring: Improving the Design of Existing Code”(请参阅参考资料)(j)中徏立的表达U定。(我们的代码基?JUnit ?Java ~程的最行的单元测试框Ӟ管它决不是 JUnit 特定的。)(j)

重构Q抽取和覆盖工厂Ҏ(gu)


重构是一U代码更改,它原始功能保持不变Q但更改代码设计Q它变得更清晰、更有效且更易于试。本节将循序渐进地描q“抽取”和“覆盖”工厂方法重构?

问题Q正在测试的对象创徏?jin)合作者对象。必ȝ模仿对象替换q个合作者?

重构之前的代码:(x)

class Application {
...
  public void run() {
    View v = new View();
    v.display();
...


解决Ҏ(gu)Q将创徏代码抽取到工厂方法,在测试子cM覆盖该工厂方法,然后使被覆盖的方法返回模仿对象。最后,如果可以的话Q添加需要原始对象的工厂Ҏ(gu)的单元测试,以返回正类型的对象Q?

重构之后的代码:(x)

class Application {
...
  public void run() {
    View v = createView();
    v.display();
...
  protected View createView() {
    return new View();
  }
...
}


该重构启用清?中所C的单元试代码Q?

清单 1. 单元试代码

class ApplicationTest extends TestCase {
  MockView mockView = new MockView();
  public void testApplication {
    Application a = new Application() {
      protected View createView() {
        return mockView;
      }
    };
    a.run();
    mockView.validate();
  }
  private class MockView extends View
  {
    boolean isDisplayed = false;
    public void display() {
      isDisplayed = true;
    }
    public void validate() {
      assertTrue(isDisplayed);
    }
  }
}


角色

该设计引入了(jin)ql中的对象扮演的下列角色Q?

· 目标对象Q正在测试的对象

· 合作者对象:(x)q标对象创建或获取的对?

· 模仿对象Q遵循模仿对象模式的合作者的子类Q或实现Q?

· Ҏ(gu)化对象:(x)覆盖创徏Ҏ(gu)以返回模仿对象而不是合作者的目标的子c?

技?/B>

重构p多小的技术性步骤组成。这些步骤统UCؓ(f)技巧。如果?zhn)象按照食谱那样严格遵循这些技术,那么(zhn)在学习(fn)重构时应该没有太大的ȝ(ch)?

标识创徏或获取合作者的代码的所有出现?

抽取方法重构应用于q个创徏代码Q创建工厂方法(在Fowler书籍的第110中讨论Q有x多信息,请参阅参考资料一节)(j)?

保目标对象?qing)其子类可以讉K工厂Ҏ(gu)。(?Java 语言中,使用 protected 关键字)(j)?

在测试代码中Q创建模仿对象且实现与合作者相同的接口?

在测试代码中Q创建扩展(专用于)(j)目标对象的特D化对象?

在特D化对象中,覆盖创徏Ҏ(gu)以返回ؓ(f)试提供的模仿对象?

可选的Q创建单元测试以保原始目标对象的工厂方法仍q回正确的非模仿对象?

CZQATM

设想(zhn)正在编写用于银行自动柜员机QAutomatic Teller MachineQ的试。其中一个测试可能类g清单 2Q?

清单 2. 初始单元试Q在模仿对象引入之前Q?

public void testCheckingWithdrawal() {
    float startingBalance = balanceForTestCheckingAccount();
    AtmGui atm = new AtmGui();
    insertCardAndInputPin(atm);
    atm.pressButton("Withdraw");
    atm.pressButton("Checking");
    atm.pressButtons("1", "0", "0", "0", "0");
    assertContains("$100.00", atm.getDisplayContents());
    atm.pressButton("Continue");
    assertEquals(startingBalance - 100,
balanceForTestCheckingAccount());
  }


另外QAtmGui cd部的匚w代码可能cM于清?3Q?

清单 3. 产品代码Q在重构之前Q?

private Status doWithdrawal(Account account, float amount) {
    Transaction transaction = new Transaction();
    transaction.setSourceAccount(account);
    transaction.setDestAccount(myCashAccount());
    transaction.setAmount(amount);
    transaction.process();
    if (transaction.successful()) {
      dispense(amount);
    }
    return transaction.getStatus();
  }


该方法将起作用,遗憾的是Q它有一个副作用Q支帐户余额比试开始时,q得其它测试变得更困难。有一些解册U困隄Ҏ(gu)Q但它们都会(x)增加试的复杂性。更p的是,该方法还需要对理货币的系l进行三ơ往q?

要修正这个问题,W一步是重构 AtmGui 以允许我们用模仿事务替换实际事务Q如清单 4 中所C(比较_体的源代码以查看我们正在更改什么)(j)Q?

清单 4. 重构

AtmGui  private Status doWithdrawal(Account account, float amount) {
    Transaction transaction = createTransaction();
    transaction.setSourceAccount(account);
    transaction.setDestAccount(myCashAccount());
    transaction.setAmount(amount);
    transaction.process();
    if (transaction.successful()) {
      dispense(amount);
    }
    return transaction.getStatus();
  }
   protected Transaction createTransaction() {
    return new Transaction();
  }


后退到测试类内部Q我们将 MockTransaction cd义ؓ(f)成员c,如清?5 中所C:(x)

清单 5. ?MockTransaction 定义为成员类Q?

private MockTransaction extends Transaction {
    private boolean processCalled = false;
    // override process method so that no real work is done
    public void process() {
      processCalled = true;
      setStatus(Status.SUCCESS);
    }
    public void validate() {
      assertTrue(processCalled);
    }
  }


最后,我们可以重写试Q以便被试的对象?MockTransaction c,而不是用实际类Q如清单 6 中所C:(x)

清单 6. 使用 MockTransaction c?

MockTransaction mockTransaction;
  public void testCheckingWithdrawal() {
    mockTransaction = new MockTransaction();
    AtmGui atm = new AtmGui() {
        protected Transaction createTransaction() {
          return mockTransaction;
        }
    };
    insertCardAndInputPin(atm);
    atm.pressButton("Withdraw");
    atm.pressButton("Checking");
    atm.pressButtons("1", "0", "0", "0", "0");
    assertContains("$100.00", atm.getDisplayContents());
    atm.pressButton("Continue");
    assertEquals(100.00, mockTransaction.getAmount());
    assertEquals(TEST_CHECKING_ACCOUNT,
mockTransaction.getSourceAccount());
    assertEquals(TEST_CASH_ACCOUNT,
mockTransaction.getDestAccount());
    mockTransaction.validate();
}


该解x案生了(jin)一个稍长的试Q但该测试只x正在试的类的直接行为,而不?ATM 接口之外整个pȝ的行为。也是_(d)我们不再(g)查测试帐L(fng)最l余额是否正;我们在?Transaction 对象的单元测试中(g)查该函数Q而不是在?AtmGui 对象的单元测试中?

注:(x)Ҏ(gu)模仿对象的创造者所_(d)它应该在?validate() Ҏ(gu)内部执行自己的所有验证。在本示例中Qؓ(f)?jin)清晰v见,我们验证的某些部分攑֜?jin)测试方法内部。随着(zhn)更加熟l地使用模仿对象Q对于将多少验证职责代理l模仿对象,(zhn)将?x)深有体会(x)?

内部c魔?/B>

在清?6 中,我们使用?AtmGui 的匿名内部子cL覆盖 createTransaction Ҏ(gu)。因为我们只需要覆盖一个简单的Ҏ(gu)Q所以这是实现我们目标的明方法。如果我们覆盖多个方法或在许多测试之间共?AtmGui 子类Q那么创Z个完整的Q非匿名Q成员类是值得的?

我们q用了(jin)实例变量来存储对模仿对象的引用。这是在试Ҏ(gu)和特D化cM间共享数据的最单方法。这是可以接受的Q因为我们的试框架不是多线E的或可重入的。(如果它是多线E的或可重入的,则必ȝ synchronized 块保护我们自己。)(j)

最后,我们模仿对象本w定义ؓ(f)试cȝ专用内部c??q通常是一U便利的Ҏ(gu)Q因为将模仿对象放在用它的测试代码旁边会(x)更加清楚Q又因ؓ(f)内部cL权访问包含它们的cȝ实例变量?

心(j)不出大错

因ؓ(f)我们覆盖?jin)工厂方法来~写q个试Q所以其l果是:(x)我们的测试不再包括Q何原始创Z码(现在它在基类的工厂方法内部)(j)。添加确实包括该代码的测试也许是有益的。这与调用基cȝ工厂Ҏ(gu)q断aq回对象h正确cd一L(fng)单。例如:(x)

AtmGui atm = new AtmGui();
    Transaction t = atm.createTransaction();
    assertTrue(!(t instanceof MockTransaction));


注:(x)相反QassertTrue(t instanceof Transaction) 不能满Q因?MockTransaction 也是 Transaction?

从工厂方法到抽象工厂


此时Q?zhn)可能很想更进一步ƈ用成熟的抽象工厂对象替换工厂Ҏ(gu)Q如 Erich Gamma {h在设计模式中详细描述的那栗(请参阅参考资料)(j)。实际上Q许多h已经用工厂对象来着手这U方法,而不是用工厂Ҏ(gu) ?我们以前是这样做的,但很快就攑ּ?jin)?

第三种对象cdQ角Ԍ(j)引入pȝ?x)有一些潜在的~点Q?

它增加了(jin)复杂性,而没有相应地增加功能?

它会(x)q(zhn)更改目标对象的公用接口。如果必M入抽象工厂对象,那么(zhn)必L加一个新的公用构造函数或赋|mutatorQ方法?

许多语言对于“工厂”这一概念都附有一些约定,它们?x)?zhn)误入歧途。例如,?Java 语言中,工厂通常作ؓ(f)?rn)态方法实玎ͼ在这U情况下Q这是不合适的?

误住,本练?fn)的宗旨是对象更易于测试。通常Q用于可性的设计可以对象的 API 推向一U更清晰更模块化的状态。但它会(x)走得太远。测试驱动的设计更改不应该污染原始对象的公用接口?

?ATM CZ中,对于产品代码QAtmGui 对象始终只生一U类型的 Transaction 对象Q实际类型)(j)。测试代码希望它产生另一U类型的对象Q模仿对象)(j)。但公用 API 适应工厂对象或抽象工厂(只因为测试代码要求它q样Q是错误的设计。如果品代码无需实例化该合作者的多个cdQ那么添加该功能最l的设计不必要地变得难于理解?


扭{乑֝ 2006-02-17 09:18 发表评论
]]>
?---Java语言中的面向对象Ҏ(gu)?/title><link>http://www.tkk7.com/wangxq/articles/13086.html</link><dc:creator>扭{乑֝</dc:creator><author>扭{乑֝</author><pubDate>Thu, 15 Sep 2005 07:37:00 GMT</pubDate><guid>http://www.tkk7.com/wangxq/articles/13086.html</guid><wfw:comment>http://www.tkk7.com/wangxq/comments/13086.html</wfw:comment><comments>http://www.tkk7.com/wangxq/articles/13086.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/wangxq/comments/commentRss/13086.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/wangxq/services/trackbacks/13086.html</trackback:ping><description><![CDATA[<TABLE class=showinfo style="TABLE-LAYOUT: fixed; WORD-BREAK: break-all" cellSpacing=0 cellPadding=3 width="100%" align=center border=0> <TBODY> <TR> <TD class=showTitle align=middle>W三讌ӀJava语言中的面向对象Ҏ(gu)?/TD></TR> <TR> <TD> <TABLE cellSpacing=0 cellPadding=0 align=left border=0> <TBODY> <TR> <TD> <SCRIPT language=javascript src="/ad/js/edu_left_300-300.js"></SCRIPT> </TD></TR></TBODY></TABLE>【课前思考?<BR>  1Q?什么是对象Q什么是c?什么是包?什么是接口Q什么是内部c? <BR>  2Q?面向对象~程的特性有哪三个?它们各自又有哪些Ҏ(gu)? <BR>  3Q?你知道java语言在面向对象编E方面有何独特的特点吗? <BR><BR>隄Q?<BR>  1Q?理解Ҏ(gu)重蝲和方法重写,不要h?jin)两者的使用?<BR>  2Q?cd量和cL法的使用?<BR>  3Q?接口的用?<BR>3Q? 面向对象技术基 <BR><BR>3Q?Q? 面向对象的基本概?<BR>  面向对象的基本思想 <BR>  面向对象是一U新兴的E序设计Ҏ(gu),或者是一U新的程序设计规?paradigm),其基本思想是用对象、类、ѝ封装、消息等基本概念来进行程序设计。从现实世界中客观存在的事物Q即对象Q出发来构造Y件系l,q且在系l构造中可能运用hcȝ自然思维方式。开发一个Y件是Z(jin)解决某些问题Q这些问题所涉及(qing)的业务范围称作该软g的问题域。其应用领域不仅仅是软gQ还有计机体系l构和h工智能等?<BR><BR>1Q?对象的基本概?<BR>  对象是系l中用来描述客观事物的一个实体,它是构成pȝ的一个基本单位。一个对象由一l属性和对这l属性进行操作的一l服务组成?<BR><BR>d对象是一l属性和一l服务的装体,其中臛_有一个服务不需要接收消息就能主动执行(UCd服务Q?<BR>2Q?cȝ基本概念 <BR>cLh相同属性和服务的一l对象的集合Q它为属于该cȝ所有对象提供了(jin)l一的抽象描qͼ其内部包括属性和服务两个主要部分。在面向对象的编E语a中,cL一个独立的E序单位Q它应该有一个类名ƈ包括属性说明和服务说明两个主要部分?<BR><BR>3Q?消息 <BR><BR>消息是向对象发出的服务hQ它应该包含下述信息Q提供服务的对象标识、服务标识、输入信息和回答信息。服务通常被称为方法或函数?<BR><BR>3Q?Q? 面向对象的基本特?<BR><BR>1Q封装?<BR>  装性就是把对象的属性和服务l合成一个独立的相同单位Qƈ可能隐蔽对象的内部l节Q包含两个含义:(x) <BR>  ?把对象的全部属性和全部服务l合在一P形成一个不可分割的独立单位Q即对象Q?<BR>  ?信息隐蔽Q即可能隐蔽对象的内部l节Q对外Ş成一个边界〔或者说形成一道屏障〕,只保留有限的对外接口使之与外部发生联pR?<BR>  装的原则在软g上的反映是:(x)要求使对象以外的部分不能随意存取对象的内部数据(属性)(j)Q从而有效的避免?jin)外部错误对它?交叉感染"Q软g错误能够局部化Q大大减查错和排错的难度?<BR><BR>2Q承?<BR>  Ҏ(gu)cȝ对象拥有其一般类的全部属性与服务Q称作特D类对一般类的ѝ?<BR><BR>一个类可以是多个一般类的特D类Q它从多个一般类中承了(jin)属性与服务Q这UCؓ(f)多ѝ?<BR><BR>在java语言中,通常我们UC般类为父c(superclass,类Q,Ҏ(gu)cMؓ(f)子类(subclass)?<BR><BR>3Q多态?<BR>  对象的多态性是指在一般类中定义的属性或服务被特D类l承之后Q可以具有不同的数据cd或表现出不同的行为。这使得同一个属性或服务在一般类?qing)其各个?gu)cMh不同的语义。例如:(x)"几何囑Ş"?l图"Ҏ(gu)Q?椭圆"?多边?都是"几何?的子c,?l图"Ҏ(gu)功能不同?<BR>3Q?Q? 面向对象E序设计Ҏ(gu) <BR>  OOAQObject Oriented Analysis     面向对象的分?<BR>  OODQObject Oriented Design      面向对象的设?<BR>  OOIQObject Oriented Implementation  面向对象的实?<BR>3Q? Java语言的面向对象特?<BR><BR>3Q?Q? c?<BR>  cLjava中的一U重要的复合数据cdQ是l成javaE序的基本要素。它?yu)装了(jin)一cd象的状态和Ҏ(gu)Q是q一cd象的原Ş。一个类的实现包括两个部分:(x)cd明和cM <BR><BR>1Q类声明Q?<BR>  [public][abstract|final] class className [extends superclassName] [implements interfaceNameList] <BR>  {……} <BR>  其中Q修饰符public,abstract,final 说明?jin)类的属性,className为类名,superclassName为类的父cȝ名字QinterfaceNameList为类所实现的接口列表?<BR> 2Q类?<BR>  cM定义如下Q?<BR>  class className <BR>  {[public | protected | private ] [static] <BR>  [final] [transient] [volatile] type <BR>  variableName;                 //成员变量 <BR>  [public | protected | private ] [static] <BR>  [final | abstract] [native] [synchronized] <BR>  returnType methodName([paramList]) [throws exceptionList] <BR>   {statements}                 //成员Ҏ(gu) <BR>  } <BR> 3Q成员变?<BR>  成员变量的声明方式如下:(x) <BR>  [public | protected | private ] [static] <BR>  [final] [transient] [volatile] type <BR>  variableName;                 //成员变量 <BR>  其中Q?<BR>  static: ?rn)态变量(cd量)(j)Q相对于实例变量 <BR>  final: 帔R <BR>  transient: 暂时性变量,用于对象存档Q用于对象的串行化,见对象的串行化一?<BR>  volatile: 贡献变量Q用于ƈ发线E的׃n <BR> 4Q成员方?<BR>  Ҏ(gu)的实现包括两部分内容Q方法声明和Ҏ(gu)体?<BR>  [public | protected | private ] [static] <BR>  [final | abstract] [native] [synchronized] <BR>  returnType methodName([paramList]) <BR>  [throws exceptionList]            //Ҏ(gu)声明 <BR>   {statements}                //Ҏ(gu)?<BR>  Ҏ(gu)声明中的限定词的含义Q?<BR>  static: cL法,可通过cd直接调用 <BR>  abstract: 抽象Ҏ(gu)Q没有方法体 <BR>  final: Ҏ(gu)不能被重?<BR>  native: 集成其它语言的代?<BR>  synchronized: 控制多个q发U程的访?<BR>  ?Ҏ(gu)声明 <BR>  Ҏ(gu)声明包括Ҏ(gu)名、返回类型和外部参数。其中参数的cd可以是简单数据类型,也可以是复合数据cdQ又U引用数据类型)(j)?<BR>  对于单数据类型来_(d)java实现的是g递,Ҏ(gu)接收参数的|但不能改变这些参数的倹{如果要改变参数的|则用引用数据cdQ因为引用数据类型传递给Ҏ(gu)的是数据在内存中的地址Q方法中Ҏ(gu)据的操作可以改变数据的倹{?<BR>  ?-1说明?jin)简单数据类型与引用数据的区别?<BR>【例3-1?<BR>  import java.io.*; <BR>  public class PassTest{ <BR>  float ptValue; <BR>  public static void main(String args[]) { <BR>  int val; <BR>  PassTest pt=new PassTest(); <BR>  val=11; <BR>  System.out.println("Original Int Value is:"+val); <BR>  pt.changeInt(val);                   //值参?<BR>  System.out.println("Int Value after Change is:" +val); /*值参?<BR>                    值的修改Q没有媄(jing)响值参数的?/ <BR>  pt.ptValue=101f; <BR>  System.out.println("Original ptValue is:"+pt.ptValue); <BR>  pt.changeObjValue(pt); //引用cd的参?<BR>  System.out.println("ptValue after Change is:"+pt.ptValue);/* 引用参数值的修改Q改变了(jin)引用参数的?/ <BR>  } <BR>  public void changeInt(int value){ <BR>  value=55;            //在方法内部对值参数进行了(jin)修改 <BR>  } <BR>  public void changeObjValue(PassTest ref){ <BR>  ref.ptValue=99f;        //在方法内部对引用参数q行?jin)修?<BR>    } <BR>  } <BR><BR>?Ҏ(gu)?<BR>  Ҏ(gu)体是Ҏ(gu)法的实现Q它包括局部变量的声明以及(qing)所有合法的Java指o(h)。方法体中声明的局部变量的作用域在该方法内部。若局部变量与cȝ成员变量同名Q则cȝ成员变量被隐藏?<BR>Z(jin)区别参数和类的成员变量,我们必须使用this。this-----用在一个方法中引用当前对象Q它的值是调用该方法的对象。返回值须与返回类型一_(d)或者完全相同,或是其子cR当q回cd是接口时Q返回值必d现该接口?<BR>5Q方法重?<BR> Ҏ(gu)重蝲是指多个Ҏ(gu)享有相同的名字,但是q些Ҏ(gu)的参数必M同,或者是参数的个C同,或者是参数cd不同。返回类型不能用来区分重载的Ҏ(gu)?<BR>  参数cd的区分度一定要_Q例如不能是同一单类型的参数Q如int与long。编译器?x)根据参数的个数和类型来军_当前所使用的方法?<BR><BR>6Q?构造方?<BR>  ?构造方法是一个特D的Ҏ(gu)。Java 中的每个c都有构造方法,用来初始化该cȝ一个对象?<BR>  ?构造方法具有和cd相同的名Uͼ而且不返回Q何数据类型?<BR>  ?重蝲l常用于构造方法?<BR>  ?构造方法只能由newq算W调?<BR><BR>3Q?Q? 对象 <BR>  cd例化可生成对象,对象通过消息传递来q行交互。消息传递即ȀzL定的某个对象的方法以改变其状态或让它产生一定的行ؓ(f)。一个对象的生命周期包括三个阶段Q生成、用和消除?<BR><BR>对象的清?<BR>  当不存在对一个对象的引用Ӟ该对象成Z个无用对象。Java的垃圾收集器自动扫描对象的动态内存区Q把没有引用的对象作为垃圾收集v来ƈ释放?<BR>  System.gc( );  System.exit();//terminate the current JVM <BR>  当系l内存用或调用System.gc( )要求垃圾回收Ӟ垃圾回收U程与系l同步运行?<BR>3Q?Q? 面向对象Ҏ(gu)?<BR>  java语言中有三个典型的面向对象的Ҏ(gu):(x)装性、承性和多态性?<BR><BR>1Q?装?<BR>  java语言中,对象是对一l变量和相关Ҏ(gu)的封装,其中变量表明?jin)对象的状态,Ҏ(gu)表明?jin)对象具有的行?f)。通过对象的封装,实现?jin)模块化和信息隐藏。通过对类的成员施以一定的讉K权限Q实C(jin)cM成员的信息隐藏?<BR>?javacM的限定词 <BR>  java语言中有四种不同的限定词Q提供了(jin)四种不同的访问权限?<BR>  1Q?private <BR>  cM限定为private的成员,只能被这个类本n讉K?<BR>  如果一个类的构造方法声明ؓ(f)private,则其它类不能生成该类的一个实例?<BR>  2Q?default <BR>  cM不加M讉K权限限定的成员属于缺省的QdefaultQ访问状态:(x)friendQ可以被q个cLw和同一个包中的cL讉K?<BR>3Q?protected <BR>  cM限定为protected的成员,可以被这个类本n、它的子c(包括同一个包中以?qing)不同包中的子类Q和同一个包中的所有其他的c访问?<BR>4Q?public <BR>  cM限定为public的成员,可以被所有的c访问?<BR>【表3-1】 java中类的限定词的作用范围比?<BR><BR><BR>同一个类 <BR>同一个包 <BR>不同包的子类 <BR>不同包非子类 <BR><BR>private <BR>* <BR><BR><BR><BR><BR>default <BR>* <BR>* <BR><BR><BR><BR>protected <BR>* <BR>* <BR>* <BR><BR><BR>public <BR>* <BR>* <BR>* <BR>* <BR><BR><BR><BR><BR>2Q?l承?<BR>  通过l承实现代码复用。Java中所有的c都是通过直接或间接地l承java.lang.Objectcd到的。承而得到的cȝ为子c,被承的cȝ为父cR子cM能承父cM讉K权限为private的成员变量和Ҏ(gu)。子cd以重写父cȝҎ(gu)Q及(qing)命名与父cd名的成员变量。但Java不支持多重承,即一个类从多个超cL生的能力?<BR>?成员变量的隐藏和Ҏ(gu)的重?<BR>  子类通过隐藏父类的成员变量和重写父类的方法,可以把父cȝ状态和行ؓ(f)改变w的状态和行ؓ(f)?<BR>例如Q?<BR>  class SuperClass{ <BR>    int x; ?<BR>    void setX( ){ x=0; } ?<BR>  } <BR>  class SubClass extends SuperClass{ <BR>    int x;   //隐藏?jin)父cȝ变量x <BR>    ?<BR>    void setX( ) { //重写?jin)父cȝҎ(gu) setX() <BR>    x=5; } ? <BR>  } <BR>  注意Q子cM重写的方法和父类中被重写的方法要h相同的名字,相同的参数表和相同的q回cdQ只是函C不同?<BR>  ?super <BR>  java中通过super来实现对父类成员的访问,super用来引用当前对象的父cRSuper 的用有三种情况Q?<BR>  1Q访问父c被隐藏的成员变量,如:(x) <BR>    super.variable; <BR>  2Q调用父cM被重写的Ҏ(gu)Q如Q?<BR>    super.Method([paramlist]); <BR>  3Q调用父cȝ构造函敎ͼ如:(x) <BR>    super([paramlist]); <BR><BR>【例3-5?<BR>  import java.io.*; <BR>  class SuperClass{ <BR>    int x; <BR>    SuperClass( ) { <BR>     x=3; <BR>     System.out.println("in SuperClass : x=" +x); <BR>    } <BR>     void doSomething( ) { <BR>     System.out.println("in SuperClass.doSomething()"); <BR>    } <BR>  } <BR>  class SubClass extends SuperClass { <BR>    int x; <BR>    SubClass( ) { <BR>     super( );    //调用父类的构造方?<BR>     x=5;      //super( ) 要放在方法中的第一?<BR>     System.out.println("in SubClass :x="+x); <BR>    } <BR>     void doSomething( ) { <BR>     super.doSomething( ); //调用父类的方?<BR>     System.out.println("in SubClass.doSomething()"); <BR>     System.out.println("super.x="+super.x+" sub.x="+x); <BR>    } <BR>  } <BR>  public class Inheritance { <BR>     public static void main(String args[]) { <BR>     SubClass subC=new SubClass(); <BR>     subC.doSomething(); <BR>    } <BR>  } <BR><BR>3Q?多态?<BR>  在java语言中,多态性体现在两个斚wQ由Ҏ(gu)重蝲实现的静(rn)态多态性(~译时多态)(j)和方法重写实现的动态多态性(q行时多态)(j)?<BR>  1Q?~译时多?<BR>  在编译阶D,具体调用哪个被重载的Ҏ(gu)Q编译器?x)根据参数的不同来?rn)态确定调用相应的Ҏ(gu)?<BR>  2Q?q行时多?<BR>  ׃子类l承?jin)父cL有的属性(U有的除外)(j)Q所以子cd象可以作为父cd象用。程序中凡是使用父类对象的地方,都可以用子类对象来代ѝ一个对象可以通过引用子类的实例来调用子类的方法?<BR>  ?重写Ҏ(gu)的调用原则:(x)javaq行时系l根据调用该Ҏ(gu)的实例,来决定调用哪个方法。对子类的一个实例,如果子类重写?jin)父cȝҎ(gu)Q则q行时系l调用子cȝҎ(gu)Q如果子cȝ承了(jin)父类的方法(未重写)(j)Q则q行时系l调用父cȝҎ(gu)?<BR>在例3-6中,父类对象a引用的是子类的实例,所以,javaq行时调用子cB的callmeҎ(gu)?<BR><BR>【例3-6?<BR>  import java.io.*; <BR>  class A{ <BR>     void callme( ) { <BR>      System.out.println("Inside A''s callme()method"); <BR>     } <BR>  } <BR>  class B extends A{ <BR>     void callme( ) { <BR>      System.out.println("Inside B''s callme() Method"); <BR>     } <BR>  } <BR>  public class Dispatch{ <BR>     public static void main(String args[]) { <BR>      A a=new B(); <BR>      a.callme( ); <BR>     } <BR>  } <BR>?Ҏ(gu)重写时应遵@的原则:(x) <BR>  1Q改写后的方法不能比被重写的Ҏ(gu)有更严格的访问权限(可以相同Q?<BR>  2Q改写后的方法不能比重写的方法生更多的例外?<BR>4Q?其它 <BR>  ?final 关键?<BR>  final 关键字可以修饰类、类的成员变量和成员Ҏ(gu)Q但final 的作用不同?<BR>  1Q?final 修饰成员变量Q?<BR>  final修饰变量,则成为常量,例如 <BR>  final type variableName; <BR>  修饰成员变量Ӟ定义时同时给出初始|且以后不能被修改Q而修饰局部变量时不做要求?<BR>  2Q?final 修饰成员Ҏ(gu)Q?<BR>  final修饰Ҏ(gu)Q则该方法不能被子类重写 <BR>  final returnType methodName(paramList){ <BR>  ?<BR>  } <BR><BR>  3Q?final c:(x) <BR>  final修饰c,则类不能被?<BR>  final class finalClassName{ <BR>  ?<BR>  } <BR>  ?实例成员和类成员 <BR>  用static 关键字可以声明类变量和类Ҏ(gu)Q其格式如下Q?<BR>  static type classVar; <BR>  static returnType classMethod({paramlist}) { <BR>  ?<BR>  } <BR> 如果在声明时不用static 关键字修饎ͼ则声明ؓ(f)实例变量和实例方法?<BR>  1Q?实例变量和类变量 <BR>  每个对象的实例变量都分配内存Q通过该对象来讉Kq些实例变量Q不同的实例变量是不同的?<BR>  cd量仅在生成第一个对象时分配内存Q所有实例对象共享同一个类变量Q每个实例对象对cd量的改变都会(x)影响到其它的实例对象。类变量可通过cd直接讉KQ无需先生成一个实例对象,也可以通过实例对象讉Kcd量?<BR>  2Q?实例Ҏ(gu)和类Ҏ(gu) <BR>  实例Ҏ(gu)可以对当前对象的实例变量q行操作Q也可以对类变量q行操作Q实例方法由实例对象调用?<BR>  但类Ҏ(gu)不能讉K实例变量Q只能访问类变量。类Ҏ(gu)可以q名直接调用,也可由实例对象进行调用。类Ҏ(gu)中不能用this或super关键字?<BR>  ?-7 是关于实例成员和cL员的例子?<BR>【例3-7?<BR>  class Member { <BR>    static int classVar; <BR>    int instanceVar; <BR>    static void setClassVar(int i) { <BR>     classVar=i; <BR>     // instanceVar=i; // cL法不能访问实例变?<BR>    } <BR>    static int getClassVar() <BR>     { return classVar; } <BR>    void setInstanceVar(int i) <BR>     { classVar=i; //实例Ҏ(gu)不但可以讉Kcd量,也可以实例变?<BR>     instanceVar=i; } <BR>     int getInstanceVar( ) <BR>     { return instanceVar; } <BR>    } <BR>    public class MemberTest{ <BR>     public static void main(String args[]) { <BR>         Member m1=new member(); <BR>         Member m2=new member(); <BR>         m1.setClassVar(1); <BR>         m2.setClassVar(2); <BR>         System.out.println("m1.classVar="+m1.getClassVar()+" <BR>                   m2.ClassVar="+m2.getClassVar()); <BR>         m1.setInstanceVar(11); <BR>         m2.setInstanceVar(22); <BR>         System.out.println("m1.InstanceVar="+m1.getInstanceVar <BR>              ()+" m2.InstanceVar="+m2.getInstanceVar()); <BR>     } <BR>    } <BR>?cjava.lang.Object <BR>  cjava.lang.Object处于java开发环境的cdơ的栚wQ其它所有的c都是直接或间接地承了(jin)此类。该cd义了(jin)一些最基本的状态和行ؓ(f)。下面,我们介绍一些常用的Ҏ(gu)?<BR>  equals() Q比较两个对?引用)是否相同?<BR>  getClass()Q返回对象运行时所对应的类的表C,从而可得到相应的信息?<BR>  toString()Q用来返回对象的字符串表C?<BR>  finalize()Q用于在垃圾攉前清除对象?<BR>  notify(),notifyAll(),wait()Q用于多U程处理中的同步?<BR><BR>3Q?Q?抽象cd接口 <BR><BR> 1Q?抽象c?<BR>  java语言中,用abstract 关键字来修饰一个类Ӟq个cd做抽象类Q用abstract 关键字来修饰一个方法时Q这个方法叫做抽象方法。格式如下:(x) <BR>  abstract class abstractClass{ …} //抽象c?<BR>  abstract returnType abstractMethod([paramlist]) //抽象Ҏ(gu) <BR>  抽象cd被l承Q抽象方法必被重写。抽象方法只需声明Q无需实现Q抽象类不能被实例化Q抽象类不一定要包含抽象Ҏ(gu)。若cM包含?jin)抽象方法,则该cd被定义为抽象类?<BR><BR>若一个类l承?jin)一个抽象类Q则抽象cȝ抽象Ҏ(gu)必须被实玎ͼ否则子类必须声明为abstract. <BR> 2Q?接口 <BR>  接口是抽象类的一U,只包含常量和Ҏ(gu)的定义,而没有变量和Ҏ(gu)的实玎ͼ且其Ҏ(gu)都是抽象Ҏ(gu)。它的用处体现在下面几个斚wQ?<BR>  ?通过接口实现不相关类的相同行?而无需考虑q些cM间的关系?<BR>  ?通过接口指明多个c需要实现的Ҏ(gu)?<BR>  ?通过接口?jin)解对象的交互界?而无需?jin)解对象所对应的类?<BR>1Q接口的定义 <BR>  接口的定义包括接口声明和接口体?<BR>  接口声明的格式如下:(x) <BR>  [public] interface interfaceName[extends listOfSuperInterface] { ?} <BR>  extends 子句与类声明的extends子句基本相同Q不同的是一个接口可有多个父接口Q用逗号隔开Q而一个类只能有一个父cR?<BR>  接口体包括常量定义和Ҏ(gu)定义 <BR>  帔R定义格式为:(x)type NAME=value; 该常量被实现该接口的多个cd? hpublic ,final, static的属性。在接口中只能声明常量,不可以声明变量?<BR>  Ҏ(gu)体定义格式ؓ(f)Q?h public和abstract属性,不能声明为protected) <BR>  returnType methodName([paramlist])Q?<BR><BR>注意Q在接口的实现类中,实现的接口方法必d明ؓ(f)public Q因为接口中定义的方法ؓ(f)publicQ默认)(j)。所以其实现必须声明为public.否则~译不会(x)通过?<BR>2Q接口的实现 <BR>  在类的声明中用implements子句来表CZ个类使用某个接口Q在cM中可以用接口中定义的常量,而且必须实现接口中定义的所有方法。一个类可以实现多个接口,在implements子句中用逗号分开?<BR>3Q?接口cd的?<BR>  接口作ؓ(f)一U引用类型来使用。Q何实现该接口的类的实例都可以存储在该接口cd的变量中Q通过q些变量可以讉KcL实现的接口中的方法?<BR>3Q?Q? 内部c?<BR><BR> 1Q?内部cȝ定义和用:(x) <BR>  内部cL在一个类的内部嵌套定义的c,它可以是其它cȝ成员Q也可以在一个语句块的内部定义,q可以在表达式内部匿名定义?<BR>  内部cL如下Ҏ(gu):(x) <BR>  ?一般用在定义它的类或语句块之内,在外部引用它时必ȝ出完整的名称.名字不能与包含它的类名相同?<BR>  ?可以使用包含它的cȝ?rn)态和实例成员变量,也可以用它所在方法的局部变量?<BR>  ?可以定义为abstract?<BR>  ?可以声明为private或protected?<BR>  ?若被声明为static,变成了(jin)层c?不能再用局部变量?<BR>  ?若想在Inner Class中声明Q何static成员,则该Inner Class必须声明为static?<BR>?-8?<BR>  import java.awt.*; <BR>  import java.awt.event.*; <BR>  public class TwoListenInner { <BR>    private Frame f; <BR>    private TextField tf; <BR>      public static void main(String args[]) { <BR>       TwoListenInner that=new TwoListenInner(); <BR>       that.go(); <BR>    } <BR>    public void go() { <BR>       f=new Frame("Two listeners example"); <BR>       f.add("North",new Label("Click and drag the mouse")); <BR>       tf=new TextField(30); <BR>       f.add("South",tf); <BR>       f.addMouseMotionListener(new MouseMotionHandler()); <BR>       f.addMouseListener(new MouseEventHandler()); <BR>       f.setSize(300,300); <BR>       f.setVisible(true); <BR>    } <BR>    public class MouseMotionHandler extends MouseMotionAdapter { <BR>      public void mouseDragged(MouseEvent e){ <BR>       String s="Mouse dragging:X="+e.getX()+"Y="+e.getY(); <BR>       tf.setText(s); <BR>      } <BR>    } <BR>    public class MouseEventHandler extends MouseAdapter { <BR>      public void mouseEntered(MouseEvent e){ <BR>       String s="The mouse entered"; <BR>       tf.setText(s); <BR>      } <BR>      public void mouseExited(MouseEvent e){ <BR>       String s="The mouse left the building"; <BR>       tf.setText(s); <BR>      } <BR>    } <BR>  } <BR><BR>说明QFramecȝaddҎ(gu)来自于其先cContainerc,addMouseMotionListener和addMouseListenerҎ(gu)来自于其先cComponent, addMouseListenerҎ(gu)的参Cؓ(f)MouseListener接口QMouseAdaptercL实现?jin)MouseListener接口的类。可见图形界面对于外部事件的响应是通过dlistener实现?<BR>2Q?匿名cȝ定义和用:(x) <BR>  匿名cL一U特D的内部c,它是在一个表辑ּ内部包含一个完整的cd义。通过对例6-7中go()部分语句的修改,我们可以看到匿名cȝ使用情况?<BR>  public void go() { <BR>         f=new Frame("Two listeners example"); <BR>         f.add("North",new Label("Click and drag the mouse")); <BR>         tf=new TextField(30); <BR>         f.add("South",tf); <BR>         f.addMouseMotionListener(new MouseMotionHandler(){ <BR>         /*定义?jin)一个匿名类Q类名没有显式地l出Q只是该cL <BR>          MouseMotionHandlercȝ子类*/ <BR>           public void mouseDragged(MouseEvent e){ <BR>             String s="Mouse dragging:X="+e.getX()+"Y <BR>             ="+e.getY(); <BR>             tf.setText(s); <BR>           } <BR>         }); <BR>         f.addMouseListener(new MouseEventHandler()); <BR>         f.setSize(300,300); <BR>         f.setVisible(true); <BR>         } <BR> 3Q?内部cȝ优缺点:(x) <BR>  ?优点:节省~译后生的字节码文件的大小 <BR>  ?~点:使程序结构不清楚 <BR><BR>?fn)题Q?<BR><BR>1 Q造型不可以从父类向子c造型Q只能从子类向父c造型。否则编?时可以通过Q执行时?x)报?<BR><BR>如:(x)SubClass sc = new SubClass(); BaseClass bc = (BaseClass)sc ;---是正的 <BR><BR>?BaseClass bc = new BaseClass(); SubClass sc = (SubClass)bc ;---是错误的 <BR><BR>BaseClass bc = new SubClass()也是正确的,q且在调用bc中的Ҏ(gu)时执行的Ҏ(gu)体是子类的方法体Q但该方法必d时在子类Q父cM同时存在Q若子类中有Q而父cM没有Q则不可以这栯用bc.subMethod(); <BR><BR>若两个类都承于同一个类(必须是直接承,否则不对)Q则q两个类可以互相赋|如:(x)Panel和Frame 同承于ContainerQ所以Panel p = new Frame() Q和Frame f = new Panel()都是正确的, <BR></TD></TR></TBODY></TABLE><img src ="http://www.tkk7.com/wangxq/aggbug/13086.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/wangxq/" target="_blank">扭{乑֝</a> 2005-09-15 15:37 <a href="http://www.tkk7.com/wangxq/articles/13086.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转蝲>http://www.tkk7.com/wangxq/articles/13077.html扭{乑֝扭{乑֝Thu, 15 Sep 2005 06:53:00 GMThttp://www.tkk7.com/wangxq/articles/13077.htmlhttp://www.tkk7.com/wangxq/comments/13077.htmlhttp://www.tkk7.com/wangxq/articles/13077.html#Feedback0http://www.tkk7.com/wangxq/comments/commentRss/13077.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/13077.html  [转帖]Java面向对象概述
Java面向对象概述    leeakQ原作)(j)

(如今的程序领域,大家都在_(d)面向对象OOP,但是真正能理解面向对象的含义的程序员却很,I竟什么是对象Q怎样面向对象)
一Q面向对象:(x)
1.何谓对象Q在面向对象E序设计中,我们问题空间中的元素以?qing)他们在?gu)I间中的的表C物UC对象QobjectQ?br /> Alan Kayȝ?jin)smalltalk中对象的5大基本特征:(x)
所有的东西都是对象?br />E序是一大堆对象的集合,他们通过消息传递,各个对象之间知道要做些什么?br />每个对象都分配有自己的存储空_(d)可容U_他对象?br />每个对象都有一个类型?br />同一cȝ所有对象能接收相同的消息?br /> -----而所有的~程语言的最l目的是提供一U抽象方?---
2Q对象的接口Q我们向对象发出h是通过它的接口定义的,对象的类型决定了(jin)它的接口形式?br />3QOOP中唯一兛_(j)的:(x) 是接口是什么,像汽R的发动机一P我们不必要知道它的结构是什么,只要它能工作p?jin)。所有的E序是由一定的属性(数据Q和行ؓ(f)Q方法)(j)l成的,不同的对象访问通过函数调用来完成,对象间的所有交都是通过Ҏ(gu)调用Q通过对封装数据对象,很大E度上提高复用率?br />4Q对象的3个主要特征:(x)
      behavior—说明这个对象能做什么?br />      State—当对象施加Ҏ(gu)时对象的反映?br />      I(yng)dentity---与其他相D为对象的区分标志Q每一个对象有唯一的indentity, 而这3者是怺影响的?br />5Q面向对象中最重要的思想 是c,cL模板是蓝图,从类中构造一个对象,卛_Z(jin)一个类的实例。(cd比一个徏材市(jng)场,其中有许多子c?-各种各样的装饰材料,而我们装修自q房子p选择我们需要的材料Q(Z(jin)建立我们自己的程序,我们必须选 择我们需要的c)(j)q个比喻可以很Ş象的解释cL什么?br />6Q类之间的关p:(x)
        依赖关系Quse-a  AcM的一个方法操作了(jin)另一个类中的对象?br />        聚合关系Qhas-a  AcM的对象包含Bcȝ对象?br />        l承关系Qis-a   Al承?jin)Bc,此时AcM仅有?jin)BcȝҎ(gu)Q还加入?jin)自qҎ(gu)。以便我们创建我们自己需要的对象?br />Java中定义的每一个类都必ȝ承另一个类Q用关键字extendsQ如果一个类在定义中不现实用关键字extends,q个cd?x)隐式承ObjectcRObjectcd叫根类Q或基类。,我们从根类l承来的叫子cRJava中每个类都是根超cȝ子类?/p>

8Q接口(interfaceQ规定了(jin)可对特定的对象发出哪些请求?br />9Q?重新使用接口Q创建出一个数据类型后Q当需要新建立一个数据类型去实现相同的功能,是很没有意义的一件事Q此时对其克隆后Q再Ҏ(gu)情况改进实现自己的目的就是ѝ?/p>

10Q封装:(x)是把数据和行ؓ(f)l合在一起在一个包中,q对对象使用者隐藏数据的实现q程。Java?个关键字来设|边界,从而进行对数据的隐藏。Public(共有)的定义Q何h都可使用.privateQ私有)(j)意味着除你自己Q类型创及(qing)那个cd的内部函数成员可以访问外其他MZ用都?x)生错误。FriendlyQ友好)(j)
意味在包(package)中是可以讉K的。(以上q程也可叫方案隐藏)(j)
11Q引用(HandleQ操控对象:(x)
    当创Z个引用时必须要对其进行初始化
  ? String s=”happy”(未徏立连接)(j)
     String s=new string(“happy?与一个新的对象连接用new 。此句徏立了(jin)一个引用,q且q接引用q初始化对象 赋值字W串“happy?
12.对象的创建及(qing)存在旉Q数据存攄地点
       1Q寄存器-速度快,数量,在cpu内部Q我们对寄存器没有控制权?br />       2Q堆栈:(x)ȝ长规内存中,堆栈指针下移建立新的内存Q上U释攑ֆ存?br />      3Q堆Q常用内存池Q保存对象,有极大的灉|性,java的数据就存放在此Q但是要以时间及(qing)效率Z仗Java的对象徏立是在程序运行时才决定。而c++是在设计时徏立对象?br /> 对象的生存时_(d)lifetimeQjava提出的垃圾收集器可以很好的发现无d用的对象Q用GCQgrabage collectorQ垃圾收集器。清除对象,释放内存?br />为此我们p付出一定的q行期的开销?br />13.在此我们׃(x)有这样一个印?一个程序只是一pd对象的集?他们的方法将其他对象作ؓ(f)自己的变量?
14.主要cd: java的主要类型有:boolean,char,byte,short,int,long,float,double,void.q些ȝ型的大小都不随机器的l构变化而变?提供?jin)java很好的可UL?
15.字段Ҏ(gu):字段又叫数据成员,成员函数又叫Ҏ(gu),java的全部工作就是定义类,制作累得对象?qing)发送消?
16.一个程序只是一pd对象的集?他们的方法将其他的对象作q变量使用,而且消息发l那些对?
17.名字的可见?Z(jin)使名字不重复,作者可以定义自q?一般用自己域名的倒写形式 ? COM.:Leeak.utility.foidles
18.static关键?即没有创徏对象,也需要一愕能调用的方?此时可以使用static
19.java.lang默认自动的导入每个javaE序?br />20.OOP中对象对属性和Ҏ(gu)的封?对象h信息的隐蔽的性质,对细节的隐藏,对象只需要知道去q样?而不知道如何做的l节,cȝҎ(gu)应}慎控制对java数据的访?可以用getdҎ(gu),用set修改Ҏ(gu).

21:pakage:Java API中每个类和接口属于一个特定的?包实际上?jng)对cd接口q行l织的目录结?提供?jin)一UY件复用机?
22.创徏可复用的cd步骤:1.定义一个publicc?br />                                               2.选择一个包?q把pakage语句加到可复用的cȝ源码?
                           3.~译q个c?
4.把可复用的类导入其他E序中即?
23.java中提出在cd义的括号外的仅有2个语?pakage和import.
24.软g的复用?软g的复用性就是利用的已有的,定义良好的的l过仔细试的文档清晰的可移植的易于获得的Y件构件开发新的Y?

以上是java面向对象的一些基本术语的概述,其中的有些部分可以扩展的更深,看过think in java的 朋友就?x)有此种感?此文章向对初学者阐qC(jin)面向对象的基本概?对已是javaE序员的朋友可以对他们的基本知识做以回顾.


http://www.csdn.net/Develop/article/22/22198.shtm



扭{乑֝ 2005-09-15 14:53 发表评论
]]>
php和mysql分页昄详解http://www.tkk7.com/wangxq/articles/11770.html扭{乑֝扭{乑֝Thu, 01 Sep 2005 09:21:00 GMThttp://www.tkk7.com/wangxq/articles/11770.htmlhttp://www.tkk7.com/wangxq/comments/11770.htmlhttp://www.tkk7.com/wangxq/articles/11770.html#Feedback0http://www.tkk7.com/wangxq/comments/commentRss/11770.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/11770.html1.数据库连接的cdbClass.inc?BR><?php
/**
* a class use to connect the MySQL database and do some query
*/
class dbClass {
private $hostName = "localhost:3306";
private $dbName = "ebooklib";
private $Login = "root";
private $Password = "";
private $conn;
private $result;

function dbClass(){
$this->conn = mysql_connect("$this->hostName","$this->Login","$this->Password");
mysql_select_db("$this->dbName", $this->conn);
}

function executeQuery($sql){
$this->result = mysql_query("$sql",$this->conn);
return $this->result;
}

function closeConn(){
mysql_close($this->conn);
}
}

?>

2.解决分页问题的PageQuery.inc
<?php
include("dbClass.inc");
class PageQuery extends dbClass {
    private $Offset;             // 记录偏移?
    private $Total;             // 记录L
     
    private $maxLine;             // 记录每页昄记录?
    private $result;             // d的结?
   
    private $TPages;             // 总页?
    private $CPages;             // 当前|
   
    private $PageQuery;         // 分页昄要传递的参数
    private $Query;             // query 语句
    private $QueryPart;         // " FROM " 以后?query 部分
    private $QueryString;         // ? 以后部分 
     
    private $FilePath;
           
    // 每页昄行数
    function PageQuery($pageLine=10) {   
        $this->dbClass();
        $this->maxLine = $pageLine;
      }
     
      // 记录L
    function getTotal(){
        return $this->Total;
    }
     
      // 昄总页?BR>    function getTotalPages() {
        return $this->TPages;
    }

    //昄当前所在页?BR>    function getCurrenPages() {         
        return $this->CPages;
    }
   
    function myQuery($sql, $flag=1){
            GLOBAL $offset;
            $this->Query = $sql;
       
        // 获取文g?BR>        //$this->FilePath = $GLOBALS["REQUEST_URI"];
            $this->FilePath = $GLOBALS["SCRIPT_NAME"];
           
            // 获取查询条g
            $this->QueryString = $GLOBALS["QUERY_STRING"];           
            //echo $this->QueryString . "<br>";           
           
            // 截取 " from " 以后?query 语句
            $this->QueryPart = trim(strstr($sql, " from "));
           
            // 计算偏移?BR>            if (!isset($offset)) $this->Offset = 0;
            else $this->Offset = (int)$offset;
           
           
       
       
        // 计算ȝ记录条数
        $SQL = "SELECT Count(*) AS total " . $this->QueryPart;
        $this->result = $this->executeQuery($SQL);
            $this->Total = mysql_result($this->result,0);
           
            // 讄当前|和总页?BR>        $this->TPages = (double)Ceil((double)$this->Total/$this->maxLine);
        $this->CPages = (double)Floor((double)$this->Offset/$this->maxLine+1);
       
       
        // Ҏ(gu)条g判断Q取出所需记录
        if ($this->Total > 0) {
            //flag{于1表示要分,否则不分?BR>            if($flag==1)
                $SQL = $this->Query . " LIMIT " . $this->Offset . " , " . $this->maxLine;
            else
                $SQL = $this->Query;           
            echo $SQL . "<br>";
            $this->result = $this->executeQuery($SQL);
        }
        return $this->result;
    }
   
    //**********昄页提示?************ 
    // 昄首页、下c(din)上c(din)尾?BR>    function PageLegend() {       
     $str = "";
        $i = 0;
        $first = 0;
        $next = 0;
        $prev = 0;
        $last = 0;
   
            $next = $this->Offset + $this->maxLine;
            $prev = $this->Offset - $this->maxLine;
            $last = ($this->TPages - 1) * $this->maxLine;
           
            GLOBAL $offset;
            if (!isset($offset)) $this->QueryString .= "&offset=";
            else{
                $this->QueryString = substr($this->QueryString,0,strrpos($this->QueryString,'&')) . "&offset=";
            }
           
            if($this->Offset >= $this->maxLine)
            $str .=  " <A href=" . $this->FilePath . "?" . $this->QueryString . $first . ">首页</A> ";
            else $str .= " 首页 ";
       
        if($prev >= 0)
            $str .=  " <A href=" . $this->FilePath . "?" . $this->QueryString . $prev . ">上一?lt;/A> ";
        else $str .= " 上一?";
       
        if($next < $this->Total)
            $str .=  " <A href=" . $this->FilePath . "?" . $this->QueryString . $next . ">下一?lt;/A> ";
        else $str .= " 下一?";
       
        if($this->TPages != 0 && $this->CPages < $this->TPages)
            $str .=  " <A href=" . $this->FilePath . "?" . $this->QueryString . $last . ">N</A>";
        else $str .= " N ";

        $str .= " |Q? . $this->getCurrenPages() . "/" . $this->getTotalPages() . "?";
        $str .= $this->maxLine . "??" . "? . $this->Total . "?;
            return $str;
    }
}
?>
3.用于昄l果的mysql_result_all.inc
<?
function mysql_result_all($result,$format="") {
echo "<table $format><tr>";
for($i=0;$i<mysql_num_fields($result);$i++) {
echo "<th>".mysql_field_name($result,$i)."</th>";
}
echo "</tr>";
while($row = mysql_fetch_array($result) ) {
for($i=0;$i<mysql_num_fields($result);$i++) {
echo "<td>".$row[$i]."</td>";
}
echo "</tr>";
}
echo "</table>";
}
?>
4.昄面的代码:(x)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>phpQmysql分页昄</title>
</head>

<body>
<?php
include("PageQuery.inc");

$pq = new PageQuery(5); // 获取Connection
$res=$pq->myQuery("select * from users"); // 执行查询

require("mysql_result_all.inc");
mysql_result_all($res,"border=1");
echo $pq->PageLegend(2); // 页?BR>?>
</body>
</html>



扭{乑֝ 2005-09-01 17:21 发表评论
]]>
转蝲http://www.tkk7.com/wangxq/articles/11709.html扭{乑֝扭{乑֝Thu, 01 Sep 2005 01:40:00 GMThttp://www.tkk7.com/wangxq/articles/11709.htmlhttp://www.tkk7.com/wangxq/comments/11709.htmlhttp://www.tkk7.com/wangxq/articles/11709.html#Feedback0http://www.tkk7.com/wangxq/comments/commentRss/11709.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/11709.html static用法
星☆?发表?2005-8-15 13:04:35
请先看下面这D늨序:(x)

以下是代码片D:(x)
    public class Hello{
      public static void main(String[] args){ //(1)
        System.out.println("Hello,world!");   //(2)
      }
    }

  看过q段E序Q对于大多数学过Java 的从来说Q都不陌生。即使没有学qJavaQ而学q其它的高语言Q例如CQ那你也应该能看懂这D代码的意思。它只是单的输出“Hello,world”,一点别的用处都没有Q然而,它却展示?jin)static关键字的主要用法?/P>

  ?处,我们定义?jin)一个静(rn)态的Ҏ(gu)名ؓ(f)mainQ这意味着告诉Java~译器,我这个方法不需要创Z个此cȝ对象卛_使用。你q得你是怎么q行q个E序吗?一般,我们都是在命令行下,打入如下的命?加下划线为手动输?Q?/P>

  javac Hello.java
  java Hello
  Hello,world!

  q就是你q行的过E,W一行用来编译Hello.javaq个文gQ执行完后,如果你查看当前,?x)发现多了(jin)一个Hello.class文gQ那是W一行生的Java二进制字节码。第二行是执行一个JavaE序的最普遍做法。执行结果如你所料。在2中,你可能会(x)惻IZ么要q样才能输出。好Q我们来分解一下这条语句。(如果没有安装Java文档Q请到Sun的官方网站浏览J2SE APIQ首先,System是位于java.lang包中的一个核?j)类Q如果你查看它的定义Q你?x)发现有q样一行:(x)public static final PrintStream out;接着在进一步,点击PrintStreamq个链接,在METHOD面Q你?x)看到大量定义的?gu)Q查找printlnQ会(x)有这样一行:(x)

  public void println(String x)?/P>

  好了(jin)Q现在你应该明白Z么我们要那样调用?jin),out是System的一个静(rn)态变量,所以可以直接用,而out所属的cL一个printlnҎ(gu)?/P>

  ?rn)态方?/STRONG>

  通常Q在一个类中定义一个方法ؓ(f)staticQ那是_(d)无需本类的对象即可调用此Ҏ(gu)。如下所C:(x)

以下是代码片D:(x)
  class Simple{
     static void go(){
       System.out.println("Go...");
     }
  }
  public class Cal{
    public static void main(String[] args){
      Simple.go();
    }
  }

  调用一个静(rn)态方法就是“类?Ҏ(gu)名??rn)态方法的使用很简单如上所C。一般来_(d)?rn)态方法常ؓ(f)应用E序中的其它cL供一些实用工h用,在Java的类库中大量的静(rn)态方法正是出于此目的而定义的?/P>

  ?rn)态变?/STRONG>

  ?rn)态变量与?rn)态方法类伹{所有此cd例共享此?rn)态变量,也就是说在类装蝲Ӟ只分配一块存储空_(d)所有此cȝ对象都可以操控此块存储空_(d)当然对于final则另当别Z(jin)。看下面q段代码Q?/P>

以下是代码片D:(x)
  class Value{
    static int c=0;
    static void inc(){
      c++;
    }
  }
  class Count{
    public static void prt(String s){
      System.out.println(s);
    }
    public static void main(String[] args){
      Value v1,v2;
      v1=new Value();
      v2=new Value();
      prt("v1.c="+v1.c+"  v2.c="+v2.c);
      v1.inc();
      prt("v1.c="+v1.c+"  v2.c="+v2.c);  
    }
  }

  l果如下Q?/P>

  v1.c=0  v2.c=0
  v1.c=1  v2.c=1

  由此可以证明它们׃n一块存储区。static变量有点cM于C中的全局变量的概c(din)值得探讨的是?rn)态变量的初始化问题。我们修改上面的E序Q?/P>

以下是代码片D:(x)
  class Value{
    static int c=0;
    Value(){
      c=15;
    }
    Value(int i){
      c=i;
    }
    static void inc(){
      c++;
    }
  }
  class Count{
    public static void prt(String s){
      System.out.println(s);
    }
      Value v=new Value(10);
      static Value v1,v2;
      static{
        prt("v1.c="+v1.c+"  v2.c="+v2.c);
        v1=new Value(27);
        prt("v1.c="+v1.c+"  v2.c="+v2.c);
        v2=new Value(15);
        prt("v1.c="+v1.c+"  v2.c="+v2.c);
      }
    public static void main(String[] args){
      Count ct=new Count();
      prt("ct.c="+ct.v.c);
      prt("v1.c="+v1.c+"  v2.c="+v2.c);
      v1.inc();
      prt("v1.c="+v1.c+"  v2.c="+v2.c);
      prt("ct.c="+ct.v.c);
    }
  }
  q行l果如下Q?/P>

  v1.c=0  v2.c=0
  v1.c=27  v2.c=27
  v1.c=15  v2.c=15
  ct.c=10
  v1.c=10  v2.c=10
  v1.c=11  v2.c=11
  ct.c=11

  q个E序展示?jin)?rn)态初始化的各U特性。如果你初次接触JavaQ结果可能o(h)你吃惊。可能会(x)对static后加大括h到困惑。首先要告诉你的是,static定义的变量会(x)优先于Q何其它非static变量Q不论其出现的顺序如何。正如在E序中所表现的,虽然v出现在v1和v2的前面,但是l果却是v1和v2的初始化在v的前面。在static{后面跟着一D代码,q是用来q行昑ּ的静(rn)态变量初始化Q这D代码只?x)初始化一ơ,且在c被W一ơ装载时。如果你能读懂ƈ理解q段代码Q会(x)帮助你对static关键字的认识。在涉及(qing)到承的时候,?x)先初始化父cȝstatic变量Q然后是子类的,依次cL。非?rn)态变量不是本文的主题Q在此不做详l讨论,请参考Think in Java中的讲解?/P>

  ?rn)态类

  通常一个普通类不允许声明ؓ(f)?rn)态的Q只有一个内部类才可以。这时这个声明ؓ(f)?rn)态的内部cd以直接作Z个普通类来用,而不需实例一个外部类。如下代码所C:(x)

以下是代码片D:(x)
  public class StaticCls{
    public static void main(String[] args){
      OuterCls.InnerCls oi=new OuterCls.InnerCls();
    }
  }
  class OuterCls{
    public static class InnerCls{
      InnerCls(){
        System.out.println("InnerCls");
      }
     }
  }

  输出l果?x)如你所料:(x)

  InnerCls

  和普通类一栗内部类的其它用法请参阅Think in Java中的相关章节Q此处不作详解?BR>
static指向同一块内存,当你把某数据成员或函数声明ؓ(f)staticӞ它就不再局限于所属的class objectQ这样就有了(jin)一个好处,可以让你在不建立M对象的情况下Q调用你声明的函数?BR>举一个例子:(x)
class Test{
static int i=1;
}
Test t1=new Test();
Test t2=new Test();
那么t1.i和t2.i都是1Q它们其中Q一个值改变,另外的也?x)一h变?/P>


阅读全文() | 回复(0) | 引用通告() | ~辑
 



扭{乑֝ 2005-09-01 09:40 发表评论
]]>
转蝲http://www.tkk7.com/wangxq/articles/10916.html扭{乑֝扭{乑֝Wed, 24 Aug 2005 06:45:00 GMThttp://www.tkk7.com/wangxq/articles/10916.htmlhttp://www.tkk7.com/wangxq/comments/10916.htmlhttp://www.tkk7.com/wangxq/articles/10916.html#Feedback0http://www.tkk7.com/wangxq/comments/commentRss/10916.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/10916.htmlWindows下PHP5和Apache的安装与配置
作者:(x) mylxiaoyi
 
在这里以PHP5Z介绍一?A class=bluekey target=_blank>Windows?/FONT>Apache和PHP5的安装与配置Ҏ(gu)?BR>一 下蝲安装E序
  Apache可以从http://www.apache.org/dyn/closer.cgi/httpd/binaries/win32/下蝲

  PHP可以从http://www.php.net下蝲.

  ?安装E序

  1、Apache的程序安装相Ҏ(gu)说要较ؓ(f)的简单一?我们从网站下来的是一个Windows下的安装E序,我们可以直接双击q行,q样我们׃利Apache在我们的?sh)脑上安下家来?jin)?BR>
  2、我们在q里要注意的是在下载PHP时一定要下蝲那个zip包的,而不要下载Installer?我们下载下来的PHP包解压到C盘下的根目录?q将解压出来的文件夹改名为php?BR>
  ?配置

  1、最好是无论使用何种接口QCGI 或?SAPIQ都保 php5ts.dll 可用Q因此必d此文件放?Windows 路径中。最好的位置?Windows ?system 目录Q?

c:\windows\system for Windows 9x/ME
c:\winnt\system32 for Windows NT/2000 或?c:\winnt40\system32 for Windows NT/2000 服务器版
c:\windows\system32 for Windows XP

  2、下一步是讑֮有效?PHP 配置文gQphp.ini。压~包中包括两?ini 文gQphp.ini-dist ?php.ini-recommended。徏议?php.ini-recommendedQ因为此文g寚w认设|作?jin)性能和安全上的优化?BR>
  选择?ini 文g拯?PHP 能够扑ֈ的目录下q改名ؓ(f) php.ini。PHP 默认?Windows 目录下搜?php.iniQ?

  3 ?Windows 9x/ME/XP 下将选择?ini 文g拯?%WINDIR%Q通常?c:\windows?

  ?Windows NT/2000 下将选择?ini 文g拯?%WINDIR% ?%SYSTEMROOT% 下,通常?c:\winnt ?c:\winnt40 对应于服务器版本?

  4 Apache中PHP的设|?BR>
  有两U方法?PHP 工作?Windows 下的 Apache。一是?CGI 二进制文?/FONT>Q另一是?Apache 模块 DLL。无论那U方法,(zhn)首先必d?Apache 服务器,然后~辑 httpd.confQ以配置 Apache ?PHP 协同工作?

  如果我们要用CGI二进制文?那么我们要将如下指o(h)插入?Apache ?httpd.conf 配置文g中,以设|?CGI 二进制文Ӟ(x)

  PHP ?CGI 方式安装?Apache 2.0:

ScriptAlias /php/ "c:/php/"
AddType application/x-httpd-php .php
Action application/x-httpd-php "/php/php.exe"

  如果我们x PHP 作ؓ(f) Apache 2.0 的模块,那么׃定要Ud php4ts.dll ?winnt/system32QWindows NT/2000Q或 windows/system32QWindows XPQ,覆盖原有文gQ如果有的话Q,对于 PHP 5Q这个文件是 php5ts.dll。然后我们要插入如下两行?httpd.conf 中,以我们?PHP 作ؓ(f) Apache ?PHP-Module 安装Q?BR>
  PHP 以模块方式安装到 Apache 2.0:

; For PHP 4 do something like this:
LoadModule php4_module "c:/php/php4apache2.dll"
AddType application/x-httpd-php .php

; For PHP 5 do something like this:
LoadModule php5_module "c:/php/php5apache2.dll"
AddType application/x-httpd-php .php

  l过q样的配|以?我们安装好?jin)我们的PHP?A class=bluekey target=_blank>Apache服务?/FONT>?jin)。我们可以简单的试一?

  1、测试Apache:

  我们打开览?在地址栏中输入localhost,如果可以出现Apache面,则说明我们的Apache可以正常工作?jin)?BR>
  2、测试PHP讄:

  我们可以单的~写一个PHP面,我们可以用文本编辑器,输入下面的代?

QhtmlQ?BR>QheadQ?BR>Q?A class=bluekey target=_blank>titleQ?BR>hello
Q?titleQ?BR>Q?headQ?BR>QbodyQ?BR>Q?php echo "hello,php"; ?Q?BR>Q?bodyQ?BR>Q?htmlQ?/TD>

  然后这个文件存为hello.php,其攑֜Apache的htdocs目录?我们也可以在http.conf文g中来更改q个目录?,然后在我们的览器中输入http://localhost/hello.php,如果能够正确的显Chello,phpp明我们的PHP配置是可以正常工作的?BR>
  q样以后我们也可以来设计我们的PHP站点?jin)?BR>


扭{乑֝ 2005-08-24 14:45 发表评论
]]>
վ֩ģ壺 5gӰԺ5gˬӰԺ| ߹ۿ| һƷ޶߲| þ޾Ʒ벥| ۺС˵ɫɫ| ޾ƷƵ߹ۿ㶮| av߹ۿҰ| aëƬ߹ۿ| ޳꿴Ƭ߹ۿ| ޹ۺϾþ| һӰԺ| þ޸ۺ| ղһ| ղһ| Ѷ| avһۿ | 99Ʒһ| ҹ븣Ƶ| һƵ| aëƬѹۿվ| ߹ۿxxxx| þþþþùƷͬ | 91͵߹ۿ| ŷ Ƶ С˵| ޾Ʒ˳߲va| ޾ƷѿӰԺ| aëƬվ| պƵ| ĻӰѹۿ| ۺ| vaĻþ| 츾밮v߹ۿ| Ļ뱬| þƷѹۿ| ƷѸþ| þþþùɫAVѿͼƬ| ߹ۿƬ| 츾AVӰ| ŷ޾Ʒ| mm1313޹ƷԿ| ƬAëƬ|