首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >映射的反思

映射的反思
EN

Stack Overflow用户
提问于 2013-02-13 13:41:13
回答 1查看 109关注 0票数 0

我正在尝试开发一些实用程序代码,它可以移植到J2SE和Android平台上,用于对象缓存。计划是在我使抽象类正常工作时提取它,但现在它是最终类实现的一部分。

我希望缓存的对象已经被实例化并传递给store(Object, Object)方法,该方法将在最终版本中成为抽象类的一部分,因此它需要使用自省来确定如何存储已传递的数据。

算法并不复杂:

1)。扫描对象的方法,寻找@Id属性,如果找到,使用它来获取对象的键。

2)。扫描store()方法自己的类,寻找实现put(key.getClass(), value.getClass())方法的字段,并使用该字段缓存对象。

第(1)部分工作得很好,第(2)部分是我无法工作的部分。我得到:

代码语言:javascript
复制
DEBUG c.n.v.ui.cache.Cache Not found: operativesMap.put(String, OperativeEntity)
WARN c.n.v.ui.cache.Cache Object Joe Bloogs, with key cac57510-c9c6-11df-8000-b56f1ffcb182 not cached!
INFO c.n.v.ui.cache.Cache Object Joe Bloggs, with key cac57510-c9c6-11df-8000-b56f1ffcb182 cached.

日志显示内省代码找不到put方法,并且下降到了双重检查逻辑(当我将该方法移到抽象类时必须删除该逻辑)。

一如既往,非常感谢您在这方面的帮助。

史蒂夫

代码语言:javascript
复制
public void store(Object key,
          Object value) {
    if (log.isInfoEnabled())
        log.info("Storing:  " + key + " => " + value);

    for (Field field: getClass().getDeclaredFields())
        if (store(field, key, value))
         return;

    log.warn("Object " + value + ", with key " + key + " not cached!");

    if (value instanceof OperativeEntity) {
        operativesMap.put(key.toString(), (OperativeEntity) value);
        log.info("Object " + value + ", with key " + key + " cached.");

        // How did I get here, and I do - the loop above should have found
        // operativesMap, it's put method and stored the value
    }
}

public boolean store(Field field,
             Object key,
             Object value) {
    try {
        Method method = field.getClass().getMethod("put", key.getClass(), value.getClass());

        if (null != method)
            return store(field.get(this), method, key, value);

        else
            return false;

    } catch (NoSuchMethodException cause) {
        if (log.isDebugEnabled())
        log.debug("Not found: " + field.getName() + ".put(" + key.getClass().getSimpleName()
                  + ", " + value.getClass().getSimpleName() + ")");
        return false;

    } catch (Exception cause) {
        log.error("Stroing " + key + "=>" + value + " mapping", cause);
        return false;
    }
}

public boolean store(Object obj,
             Method method,
             Object key,
             Object value) {
    try {
        method.invoke(obj, key, value);
        if (log.isInfoEnabled())
           log.info(">>>>>> Cached " + key + "=>" + value);
        return true;

    } catch (Exception cause) {
        log.error("Stroing " + key + "=>" + value + " mapping", cause);
        return false;
    }
}

更新

对于将来阅读这篇文章的人,下面给出了查找有效的put方法的代码:

代码语言:javascript
复制
public boolean store(Field field,
         Object key,
         Object value) {
try {
    Object obj = field.get(this);
    Method method = obj.getClass().getMethod("put", Object.class, Object.class);

    if (null != method) {
    Class[] params = method.getParameterTypes();
    if (log.isDebugEnabled())
        log.debug("  Found: put(" + params[0].getSimpleName() + ", " + params[1].getSimpleName() + ")");

    if (params[0].isAssignableFrom(key.getClass())
        && params[1].isAssignableFrom(value.getClass()))
        return store(obj, method, key, value);

    else
        return false;

    } else
    return false;

} catch (NoSuchMethodException cause) {
    if (log.isDebugEnabled())
    log.debug("Not found: " + field.getName() + ".put(Object, Object)");
    return false;

} catch (Exception cause) {
    log.error("Storing " + key + "=>" + value + " mapping", cause);
    return false;
}
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-02-13 13:51:17

Class.getMethod()接受参数的实际声明类型。因此,对于一张地图,这将是getMethod("put", Object.class, Object.class)。如果您只想找到一个可以接受您所拥有的键和值类型的put()方法,则需要迭代该类的方法并使用Class.isAssignableFrom()检查参数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14854916

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档