Cactus
Cactus是一个基于JUnit框架的简单测试框Ӟ用来单元试服务端Java代码。Cactus框架的主要目标是能够单元试服务端的使用Servlet对象的JavaҎ(gu)如HttpServletRequest,HttpServletResponse,HttpSession{?/strong>
??xml version="1.0" encoding="utf-8" standalone="yes"?> java实现Ҏ(gu)件的各种操作
<%
String filePath="c:/aaa/";
filePath=filePath.toString();//中文转换
java.io.File myFilePath=new java.io.File(filePath);
if(!myFilePath.exists())
myFilePath.mkdir();
%>
<%@ 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();
%>
<%
String filePath="c:/支出证明?/span>.xls";
filePath=filePath.toString();
java.io.File myDelFile=new java.io.File(filePath);
myDelFile.delete();
%>
<%@ 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();
%>
<%@ 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();
}
}
%>
<%@ 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();
%>
<%@ 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();
InputStream inStream=result.getBinaryStream("content");
FileOutputStream fs=new FileOutputStream( "c:/dffdsafd.doc");
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);
}
%>
<%@ 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;
}
stdIn = new BufferedReader(new InputStreamReader(stdURL.openStream()));
stdOut = new PrintWriter(new BufferedWriter(new FileWriter("c:/163.html")));
}
catch (IOException e) {
}
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);
}
}
%>
<%@ page import="java.net.*"%&
]]>
其中的“rws”参CQrw代表d方式Qs代表同步方式Q也是锁。这U方式打开的文Ӟ是独占方式?br />
方式二:(x)用文仉道QF(tun)ileChannelQ的锁功?br />
如:(x)
RandomAccessFile raf = new RandomAccessFile(new File("c:\\test.txt"), "rw");
FileChannel fc = raf.getChannel();
FileLock fl = fc.tryLock();
if (fl.isValid()) {
System.out.println("get the lock!");
但这俩种方式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) {
FileChannel channel = null;
synchronized (fileIn) {
channel = FileChannelImpl.open(fd, true, true, fileIn);
return channel;
}
}
其实Q主要是打开文g的第三个参数控制?jin)对文g的操作模式,如果讄为falseQ就不能锁住文gQ缺省的getChannelҎ(gu)Q就是falseQ因此,不能锁住文g?br />
]]>
热键:(x)
Template
Q?span lang="EN-US" twffan="done">Alt + /
修改处:(x)H口->喜好讑֮->工作?span lang="EN-US" twffan="done">->按键->~辑->内容辅助?span lang="EN-US" twffan="done">
个h?fn)惯Q?span lang="EN-US" twffan="done">Shift+SPACE(I白)?span lang="EN-US" twffan="done">
易说明:(x)~辑E序代码Ӟ?span lang="EN-US" twffan="done">sysout +Template启动键,?span lang="EN-US" twffan="done">
?x)自动出玎ͼ?x)System.out.println(); ?span lang="EN-US" twffan="done">
讑֮Template的格式:(x)H口->喜好讑֮->Java->~辑?span lang="EN-US" twffan="done">->模板?/b>
E序代码自动排版Q?span lang="EN-US" twffan="done">Ctrl+Shift+F
修改处:(x)H口->喜好讑֮->工作?span lang="EN-US" twffan="done">->按键->E序代码->格式?span lang="EN-US" twffan="done">
个h?fn)惯Q?span lang="EN-US" twffan="done">Alt+Z?span lang="EN-US" twffan="done">
自动排版讑֮Q窗?span lang="EN-US" twffan="done">->喜好讑֮->Java->E序代码格式制作E序?span lang="EN-US" twffan="done">
样式面->插?span lang="EN-US" twffan="done">tab(而非I格?span lang="EN-US" twffan="done">)以内~,该选项取消N?span lang="EN-US" twffan="done">
Q下面空格数目填4Q这样在自动~排时会(x)以空?span lang="EN-US" twffan="done">4作羃排?span lang="EN-US" twffan="done">
快速执行程序:(x)Ctrl + F11
个h?fn)惯Q?span lang="EN-US" twffan="done">ALT+X
修改处:(x)H口->喜好讑֮->工作?span lang="EN-US" twffan="done">->按键->执行->启动前一ơ的启动作业?span lang="EN-US" twffan="done">
易说明:(x)W一ơ执行时Q它?x)询问(zhn)执行模式Q?span lang="EN-US" twffan="done">
讄好后Q以后只要按q个热键Q它?yu)׃?x)快速执行?span lang="EN-US" twffan="done">
自动汇入所需要的cdQ?span lang="EN-US" twffan="done">Ctrl+Shift+O
易说明:(x)
假设我们没有ImportMcdӞ当我们在E序里打入:(x)
BufferedReader buf =
new BufferedReader(new InputStreamReader(System.in));
此时Eclipse?x)警C没有汇入cdQ这时我们只要按?span lang="EN-US" twffan="done">Ctrl+Shift+O
Q它?yu)׃?x)自动帮我?span lang="EN-US" twffan="done">Importcd?span lang="EN-US" twffan="done">
查看使用cd的原始码Q?span lang="EN-US" twffan="done">Ctrl+鼠标左键点击
易说明:(x)可以看到(zhn)所使用cd的原始码?span lang="EN-US" twffan="done">
选取的文字批注v来:(x)Ctrl+/
易说明:(x)Debug时很方便?span lang="EN-US" twffan="done">
修改处:(x)H口->喜好讑֮->工作?span lang="EN-US" twffan="done">->按键->E序代码->Ҏ(gu)
视景切换Q?span lang="EN-US" twffan="done">Ctrl+F8
个h?fn)惯Q?span lang="EN-US" twffan="done">Alt+S?span lang="EN-US" twffan="done">
修改处:(x)H口->喜好讑֮->工作?span lang="EN-US" twffan="done">->按键->H口->下一个视景?span lang="EN-US" twffan="done">
易说明:(x)可以方便我们快速切换编辑、除错等视景?span lang="EN-US" twffan="done">
密技:(x)
一?span lang="EN-US" twffan="done">Eclipse可同时切换,英文、繁体、简体显C:(x)
1.首先要先安装完中文化包?span lang="EN-US" twffan="done">
2.在桌面的快捷方式后面加上参数卛_Q?span lang="EN-US" twffan="done">
英文-> -nl "zh_US"
J体-> -nl "zh_TW"
?span lang="EN-US" twffan="done">-> -nl "zh_CN"?span lang="EN-US" twffan="done">
(其它语系以此cL)
像我2.1.2中文化后Q我在我桌面?span lang="EN-US" twffan="done">Eclipse快捷方式加入参数-n1 "zh_US"?span lang="EN-US" twffan="done">
"C:\Program Files\eclipse\eclipse.exe" -n "zh_US"
接口׃(x)变回英文语系噜?span lang="EN-US" twffan="done">
利用EclipseQ在Word~辑文书时可不必程序代码重新编排:(x)
?span lang="EN-US" twffan="done">EclipseE序~辑区的E序代码整个复制下来(Ctrl+C)Q直接脓(chung)(Ctrl+V)?span lang="EN-US" twffan="done">
Word?span lang="EN-US" twffan="done">WordPad上,(zhn)将?x)发现?span lang="EN-US" twffan="done">Word里的E序代码格式Q跟Eclipse
所讑֮的完全一P包括字型、羃排、关键词颜色。我曾试q?span lang="EN-US" twffan="done">JBuilder
?span lang="EN-US" twffan="done">GEL?span lang="EN-US" twffan="done">NetBeans...使用复制贴上Ӟ只有~排格式一P字型、颜
色等都不?x)改变?span lang="EN-US" twffan="done">
外挂:(x)
外挂安装Q将外挂包下载回来后Q将其解压羃后,(zhn)会(x)发现features?span lang="EN-US" twffan="done">
pluginsq?span lang="EN-US" twffan="done">2个数据夹Q将里面的东襉K复制或移动到Eclipse?span lang="EN-US" twffan="done">features
?span lang="EN-US" twffan="done">plugins数据夹内后,重新启动Eclipse卛_?span lang="EN-US" twffan="done">
?span lang="EN-US" twffan="done">Eclipse可以?span lang="EN-US" twffan="done">JBuilderX一样用拖拉方式徏?span lang="EN-US" twffan="done">GUI的外挂:(x)
1.Jigloo SWT/Swing GUI Builder Q?span lang="EN-US" twffan="done">
http://cloudgarden.com/jigloo/index.html
下蝲此版本:(x)Jigloo plugin for Eclipse (using Java 1.4 or 1.5)
安装后即可由档案->新徏->其它->GUI Form选取要徏构的GUIcd?span lang="EN-US" twffan="done">
2.Eclipse Visual Editor ProjectQ?span lang="EN-US" twffan="done">
http://www.eclipse.org/vep/
炚w下?span lang="EN-US" twffan="done">Download PageQ再炚w?span lang="EN-US" twffan="done">Latest Release 0.5.0q入下蝲?span lang="EN-US" twffan="done">
除了(jin)VE-runtime-0.5.0.zip要下载外Q以下这2个也要:(x)
EMF build 1.1.1: (build page) (download zip)
GEF Build 2.1.2: (build page) (download zip)
3.0 M8版本Q请下蝲Q?span lang="EN-US" twffan="done">
EMF build I200403250631
GEF Build I20040330
VE-runtime-1.0M1
安装成功后,便可?span lang="EN-US" twffan="done">File->New->Visual Class开?span lang="EN-US" twffan="done">UI设计?span lang="EN-US" twffan="done">
安装成功后,卛_由新?span lang="EN-US" twffan="done">->Java->AWT?span lang="EN-US" twffan="done">Swing里选择
所要徏构的GUIcd开始进行设计?span lang="EN-US" twffan="done">VE必须配合着对应
版本Q才能正怋用,否则即安装成功Q用上仍会(x)
有问题?span lang="EN-US" twffan="done">
使用Eclipse来开?span lang="EN-US" twffan="done">JSPE序Q?span lang="EN-US" twffan="done">
外挂名称Q?span lang="EN-US" twffan="done">lomboz(下蝲面)
http://forge.objectweb.org/project/showfiles.php?group_id=97
请选择适合自己版本?span lang="EN-US" twffan="done">lomboz下蝲Q?span lang="EN-US" twffan="done">lomboz.212.p1.zip表示2.1.2版,
lomboz.3m7.zip表示M7版本....以此cL?span lang="EN-US" twffan="done">
lomboz安装以及(qing)讄教学Q?span lang="EN-US" twffan="done">
Eclipse
开发JSP-
教学文g
Java
?span lang="EN-US" twffan="done">exe:(x)
实现方式Q?span lang="EN-US" twffan="done">Eclipse搭配JSmooth(免费)?span lang="EN-US" twffan="done">
1.先由Eclipse制作包含Manifest?span lang="EN-US" twffan="done">JAR?span lang="EN-US" twffan="done">
制作教学
2.
使用JSmooth做好的JAR包装?span lang="EN-US" twffan="done">EXE?span lang="EN-US" twffan="done">
JSmooth下蝲面Q?span lang="EN-US" twffan="done">
http://jsmooth.sourceforge.net/index.php
3.
制作完成?span lang="EN-US" twffan="done">exe文gQ可在有装置JRE?span lang="EN-US" twffan="done">Windows上执行?span lang="EN-US" twffan="done">
Eclipse-Java~辑器最佌定:(x)
~辑器字型设定:(x)工作?span lang="EN-US" twffan="done">->字型->Java~辑器文字字型?span lang="EN-US" twffan="done">
(讑֮Courier New -regular 10)
~辑器相兌定:(x)H口->喜好讑֮->Java->~辑?span lang="EN-US" twffan="done">
外观Q显C受强调对U显C的Ҏ(gu)受强调显C现行行?span lang="EN-US" twffan="done">
昄打印边距Q将其勾选,Tab宽度?span lang="EN-US" twffan="done">4Q打印编距字D设80?span lang="EN-US" twffan="done">
E序代码协助Q采预设卛_?span lang="EN-US" twffan="done">
语法Q可讑֮关键词、字W串{等的显C颜艌Ӏ?span lang="EN-US" twffan="done">
附注Q采预设卛_?span lang="EN-US" twffan="done">
输入Q全部字D都N?span lang="EN-US" twffan="done">
动说明Q采预设卛_?span lang="EN-US" twffan="done">
DQ采预设卛_?span lang="EN-US" twffan="done">
使自动排版排出来的效果,最W合Java设计惯例的设定:(x)
自动排版讑֮Q窗?span lang="EN-US" twffan="done">->喜好讑֮->Java->E序代码制作格式?span lang="EN-US" twffan="done">
换行Q全部不N?span lang="EN-US" twffan="done">
分行Q行长度上限设:(x)80?span lang="EN-US" twffan="done">
样式Q只强制{型后插入I白N?span lang="EN-US" twffan="done">
内羃I格数目Q设?span lang="EN-US" twffan="done">4?span lang="EN-US" twffan="done">
Eclipse的教学文Ӟ(x)
Eclipse 3.0
pd热键?-
中英对照解说?(by sungo)
~New~
Window+GCC+CDT
用Eclipse
开发C
、C++ (by sungo)
~New~
其它Q?span lang="EN-US" twffan="done">
扩充Eclipse
的Java
开发工?
中文)
使用Eclipse
开发J2EE
应用E序(
中文)
使用Eclipse
q_q行除错(
中文)
用Eclipse
q行XML
开?
中文)
开发Eclipse
外挂E序(
中文)
国际化?zhn)的Eclipse
外挂E序(
英文)
Swing
~辑器加入Eclipse(
英文)
如何试你的Eclipse plug-in
W合国际?jng)场需?
英文)
Eclipse
的相关网站:(x)
http://eclipse-plugins.2y.net/eclipse/index.jsp
http://www.eclipseplugincentral.com/
Eclipse
相关教学[
体]
出处 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); |
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
JavaU程ȝ
http://java.chinaitlab.com/line/373702.html
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/
|
特别是如果一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>
不要重新分配被锁定对象的对象引用
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.
JUnit是由 Erich Gamma ?Kent Beck ~写的一个回归测试框Ӟregression testing frameworkQ。Junit试是程序员?gu)试Q即所谓白盒测试,因ؓ(f)E序员知道被试的Y件如何(HowQ完成功能和完成什么样QWhatQ的功能。Junit是一套框Ӟl承TestCasec,可以用Junitq行自动试?jin)?/strong>
Cactus是一个基于JUnit框架的简单测试框Ӟ用来单元试服务端Java代码。Cactus框架的主要目标是能够单元试服务端的使用Servlet对象的JavaҎ(gu)如HttpServletRequest,HttpServletResponse,HttpSession{?/strong>
Junitperf实际是junit的一个decoratorQ通过~写用于junitperf的单元测试,我们也可使测试过E自动化?/strong>
DbUnit是ؓ(f)数据库驱动的目提供的一个对JUnit 的扩展,除了(jin)提供一些常用功能,它可以将你的数据库置于一个测试轮回之间的状态?
Mockrunner用在J2EE环境中进行应用程序的单元试。它不仅支持Struts actions, servletsQ过滤器和标{q包括一个JDBC和一个JMS试框架Q可以用于测试基于EJB的应用程序?/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对象试框架?
JFCUnit使得你能够ؓ(f)Java偏移应用E序~写试例子。它Z用代码打开的窗口上获得句柄提供?jin)支持;为在一个部件层ơ定位部件提供支持;为在部g中发起事Ӟ例如按一个按钮)(j)以及(qing)以线E安全方式处理部件测试提供支持?/strong>
JTestCase 使用XML文g来组l多试案例数据Q声明条Ӟ操作和期望的l果Q,提供?jin)一套易于用的Ҏ(gu)来检索XML中的试案例Q按照数据文件的定义来声明结果?/strong>
JTR (Java Test Runner)是一个开源的Z反{控制(IOC)的J2EE试框架。它允许你构建复杂的J2EE试套g(Test Suites)q连到应用服务器执行试,可以包括多个试实例。JTR的licensed是GPL协议?/strong>
Marathon是一个针对用Java/Swing开发GUI应用E序的测试框Ӟ它由recorder, runner ?editorl成Q测试脚本是python代码。Marathon的焦Ҏ(gu)攑֜最l用L(fng)试上?/strong>
TestNG是根据JUnit ?NUnit思想而构建的一个测试框Ӟ但是TestNG增加?jin)许多新的功能得它变得更加强大与容易用比如?x)
*支持JSR 175注释QJDK 1.4利用JavaDoc注释同样也支持)(j)
*灉|的Test配置
*支持默认的runtime和logging JDK功能
*强大的执行模型(不再TestSuiteQ?br />*支持独立的测试方法?/strong>
MockCreator可以为给定的interface或class生成模拟对象QMock objectQ的源码?/strong>
jMock利用mock objects思想来对Java codeq行试。jMockh以下特点:Ҏ(gu)扩展Q让你快速简单地定义mock objects,因此不必打破E序间的兌Q让你定义灵zȝ越对象之间交互作用而带来测试局限,减少你测试地脆弱性?/strong>
EasyMock为Mock Objects提供接口q在JUnit试中利用Java的proxy设计模式生成它们的实例。EasyMock最适合于测试驱动开发?/strong>
XMLUnit不仅有Java版本的还?Net版本的。Java开发的XMLUnit提供?jin)两个JUnit 扩展cXMLAssert和XMLTestCase,和一l支持的cR这些类可以用来比较两张XML之间的不同之处,展示XML利用XSLT?校验XML,求得XPath表达式在XML中的?遍历XML中的某一节点利DOM展开,
Jameleon一个自动化试工具。它被用来测试各U各L(fng)应用E序Q所以它被设计成插g模式。ؓ(f)?jin)整个试q程变得单Jameleon提供?jin)一个GUI,因此Jameleon实现?jin)一个Swing 插g?/strong>
【Java开?nbsp;Java试工具?/FONT>
JUnit是由 Erich Gamma ?Kent Beck ~写的一个回归测试框Ӟregression testing frameworkQ。Junit试是程序员?gu)试Q即所谓白盒测试,因ؓ(f)E序员知道被试的Y件如何(HowQ完成功能和完成什么样QWhatQ的功能。Junit是一套框Ӟl承TestCasec,可以用Junitq行自动试?jin)?/STRONG>
Cactus是一个基于JUnit框架的简单测试框Ӟ用来单元试服务端Java代码。Cactus框架的主要目标是能够单元试服务端的使用Servlet对象的JavaҎ(gu)如HttpServletRequest,HttpServletResponse,HttpSession{?/STRONG>
Junitperf实际是junit的一个decoratorQ通过~写用于junitperf的单元测试,我们也可使测试过E自动化?/STRONG>
DbUnit是ؓ(f)数据库驱动的目提供的一个对JUnit 的扩展,除了(jin)提供一些常用功能,它可以将你的数据库置于一个测试轮回之间的状态?
Mockrunner用在J2EE环境中进行应用程序的单元试。它不仅支持Struts actions, servletsQ过滤器和标{q包括一个JDBC和一个JMS试框架Q可以用于测试基于EJB的应用程序?/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对象试框架?
JFCUnit使得你能够ؓ(f)Java偏移应用E序~写试例子。它Z用代码打开的窗口上获得句柄提供?jin)支持;为在一个部件层ơ定位部件提供支持;为在部g中发起事Ӟ例如按一个按钮)(j)以及(qing)以线E安全方式处理部件测试提供支持?/STRONG>
JTestCase 使用XML文g来组l多试案例数据Q声明条Ӟ操作和期望的l果Q,提供?jin)一套易于用的Ҏ(gu)来检索XML中的试案例Q按照数据文件的定义来声明结果?/STRONG>
JTR (Java Test Runner)是一个开源的Z反{控制(IOC)的J2EE试框架。它允许你构建复杂的J2EE试套g(Test Suites)q连到应用服务器执行试,可以包括多个试实例。JTR的licensed是GPL协议?/STRONG>
Marathon是一个针对用Java/Swing开发GUI应用E序的测试框Ӟ它由recorder, runner ?editorl成Q测试脚本是python代码。Marathon的焦Ҏ(gu)攑֜最l用L(fng)试上?/STRONG>
TestNG是根据JUnit ?NUnit思想而构建的一个测试框Ӟ但是TestNG增加?jin)许多新的功能得它变得更加强大与容易用比如?x)
*支持JSR 175注释QJDK 1.4利用JavaDoc注释同样也支持)(j)
*灉|的Test配置
*支持默认的runtime和logging JDK功能
*强大的执行模型(不再TestSuiteQ?BR>*支持独立的测试方法?/STRONG>
MockCreator可以为给定的interface或class生成模拟对象QMock objectQ的源码?/STRONG>
jMock利用mock objects思想来对Java codeq行试。jMockh以下特点:Ҏ(gu)扩展Q让你快速简单地定义mock objects,因此不必打破E序间的兌Q让你定义灵zȝ越对象之间交互作用而带来测试局限,减少你测试地脆弱性?/STRONG>
EasyMock为Mock Objects提供接口q在JUnit试中利用Java的proxy设计模式生成它们的实例。EasyMock最适合于测试驱动开发?/STRONG>
XMLUnit不仅有Java版本的还?Net版本的。Java开发的XMLUnit提供?jin)两个JUnit 扩展cXMLAssert和XMLTestCase,和一l支持的cR这些类可以用来比较两张XML之间的不同之处,展示XML利用XSLT?校验XML,求得XPath表达式在XML中的?遍历XML中的某一节点利DOM展开,
Jameleon一个自动化试工具。它被用来测试各U各L(fng)应用E序Q所以它被设计成插g模式。ؓ(f)?jin)整个试q程变得单Jameleon提供?jin)一个GUI,因此Jameleon实现?jin)一个Swing 插g?/STRONG>
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=568616
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());
}
}
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;
}
}
}
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) |
模仿对象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)正确的查询?
|
|
|
|
|
|
|
|
|
(如今的程序领域,大家都在_(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序员的朋友可以对他们的基本知识做以回顾.
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>
请先看下面这D늨序:(x)
看过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 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)
调用一个静(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>
l果如下Q?/P> v1.c=0 v2.c=0 由此可以证明它们׃n一块存储区。static变量有点cM于C中的全局变量的概c(din)值得探讨的是?rn)态变量的初始化问题。我们修改上面的E序Q?/P>
v1.c=0 v2.c=0 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)
输出l果?x)如你所料:(x) InnerCls 和普通类一栗内部类的其它用法请参阅Think in Java中的相关章节Q此处不作详解?BR> |
阅读全文() | 回复(0) | 引用通告() | ~辑 |
|
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 |
ScriptAlias /php/ "c:/php/" AddType application/x-httpd-php .php Action application/x-httpd-php "/php/php.exe" |
; 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 |
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> |