??xml version="1.0" encoding="utf-8" standalone="yes"?> 1 {call procedure-name} 作ؓ(f)实例Q在 SQL Server 2005 AdventureWorks CZ数据库中创徏以下存储q程Q?/p>
CREATE PROCEDURE GetContactFormalNames AS BEGIN SELECT TOP 10 Title + ' ' + FirstName + ' ' + LastName AS FormalName FROM Person.Contact END 此存储过E返回单个结果集Q其中包含一列数??Person.Contact 表中前十个联pMh的称呹{名U和姓氏l成)?/p>
在下面的实例中,向此函C?AdventureWorks CZtb数据库的打开q接Q然后?executeQuery Ҏ(gu)调用 GetContactFormalNames 存储q程?/p>
public static void executeSprocNoParams(Connection con) …{ try …{ Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("{call dbo.GetContactFormalNames}"); while (rs.next()) …{ System.out.println(rs.getString("FormalName")); } rs.close(); stmt.close(); } catch (Exception e) …{ e.printStackTrace(); } } 2使用带有输入参数的存储过E?/p>
使用 JDBC 驱动E序调用带参数的存储q程Ӟ必须l合 SQLServerConnection cȝ prepareCall Ҏ(gu)使用 call SQL 转义序列。带?IN 参数?call 转义序列的语法如下所C:(x) {call procedure-name[([parameter][,[parameter]]…)]}http://jie.baijiale.94ibc.com 构?call 转义序列Ӟ请??(问号)字符来指?IN 参数。此字符充当要传递给该存储过E的参数值的占位W。可以?SQLServerPreparedStatement cȝ setter Ҏ(gu)之一为参数指定倹{可使用?setter Ҏ(gu)?IN 参数的数据类型决定?/p>
?setter Ҏ(gu)传递值时Q不仅需要指定要在参C使用的实际|q必L定参数在存储q程中的序数位置。例如,如果存储q程包含单个 IN 参数Q则其序数gؓ(f) 1.如果存储q程包含两个参数Q则W一个序数gؓ(f) 1,W二个序数gؓ(f) 2. 作ؓ(f)如何调用包含 IN 参数的存储过E的实例Q?SQL Server 2005 AdventureWorks CZ数据库中?uspGetEmployeeManagers 存储q程。此存储q程接受名ؓ(f) EmployeeID 的单个输入参?/p> 2. 不要把简单事情复杂化(Do not complicate things)?– 我曾l这么做q,我相信你也一栗开发者都們于采用复杂方式解决简单问题。我们在一个只?个用L(fng)pȝ中引入EJB,Z个ƈ不需要框架的应用实现一套框Ӟ采用属性文件、采用面?a style="color: #000000" >tb对象解决Ҏ(gu)、用线E,而这些根本用不着。ؓ(f)什么会(x)q么做?一些h可能不知道有更好的解x案,但另一些h可能故意q样做来学习(fn)新知识,或仅仅是因ؓ(f)有趣。对那些不知道更好解x案的人,要多听有l验E序员的。对于那些纯_出于个人目的而将设计复杂化的人,我徏议你要更加专业一炏V?br /> 3. 不要"编?(No hard coding please)?– ׃旉紧迫Q开发者L?x)忘记或故意忽略q一条。然而另一U可能是Q遵循这条戒律,我们׃?x)陷?旉紧迫"的困境。定义一个static final 变量Q增加一行代码,又能花多长时间呢Q?/p>
4. Z码添加注?Add comments to your code)?– 每个人都知道q一点,但不是每个h都会(x)q么做。你有多次"忘记"d注释了?实Q注释不?x)?f)你的E序增加M函数功能。但是,有多次Q看?周前写的代码Q你都记不v它是q什么的Q你很幸q,那些未注释的代码是你自己写的Q你脑v中还?x)有D存的印象。非怸q,大多时候,代码是别人写的,q且那个人很可能已经d公司了。有句谚语说的好Q?有来有往Q互惠互?,因此E序员应该体谅彼?q有你自?Q给你的代码加上注释?/p>
首先下蝲好:(x)Java Excel ApiQ这个文件我已经?JAVA+Excel+API详细教程。pdf一q压~上传了Q感兴趣的朋友可以下? 我这里用的开发^台是EclipseQ这里我把操作简单说一下:(x) 1Q?建,立java目Q在q个目在徏立一个新的文件夹lib; 2Q?jxl.jarQ即Java Excel ApQ复制到l(f)ib 3Q然后右键点击这个java目Q?a style="color: #000000" >tb选择Propertieshttp://jie.baijiale.ibc198.com 4Q在左侧列表里选中Java Build Path Q右侧选中Libraries 5Q点击Add JARs 6Q?然后去选择q个目中lib文g夹中的jxl.jarQ点ȝ?/p>
成功后,目中会(x)多一个文件夹为:(x)Referenced Libraries 准备工作完成后,可以去操作excel了, 核心概念 Quartz核心的概念:(x)schedulerd调度、Jobd、Trigger触发器、JobDetaildl节 JobdQ其实Job是接口,其中只有一个executeҎ(gu)Q?/p>
package org.quartz; public abstract interface Job { public abstract void execute(JobExecutionContext paramJobExecutionContext) throws JobExecutionException; } 我们开发者只要实现此接口Q实现executeҎ(gu)卛_。把我们惛_的事情,在execute中执行即可?/p>
JobDetailQQ务细节,Quartz执行JobӞ需要新ZJob实例Q但是不能直接操作Jobc,所以通过JobDetail来获取Job的名U、描qC息?/p>
Trigger触发器:(x)执行d的规?比如每天Q每时{?/p>
一般情况用SimpleTriggerQ和CronTriggerQ这个触发器实现了Trigger接口?/p>
对于复杂的时间表辑ּ来说Q比如每个月15日上午几点几分,使用CronTrigger 对于单的旉来说Q比如每天执行几ơ,使用SimpleTrigger schedulerd调度Q是最核心的概念,需要把JobDetail和Trigger注册到scheduler中,才可以执行?/p>
注意Q?/p>
不同的版本的jar包,具体的操作不太相同,但是tbw思\是相同的;比如1.8.6jar包中QJobDetail是个c,直接通过构造方法与Jobcd联。SimpleTrigger和CornTrigger是类;?.0.2jar包中QJobDetail是个接口QSimpleTrigger和CornTrigger是接?/p>
不同版本试Q?/p>
1.8.6jar包:(x) [html] package com.test; import java.util.Date; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; /** * 需要执行的d * @author lhy * */ public class MyJob implements Job { @Override //把要执行的操作,写在executeҎ(gu)?/p>
public void execute(JobExecutionContext arg0) throws JobExecutionException { System.out.println("试Quartz"+new Date()); } } package com.test; import java.util.Date; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; /** * 需要执行的d * @author lhy * */ public class MyJob implements Job { @Override //把要执行的操作,写在executeҎ(gu)?/p>
public void execute(JobExecutionContext arg0) throws JobExecutionException { System.out.println("试Quartz"+new Date()); } } 使用SimpleTrigger触发?/p>
[html] package com.test; import java.util.Date; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; import org.quartz.SimpleTrigger; import org.quartz.impl.StdSchedulerFactory; /** * 调用d的类 * @author lhy * */ public class SchedulerTest { public static void main(String[] args) { //通过schedulerFactory获取一个调度器 SchedulerFactory schedulerfactory=new StdSchedulerFactory(); Scheduler scheduler=null; try{ // 通过schedulerFactory获取一个调度器 scheduler=schedulerfactory.getScheduler(); // 创徏jobDetail实例Q绑定Job实现c?/p>
// 指明job的名Uͼ所在组的名Uͼ以及(qing)l定jobc?/p>
JobDetail jobDetail=new JobDetail("job1", "jgroup1", MyJob.class); // 定义调度触发规则Q比如每1U运行一ơ,p??/p>
SimpleTrigger simpleTrigger=new SimpleTrigger("simpleTrigger","triggerGroup"); // 马上启动 simpleTrigger.setStartTime(new Date()); // 间隔旉 simpleTrigger.setRepeatInterval(1000); // q行ơ数 simpleTrigger.setRepeatCount(8); // 把作业和触发器注册到d调度?/p>
scheduler.scheduleJob(jobDetail, simpleTrigger); // 启动调度 scheduler.start(); }catch(SchedulerException e){ e.printStackTrace(); } } } package com.test; import java.util.Date; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; import org.quartz.SimpleTrigger; import org.quartz.impl.StdSchedulerFactory; /** * 调用d的类 * @author lhy * */ public class SchedulerTest { public static void main(String[] args) { //通过schedulerFactory获取一个调度器 SchedulerFactory schedulerfactory=new StdSchedulerFactory(); Scheduler scheduler=null; try{ // 通过schedulerFactory获取一个调度器 scheduler=schedulerfactory.getScheduler(); // 创徏jobDetail实例Q绑定Job实现c?/p>
// 指明job的名Uͼ所在组的名Uͼ以及(qing)l定jobc?br /> JobDetail jobDetail=new JobDetail("job1", "jgroup1", MyJob.class); // 定义调度触发规则Q比如每1U运行一ơ,p??/p>
SimpleTrigger simpleTrigger=new SimpleTrigger("simpleTrigger","triggerGroup"); // 马上启动 simpleTrigger.setStartTime(new Date()); // 间隔旉 simpleTrigger.setRepeatInterval(1000); // q行ơ数 simpleTrigger.setRepeatCount(8); // 把作业和触发器注册到d调度?/p>
scheduler.scheduleJob(jobDetail, simpleTrigger); // 启动调度 scheduler.start(); }catch(SchedulerException e){ e.printStackTrace(); } } } 若用CornTrigger触发器:(x) [html] package com.test; import java.util.Date; import org.quartz.CronTrigger; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; import org.quartz.SimpleTrigger; import org.quartz.impl.StdSchedulerFactory; /** * 调用d的类 * @author lhy * */ public class CronTriggerTest { public static void main(String[] args) { //通过schedulerFactory获取一个调度器 SchedulerFactory schedulerfactory=new StdSchedulerFactory(); Scheduler scheduler=null; try{ // 通过schedulerFactory获取一个调度器 scheduler=schedulerfactory.getScheduler(); // 创徏jobDetail实例Q绑定Job实现c?/p>
// 指明job的名Uͼ所在组的名Uͼ以及(qing)l定jobc?/p>
JobDetail jobDetail=new JobDetail("job1", "jgroup1", MyJob.class); // 定义调度触发规则Q每天上?0Q?5执行 CronTrigger cornTrigger=new CronTrigger("cronTrigger","triggerGroup"); // 执行规则表达?/p>
cornTrigger.setCronExpression("0 15 10 * * ? *"); // 把作业和触发器注册到d调度?/p>
scheduler.scheduleJob(jobDetail, cornTrigger); // 启动调度 scheduler.start(); }catch(Exception e){ e.printStackTrace(); } } } package com.test; import java.util.Date; import org.quartz.CronTrigger; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; import org.quartz.SimpleTrigger; import org.quartz.impl.StdSchedulerFactory; /** * 调用d的类 * @author lhy * */ public class CronTriggerTest { public static void main(String[] args) { //通过schedulerFactory获取一个调度器 SchedulerFactory schedulerfactory=new StdSchedulerFactory(); Scheduler scheduler=null; try{ // 通过schedulerFactory获取一个调度器 scheduler=schedulerfactory.getScheduler(); // 创徏jobDetail实例Q绑定Job实现c?/p>
// 指明job的名Uͼ所在组的名Uͼ以及(qing)l定jobc?/p>
JobDetail jobDetail=new JobDetail("job1", "jgroup1", MyJob.class); // 定义调度触发规则Q每天上?0Q?5执行 CronTrigger cornTrigger=new CronTrigger("cronTrigger","triggerGroup"); // 执行规则表达?/p>
cornTrigger.setCronExpression("0 15 10 * * ? *"); // 把作业和触发器注册到d调度?/p>
scheduler.scheduleJob(jobDetail, cornTrigger); // 启动调度 scheduler.start(); }catch(Exception e){ e.printStackTrace(); } } } 对于2.0.2jar包如下:(x) 其中的jobcM变,主要是调度类如下Q?/p>
[html] package com.test; import java.util.Date; import org.quartz.CronScheduleBuilder; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; import org.quartz.SimpleScheduleBuilder; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; /** * 调用d的类 * @author lhy * */ public class SchedulerTest { public static void main(String[] args) { //通过schedulerFactory获取一个调度器 SchedulerFactory schedulerfactory=new StdSchedulerFactory(); Scheduler scheduler=null; try{ // 通过schedulerFactory获取一个调度器 scheduler=schedulerfactory.getScheduler(); // 创徏jobDetail实例Q绑定Job实现c?/p>
// 指明job的名Uͼ所在组的名Uͼ以及(qing)l定jobc?/p>
JobDetail job=JobBuilder.newJob(MyJob.class).withIdentity("job1", "jgroup1").build(); // 定义调度触发规则 // 使用simpleTrigger规则 // Trigger trigger=TriggerBuilder.newTrigger().withIdentity("simpleTrigger", "triggerGroup") // .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1).withRepeatCount(8)) // .startNow().build(); // 使用cornTrigger规则 每天10?2?/p>
Trigger trigger=TriggerBuilder.newTrigger().withIdentity("simpleTrigger", "triggerGroup") .withSchedule(CronScheduleBuilder.cronSchedule("0 42 10 * * ? *")) .startNow().build(); // 把作业和触发器注册到d调度?/p>
scheduler.scheduleJob(job, trigger); // 启动调度 scheduler.start(); }catch(Exception e){ e.printStackTrace(); } } } package com.test; import java.util.Date; import org.quartz.CronScheduleBuilder; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; import org.quartz.SimpleScheduleBuilder; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; /** * 调用d的类 * @author lhy * */ public class SchedulerTest { public static void main(String[] args) { //通过schedulerFactory获取一个调度器 SchedulerFactory schedulerfactory=new StdSchedulerFactory(); Scheduler scheduler=null; try{ // 通过schedulerFactory获取一个调度器 scheduler=schedulerfactory.getScheduler(); // 创徏jobDetail实例Q绑定Job实现c?/p>
// 指明job的名Uͼ所在组的名Uͼ以及(qing)l定jobc?/p>
JobDetail job=JobBuilder.newJob(MyJob.class).withIdentity("job1", "jgroup1").build(); // 定义调度触发规则 // 使用simpleTrigger规则 // Trigger trigger=TriggerBuilder.newTrigger().withIdentity("simpleTrigger", "triggerGroup") // .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1).withRepeatCount(8)) // .startNow().build(); // 使用cornTrigger规则 每天10?2?/p>
Trigger trigger=TriggerBuilder.newTrigger().withIdentity("simpleTrigger", "triggerGroup") .withSchedule(CronScheduleBuilder.cronSchedule("0 42 10 * * ? *")) .startNow().build(); // 把作业和触发器注册到d调度?/p>
scheduler.scheduleJob(job, trigger); // 启动调度 scheduler.start(); }catch(Exception e){ e.printStackTrace(); } } } 上述demo下蝲Q?.8版本demo下蝲 2.0版本demo下蝲 对于CornExpress讲解如下Q?/p>
字段 允许?允许的特D字W?/p>
U?0-59 , - * / ?0-59 , - * / 时 0-23 , - * / 日期 1-31 , - * ? / L W C 月䆾 1-12 或?JAN-DEC , - * / 星期 1-7 或?SUN-SAT , - * ? / L C # q?可? 留空, 1970-2099 , - * / 表达?意义 "0 0 12 * * ?" 每天中午12点触?/p>
"0 15 10 ? * *" 每天上午10:15触发 "0 15 10 * * ?" 每天上午10:15触发 "0 15 10 * * ? *" 每天上午10:15触发 "0 15 10 * * ? 2005" 2005q的每天上午10:15触发 "0 * 14 * * ?" 在每天下?点到下午2:59期间的每1分钟触发 "0 0/5 14 * * ?" 在每天下?点到下午2:55期间的每5分钟触发 "0 0/5 14,18 * * ?" 在每天下?点到2:55期间和下?点到6:55期间的每5分钟触发 "0 0-5 14 * * ?" 在每天下?点到下午2:05期间的每1分钟触发 "0 10,44 14 ? 3 WED" 每年三月的星期三的下?:10?:44触发 "0 15 10 ? * MON-FRI" 周一臛_五的上午10:15触发 "0 15 10 15 * ?" 每月15日上?0:15触发 "0 15 10 L * ?" 每月最后一日的上午10:15触发 "0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发 "0 15 10 ? * 6L 2002-2005" 2002q至2005q的每月的最后一个星期五上午10:15触发 "0 15 10 ? * 6#3" 每月的第三个星期五上?0:15触发 Ҏ(gu)字符 意义 * 表示所有? ? 表示未说明的|即不兛_它ؓ(f)何? - 表示一个指定的范围; , 表示附加一个可能? / W号前表C开始时_(d)W号后表C每ơ递增的? L("last") ("last") "L" 用在day-of-month字段意思是 "q个月最后一?;用在 day-of-week字段, 它简单意思是 "7" or "SAT"?如果在day-of-week字段里和数字联合使用Q它的意思就?"q个月的最后一个星期几" – 例如Q?"6L" means "q个月的最后一个星期五". 当我们用“L”Ӟ不指明一个列表值或者范围是很重要的Q不然的话,我们?x)得C些意想不到的l果?/p>
W("weekday") 只能用在day-of-month字段。用来描叙最接近指定天的工作?周一到周?。例如:(x)在day-of-month字段?#8220;15W”?#8220;最接近q个月第15天的工作?#8221;Q即如果q个月第15天是周六Q那么触发器会(x)在这个月W?4天即周五触发;如果q个月第15天是周日Q那么触发器会(x)在这个月W?6天即周一触发;如果q个月第15天是周二Q那么就?strong>tbw触发器这天触发。注意一点:(x)q个用法只会(x)在当前月计算|不会(x)过当前月?#8220;W”字符仅能在day-of-month指明一天,不能是一个范围或列表。也可以?#8220;LW”来指定这个月的最后一个工作日?/p>
# 只能用在day-of-week字段。用来指定这个月的第几个周几。例Q在day-of-week字段?6#3"指这个月W?个周?6指周五,3指第3?。如果指定的日期不存在,触发器就不会(x)触发?/p>
C 指和calendar联系后计过的倹{例Q在day-of-month 字段?#8220;5C”指在q个月第5天或之后包括calendar的第一?在day-of-week字段?#8220;1C”指在q周日或之后包括calendar的第一?/p> 序列化的实现Q将需要被序列化的cd现Serializable接口Q然后用一个输出流(如:(x)FileOutputStream)来构造一个ObjectOutputStream(对象?对象Q接着Q用ObjectOutputStream对象的writeObject(Object obj)Ҏ(gu)可以将参数为obj的对象写?即保存其状?Q要恢复的话则用输入?br /> 写对象和d象的时候一定要使用序列化:(x) import java.io.*; class Product implements Serializable { private static final long serialVersionUID = 1L; private float price; private float tax; public Product(float price) { this.price = price; tax = (float)(price*0.20); } public String toString() { return "price:"+price+",tax:"+tax; } } public class CmdDemo { public static void main(String[] strtb) throws Exception { Product p1 = new Product(100); ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream ("d:\product.txt")); os.writeObject(p1); os.close(); ObjectInputStream is = new ObjectInputStream(new FileInputStream ("d:\product.txt")); Product p2 = (Product) is.readObject(); System.out.println(p2.toString()); } }
]]>
]]>
]]>
0. 声明一个数l(Declare an arrayQ?
String[] aArray = new String[5];
String[] bArray = {"a","b","c", "d", "e"};
String[] cArray = new String[]{"a","b","c","d","e"};
1. 在Java中输Z个数l(Print an array in JavaQ?br />
int[] intArray = { 1, 2, 3, 4, 5 };
String intArrayString = Arrays.toString(intArray);
// print directly will print reference value
System.out.println(intArray);
// [I@7150bd4d
System.out.println(intArrayString);
// [1, 2, 3, 4, 5]
2. 从数l中创徏数组列表QCreate an ArrayList from an arrayQ?br />
String[] stringArray = { "a", "b", "c", "d", "e" };
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(stringArray));
System.out.println(arrayList);
// [a, b, c, d, e]
3. (g)?strong>爱淘?/strong>数组中是否包含特定|Check if an array contains a certain valueQ?br />
String[] stringArray = { "a", "b", "c", "d", "e" };
boolean b = Arrays.asList(stringArray).contains("a");
System.out.println(b);
// true
4. q接两个数组Q?Concatenate two arraysQ?br />
int[] intArray = { 1, 2, 3, 4, 5 };
int[] intArray2 = { 6, 7, 8, 9, 10 };
// Apache Commons Lang library
int[] combinedIntArray = ArrayUtils.addAll(intArray, intArray2);
5. 声明一个数l内链(Declare an array inline Q?br />
method(new String[]{"a", "b", "c", "d", "e"});
6. 数l元素加入到一个独立的字符串中QJoins the elements of the provided array into a single StringQ?/p>
// containing the provided list of elements
// Apache common lang
String j = StringUtils.join(new String[] { "a", "b", "c" }, ", ");
System.out.println(j);
// a, b, c
7. 数l列表{换成一个数l?QCovnert an ArrayList to an arrayQ?
String[] stringArray = { "a", "b", "c", "d", "e" };
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(stringArray));
String[] stringArr = new String[arrayList.size()];
arrayList.toArray(stringArr);
for (String s : stringArr)
System.out.println(s);
8. 数l{换成一个集合(Convert an array to a setQ?
Set<String> set = new HashSet<String>(Arrays.asList(stringArray));
System.out.println(set);
//[d, e, b, c, a]
9. 反向数组QReverse an arrayQ?br />
int[] intArray = { 1, 2, 3, 4, 5 };
ArrayUtils.reverse(intArray);
System.out.println(Arrays.toString(intArray));
//[5, 4, 3, 2, 1]
10. 删除数组元素QRemove element of an arrayQ?br />
int[] intArray = { 1, 2, 3, 4, 5 };
int[] removed = ArrayUtils.removeElement(intArray, 3);
//create a new array
System.out.println(Arrays.toString(removed));
One more – convert int to byte array
byte[] bytes = ByteBuffer.allocate(4).putInt(8).array();
for (byte t : bytes) {
System.out.format("0x%x ", t);
}
DynamicProxy.java 代理对象
[java]
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicProxy implements InvocationHandler {
private Object object;
public DynamicProxy(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
System.out.println("Before Invoke ! method : " + method);
//我们可以再代理方法调用前后添加功?br /> Object result = method.invoke(object, args);
System.out.println("object : " + object + " result : " + result + " args : " + args);
System.out.println("After Invoke !");
return result;
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicProxy implements InvocationHandler {
private Object object;
public DynamicProxy(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
System.out.println("Before Invoke ! method : " + method);
//我们可以再代理方法调用前后添加功?br /> Object result = method.invoke(object, args);
System.out.println("object : " + object + " result : " + result + " args : " + args);
System.out.println("After Invoke !");
return result;
}
}
Client.java 试
[java]
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Client {
public static void main(String[] args) throws Exception {
//创徏目标对象Q也是被代理对?br /> RealSubject realSubject = new RealSubject();
//目标对象交l代?br /> InvocationHandler handler = new DynamicProxy(realSubject);
// Class proxyClass = Proxy.getProxyClass(Subject.class.getClassLoader()
// , new Class[]{Subject.class});
// Subject subject = (Subject)proxyClass.getConstructor(new Class[]{InvocationHandler.class})
// .newInstance(new Object[]{handler});
//q回代理对象Q相当于上面两句
Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
handler);
//叫代理对象去doSomething()Q其实在代理对象中的doSomething()中还是会(x)
//用handler来调用invoke(proxy, method, args) 参数proxy用者subject(this)Q?br /> //method为doSomething()Q?strong>tb参数为方法要传入的参敎ͼq里没有
subject.doSomething();
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Client {
public static void main(String[] args) throws Exception {
//创徏目标对象Q也是被代理对?br /> RealSubject realSubject = new RealSubject();
//目标对象交l代?br /> InvocationHandler handler = new DynamicProxy(realSubject);
// Class proxyClass = Proxy.getProxyClass(Subject.class.getClassLoader()
// , new Class[]{Subject.class});
// Subject subject = (Subject)proxyClass.getConstructor(new Class[]{InvocationHandler.class})
// .newInstance(new Object[]{handler});
//q回代理对象Q相当于上面两句
Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
handler);
//叫代理对象去doSomething()Q其实在代理对象中的doSomething()中还是会(x)
//用handler来调用invoke(proxy, method, args) 参数proxy用者subject(this)Q?br /> //method为doSomething()Q参Cؓ(f)Ҏ(gu)要传入的参数Q这里没?br /> subject.doSomething();
}
}
打印l果Q?br /> Before Invoke ! method : public abstract void Subject.doSomething()
RealSubject.doSomething
object : RealSubject@ec6b00 result : null args : null
After Invoke !
注意Q?br /> Java动态代理涉?qing)到的两个类Q?br /> InvocationHandlerQ该接口中仅定义了一个Object : invoke(Object proxy, Method method, Object[] args);参数proxy指代理类Qmethod表示被代理的Ҏ(gu)Qargs为method中的参数数组Q返回值ObjectZ理实例的Ҏ(gu)调用q回的倹{这个抽象方法在代理cM动态实现?br /> ProxyQ所有动态代理类的父c,提供用于创徏动态代理类和实例的静态方法?/p>
(23) 为避免编E时遇到ȝ(ch)Q请保证在自q路径指到的Q何地方,每个名字都仅对应一个类。否则,~译器可能先扑ֈ同名的另一个类Qƈ报告出错?息。若怀疑自qCc\径问题,误试在c\径的每一个v点,搜烦(ch)一下同名的.class文g?br /> (24) 在Java 1.1 AWT 中用事?#8220;适配?#8221;Ӟ特别Ҏ(gu)到一个陷阱。若覆盖了某个适配器方法,同时拼写Ҏ(gu)没有特别讲究Q最后的l果是新添加一个方法,而不是覆盖现成方法。然而,׃q样做是完全合法的,所以不?x)从~译器或q行期系l获得Q何出错提C?#8212;—只不q代码的工作变得不正常了?br /> (25) 用合理的设计Ҏ(gu)消除“伪功?#8221;。也是_(d)假若只需要创建类的一个对象,׃要提前限制自׃用应用程序,q加上一?#8220;只生成其中一?” 注释。请考虑其装成一?#8220;独生?#8221;的Ş式。若在主E序里有大量散ؕ的代码,用于创徏自己的对象,误(g)虑采纳一U创造性的Ҏ(gu)Q将些代码封装v来?br /> (26) 警惕“分析瘫痪”。请CQ无论如何都要提前了解整个项目的状况Q再去考察其中的细节。由于把握了全局Q可快速认识自己未知的一些因素,?止在考察l节的时候陷?#8220;死逻辑”中?br /> (27) 警惕“q早优化”。首先让它运行v来,再考虑变得更快——但只有在自己必须q样做、而且l证实在某部分代码中的确存在一个性能瓉的时候, 才应q行优化。除非用专门的工具分析瓶颈,否则很有可能是在费自己的时间。性能提升的隐含代h自己的代码变得难于理解,而且难于l护?br /> (28) 误住,阅读代码的时间比写代码的旉多得多。思\清晰的设计可获得易于理解的程序,但注释、细致的解释以及(qing)一些示例往往h不可估量的h(hun) 倹{无论对你自己,q是对后来的人,它们都是相当重要的。如Ҏ(gu)仍有怀疑,那么误惌p图从联机Java文档里找出有用信息时到的挫折,q样或许?你说服?br /> (29) 如认己已q行了良好的分析、设计或者实施,那么L(fng)微更换一下思维角度。试试邀(g)请一些外来h?#8212;—q不一定是专家Q但可以是来自本公司其他部门的h。请他们用完全新鲜的眼光考察你的工作Q看看是否能扑և你一度熟视无睹的问题。采取这U方式,往往能在最适合修改的阶D|Z些关键性的问题Q避免品发行后再解决问题而造成的金钱及(qing)_֊斚w的损失?br /> (30) 良好的设计能带来最大的回报。简a之,对于一个特定的问题Q通常?x)花较长的时间才能找CU最恰当的解x案。但一旦找C正确的方法,以后的工作就L多了Q再也不用经历数时、数天或者数月的痛苦挣扎。我们的努力工作?x)带来最大的回报(甚至无可估量)。而且׃自己倾注了大量心血Q最l获得一个出色的设计Ҏ(gu)Q成功的快感也是令h心动的。坚持抵制草草完工的诱惑——那样做往往得不偿失
蒙特卡罗?Monte Carlo method)是以概率和统计的理论、方法ؓ(f)基础的一U计方?所求解的问题同一定的概率模型相联p?用电(sh)子计机实现l计模拟或抽?以获得问题的q似?故又U统计模拟法或统计试验法. --癑ֺ癄
蒙特卡罗求算法求π
W一?br /> L方Ş和内切圆
W二?br /> 变换表达?br /> 正方形面UAs=(2R)^2
圆的面积Ac=πR^2
Ac/As=(2R)^2/πR^2
π=4As/Ac
令P=As/Sc,?#960;=4P
W三?br /> 重复Nơ实验求q_?br /> 在正方Ş区域内随机生成一个点A,若A落在圆区域内,M++
P=M/N
π=4P,N的取D?π的D_
2.2 java代码实现法
N取gؓ(f)10000?多线E的Cؓ(f)100,每个U程执行100万次模拟实验
U程实现
import java.util.concurrent.CountDownLatch;
public class ProModel implements Runnable {
public int N;//随机实验的L?br /> public static int M;//随机点落在圆中的ơ数
private int id;
private final CountDownLatch doneSignal;
OBJ semaphore;
public ProModel(int id,CountDownLatch doneSignal,int N,OBJ semaphore2){
this.id=id;
this.doneSignal=doneSignal;
this.N=N;
this.semaphore=semaphore2;
M=0;
}
public void run(){
int tempM=0;
for(int i=0;i
if(isInCircle()){
tempM++;
}
}
synchronized (semaphore) {
add(tempM);
}
doneSignal.countDown();//使end状态减1
}
public void add(int tempM){
System.out.println(Thread.currentThread().getName());
M=M+tempM;
System.out.println(M);
}
//随机产生一个在正方形区域的?判断它是否在圆中
public boolean isInCircle(){
double x=Math.random();
double y=Math.random();
if((x-0.5)*(x-0.5)+(y-0.5)*(y-0.5)<0.25)
return true;
else
return false;
}
public static int getTotal(){
return M;
}
}
多线EMain实现
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MutliThread {
public static void main(String[] args) throws InterruptedException {
long begin=System.currentTimeMillis();
int threadSize=100;
int N=1000000;
OBJ semaphore = new OBJ();
CountDownLatch doneSignal = new CountDownLatch(threadSize);
ProModel[] pros=new ProModel[threadSize];
//讄特定的线E池,大小为threadSizde
System.out.println(“begins!”);
ExecutorService exe = Executors.newFixedThreadPool(threadSize);
for(int i=0;i
exe.execute(new ProModel(i+1,doneSignal,N,semaphore));
try{
doneSignal.await(); //{待end状态变?, }catch (InterruptedException e) {
// TODO: handle exception35
e.printStackTrace();
}finally{
System.out.println(“ends!”);
System.out.println(4*(float)ProModel.getTotal()/(float)(threadSize*N));
}
exe.shutdown();
long end=System.currentTimeMillis();
System.out.println(“used time(ms):”+(end-begin));
}
}
class OBJ{}
单线EMain实现
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SingleThread {
public static void main(String[] args) {
long begin=System.currentTimeMillis();
int threadSize=1;
int N=100000000;
OBJ semaphore = new OBJ();
CountDownLatch doneSignal = new CountDownLatch(threadSize);
ProModel[] pros=new ProModel[threadSize];
//讄特定的线E池,大小?
System.out.println(“begins!”);
ExecutorService exe = Executors.newFixedThreadPool(threadSize);
for(int i=0;i
exe.execute(new ProModel(i+1,doneSignal,N,semaphore));
try{
doneSignal.await(); //{待end状态变?, }catch (InterruptedException e) {
// TODO: handle exception35
e.printStackTrace();
}finally{
System.out.println(“ends!”);
System.out.println(4*(float)ProModel.getTotal()/(float)(threadSize*N));
}
exe.shutdown();
long end=System.currentTimeMillis();
System.out.println(“used time(ms):”+(end-begin));
}
}
Ҏ(gu)asListq回的是new ArrayList(a)。但是,q个ArrayListq不是java.util.ArrayListQ它是一个ArrayscM的重新定义的内部cR?br /> 具体的实现如下:(x)
Java代码
/**
* @serial include
*/
private static class ArrayList extends AbstractList
implements RandomAccess, java.io.Serializable
{
private static final long serialVersionUID = -2764017481108945198L;
private Object[] a;
ArrayList(E[] array) {
if (array==null)
throw new NullPointerException();
a = array;
}
public int size() {
return a.length;
}
public Object[] toArray() {
return (Object[])a.clone();
}
public E get(int index) {
return (E)a[index];
}
public E set(int index, E element) {
Object oldValue = a[index];
a[index] = element;
return (E)oldValue;
}
public int indexOf(Object o) {
if (o==null) {
for (int i=0; i
if (a[i]==null)
return i;
} else {
for (int i=0; i
if (o.equals(a[i]))
return i;
}
return -1;
}
public boolean contains(Object o) {
return indexOf(o) != -1;
}
}
从这个内部类ArrayList的实现可以看出,它承了cAbstractList,但是没有重写add和removeҎ(gu)Q没有给出具体的实现。查看一下AbstractListcM对add和removeҎ(gu)的定义,如果一个list不支持add和remove׃(x)抛出UnsupportedOperationException?br /> Java代码
public abstract class AbstractList extends AbstractCollection implements List {
/**
* Sole constructor. (For invocation by subclass constructors, typically
* implicit.)
*/
protected AbstractList() {
}
/**
* Appends the specified element to the end of this List (optional
* operation).
*
* This implementation calls add(size(), o).
*
* Note that this implementation throws an
* UnsupportedOperationException unless add(int, Object)
* is overridden.
*
* @param o element to be appended to this list.
*
* @return true (as per the general contract of
* Collection.add).
*
* @throws UnsupportedOperationException if the add method is not
* supported by this Set.
*
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this set.
*
* @throws IllegalArgumentException some aspect of this element prevents
* it from being added to this collection.
*/
public boolean add(E o) {
add(size(), o);
return true;
}
/**
* Inserts the specified element at the specified position in this list
* (optional operation). Shifts the element currently at that position
* (if any) and any subsequent elements to the right (adds one to their
* indices).
*
* This implementation always throws an UnsupportedOperationException.
*
* @param index index at which the specified element is to be inserted.
* @param element element to be inserted.
*
* @throws UnsupportedOperationException if the add method is not
* supported by this list.
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this list.
* @throws IllegalArgumentException if some aspect of the specified
* element prevents it from being added to this list.
* @throws IndexOutOfBoundsException index is out of range (index <
* 0 || index > size()).
*/
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
/**
* Removes the element at the specified position in this list (optional
* operation). Shifts any subsequent elements to the left (subtracts one
* from their indices). Returns the element that was removed from the
* list.
*
* This implementation always throws an
* UnsupportedOperationException.
*
* @param index the index of the element to remove.
* @return the element previously at the specified position.
*
* @throws UnsupportedOperationException if the remove method is
* not supported by this list.
* @throws IndexOutOfBoundsException if the specified index is out of
* range (index < 0 || index >= size()).
*/
public E remove(int index) {
throw new UnsupportedOperationException();
}
}
xQؓ(f)什么Arrays.asList产生的List是不可添加或者删除,否则?x)生UnsupportedOperationExceptionQ就可以得到解释了?br /> 如果我们x一个变长或者数据{变成ListQ?而且tb期望q个List能够q行add或者remove操作Q那该怎么做呢?
我们可以写一个类似的Ҏ(gu)Q里面直接采用java.util.ArrayList卛_?br /> 比如Q?br /> Java代码
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MyArrays {
public static List asList(T... a) {
List list = new ArrayList();
Collections.addAll(list, a);
return list;
}
}
试代码如下Q?br /> Java代码
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Test {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
List stooges = Arrays.asList("Larry", "Moe", "Curly");
print(stooges);
List> seasonsList = Arrays.asList(retrieveSeasonsList());
print(seasonsList);
/*
* 自己实现一个asListҎ(gu)Q能够添加和删除?br /> */
List list = MyArrays.asList("Larry", "Moe", "Curly");
list.add("Hello");
print(list);
}
private static void print(List list) {
System.out.println(list);
}
private static List retrieveSeasonsList() {
List seasonsList = new ArrayList();
seasonsList.add("Spring");
seasonsList.add("Summer");
seasonsList.add("Autumn");
seasonsList.add("Winter");
return seasonsList;
}
}
输出l果Q?br /> [Larry, Moe, Curly]
[[Spring, Summer, Autumn, Winter]]
[Larry, Moe, Curly, Hello]