随笔-124  评论-194  文章-0  trackbacks-0
回调函数是相当有用,它的意义不仅可以让调用者控制调用函数的执行,还可以有效的将“算法”与“数据”分离,将涉及数据的部分放入回调接口(inner class)中,算法就会相对独立。下面是一个示例。

先声明一个回调接口,算法函数直接调用这些接口来获取数据:
/**
 * an inner callback interface for getting object data
 
*/

public interface ObjForJSON {
    String getName (Object o);
    String getId (Object o);
    
void putJSONData (Object o, JSONObject js) throws JSONException; 
}

算法函数,根据对象数据,进行一些逻辑处理,将集合变成JSON格式的字串:
    /**
     * iterator a set of objects, invoking its interfaces for format JSON set string
     * 
@param setName set name in XML element
     * 
@param iter set iterator object
     * 
@param e XML element
     * 
@param ctx context of DB
     * 
@param obj an inner callback class for getting object data
     
*/

    
static public void setToJSON(String setName, Iterator iter, Element e, ManagerContext ctx, ObjForJSON obj) {
        Field2Attr f2a 
= ctx.getF2a();

        String setStr 
= XmlHelper.getValue(e, setName, ctx);
        logger.debug(
"before add {}", setStr);

        
try {
            
// create JSON from exist string
            JSONObject setJson;
            
if (setStr != null && setStr.length() > 0)
                setJson 
= new JSONObject(setStr);
            
else
                setJson 
= new JSONObject();

            
while (iter.hasNext()) {
                Object o 
= iter.next();
                
                
// test if this object exists in array
                if (!setJson.has(obj.getName(o))) {
                    
// if not exist, I'll add it to array
                    JSONObject jo = new JSONObject();
                    obj.putJSONData(o, jo);

                    setJson.put(obj.getName(o), jo);
                    logger.debug(
"add obj {}", obj.getId(o));
                }

            }


            
// set it to output element
            XmlHelper.replaceValue(e, setName, setJson.toString(), ctx);

            logger.debug(
"obj set is {}", setJson.toString());
        }
 catch (JSONException e1) {
            
// TODO Auto-generated catch block
            e1.printStackTrace();
        }

    }
    


用inner class回调类为参数,调用算法函数:
        JSONHelper.setToJSON(f2a.HOST_SERVICES, o.getServices().iterator(), e, ctx, new ObjForJSON() {
            
public String getId(Object obj) {
                
return ((Service) obj).getId().toString();
            }


            
public String getName(Object obj) {
                
return ((Service) obj).getName();
            }


            
public void putJSONData(Object obj, JSONObject js) throws JSONException {
                Service s 
= (Service) obj;
                js.put(
"id", s.getId());
                js.put(
"n", s.getName());
                js.put(
"pid", o.getId());
                js.put(
"p", o.getName());
            }

        }
);


上面的匿名inner class看似语法有点怪,实际上却相当简洁实用,你只要把它视作是实现了ObjForJSON接口的一个类就可以了,只不过它是内部声明的,没有名字而矣。另外,最方便的是你可以在inner class里访问外层函数的本地变量,以及外层类的成员,大大方便数据处理。

上例中,由于使用回调inner class,可以针对多种对象执行算法函数,而不必要求待处理的对象去实现特定接口。更有些情况下,还必须使用回调才显得合理。


posted on 2008-05-16 19:19 我爱佳娃 阅读(2638) 评论(3)  编辑  收藏 所属分类: JAVA基础

评论:
# re: 用匿名inner class方便的在JAVA里实现callback功能 2008-05-17 11:01 | 山风小子
closure in disguise :)  回复  更多评论
  
# re: 用匿名inner class方便的在JAVA里实现callback功能 2008-05-17 22:13 | 我爱佳娃
TIJ3里曾经写过an inner class is an object-oriented closure,这种方式将单纯的回调方法扩展正“回调对象”。
另外,closure的语法太不平易近人,我倒是觉得匿名inner class的语法挺像JAVASCRIPT里“在调用处定义”,一眼能看清楚它都干了些啥。  回复  更多评论
  
# re: 用匿名inner class方便的在JAVA里实现callback功能 2013-06-03 14:45 | Mr.杨
好复杂 直接看不懂啊   回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问