最近在研究java回调的问题,有些地方不理解,特地请教,请不吝赐教,谢谢部分代码public String updateGiftSendAddress(final String giftOrderId, final String receiverName, final String address, final String zoneCode, final String linkTel, final String customerId) {
int updateNum = giftOrderDao.updateGiftSendAddress( giftOrderId, receiverName, address, zoneCode, linkTel, customerId);
String updateResult = "false";
       ..............
              ..............
return updateResult;
}
被调用代码 public int updateGiftSendAddress(final String giftOrderId, final String receiverName, final String address,
final String zoneCode, final String linkTel, final String customerId)
 {

String sql = "update JSMSS_GIFT_ORDER set RECEIVE_MAN=?,ADDR=?,ZONE_CODE=?,LINK_TEL=?,CUSTOMER_ID=? where GIFT_ORDER_ID=? ";
int updateNum = jdbcDao.update(sql, new PreparedStatementSetter() {
public void setValues(PreparedStatement ps) throws SQLException {
ps.setString(1, receiverName);
ps.setString(2, address);
ps.setInt(3, Integer.parseInt(zoneCode));
ps.setString(4, linkTel);
ps.setString(5, customerId);
ps.setInt(6, Integer.parseInt(giftOrderId));
}
});
return updateNum;
}函数giftOrderDao.updateGiftSendAddress调用兰色部分的代码
被调用的函数中有一个匿名类,我想问下,这个匿名类部分是不是java回调的实现哦,而且匿名类部分代码在什么时候执行哦?

解决方案 »

  1.   

    这怎么看哦,反正我是从来没有看到过 PreparedStatementSetter 这个类,也不知道这是干嘛用的。
      

  2.   

    匿名类和回调函数是不一样的。
    匿名类的好处只是不需要显示地生成一个Java文件定义一个类,本质上还是生成了一个类的实例,只是这个类没有名字。一般应用于生成实现某一个接口的实例类。
      

  3.   

    jdbcDao.update方法的定义就是update(String,PreparedStatementSetter ) 这里的PreparedStatementSetter 是一个接口,也可以自己写一个实现类,这里用的是匿名类。那么在update的而方法题中一定是这个样子:
    update(String sql,PreparedStatementSetter psseter) {
         Connection con = getConn();
         PreparedStatement ps = con.prepareStatement(sql);
         psseter.setValues(ps );
         ps.excuteQuery();
    。。
    }回调就是在psseter.setValues(ps )这一行发生的。说白了,上层方法只是告诉你到了一个时点我要做什么事情,但是怎么做,就依赖调用者提供的规则。
    上面的例子中上层方法指的就是update,方法中说生成了PreparedStatement 之后,要为PreparedStatement 设置参数,但是怎么做,update方法不知道,他只管调用自己认识的PreparedStatementSetter 中的setValues,至于传进来的PreparedStatementSetter 的实现类怎么去实现,实现是否正确,那全部由调用者保证。SSH中类似的回调很多,比如吧查询结果包装成对象列表返回等。Jquery中也有类似的机制,在ajax接收到服务器返回的信息时,也是通过回调来吧信息写回到页面上的
      

  4.   

    如果LZ学过spring就知道,spring中有部分说到持久层,其中有个类JdbcTemplate,顾名思义它是利用Template模式,Template模式就是说在父类中定义一个操作算法或操作顺序,而将一些步骤的具体实现延迟到子类中。例子:
    父类:
    public abstract class TestTemplate {
    public abstract Object doInTransaction(); public void execute() {
    try {
    System.out.println("事务开始");
    System.out.println("开始执行业务逻辑代码");
    doInTransaction();
    System.out.println("业务逻辑处理完成,提交事务");
    } catch (Exception e) {
    System.out.println("出现错误,回滚");
    }
    }
    }
    子类:
    public class SubTemplate extends TestTemplate { public Object doInTransaction() {
    System.out.println("正在执行业务逻辑代码");
    return null;
    } public static void main(String[] args) {
    SubTemplate s = new SubTemplate();
    s.execute();
    }
    }
    还有一种回调形式是利用接口回调函数,例子:
    // Tepmlate 模式
    // 声明回调接口
    interface TestTemplateCallBack {
    Object doSomething();
    }class Template2 { // 执行业务逻辑的方法,参数类型为接口
    public void execute(TestTemplateCallBack callBack) {
    try {
    System.out.println("事务开始");
    System.out.println("开始执行业务逻辑");
    callBack.doSomething();
    System.out.println("业务逻辑执行成功,提交事务"); } catch (Exception e) { String sOut = "";
    StackTraceElement[] trace = e.getStackTrace();
    for (StackTraceElement s : trace) {
    sOut += "\tat " + s + "\r\n";
    }
    System.out.println(sOut); }
    }
    }public class TestTemplate2 { public void insert(final String msg) {
    Template2 t = new Template2();
    // 匿名内部类重写方法,--1--
    t.execute(new TestTemplateCallBack() {
    public Object doSomething() {
    System.out.println("插入数据:" + msg);
    return null;
    }
    }); } public static void main(String[] args) {
    TestTemplate2 t = new TestTemplate2();
    t.insert("Hello");
    }
    }
    PreparedStatementSetter,也是个spring接口,全称org.springframework.jdbc.core.PreparedStatementSetter
    因此LZ得代码是一种回调的实现
      

  5.   

    首先顶6楼的
    函数回调和匿名类是两个不同范畴,只是使用匿名类更加方便的实现方法回调。
    比如js中的回调吧:
      function f1(){
        ...
      };
      setTimeOut(f1(),1000);
    写成匿名的就是:
      setTimeOut(function(){
        ...
      },1000);