2013-02-13 49 views
0

我想開發一些實用程序代碼,它可以移植到J2SE和Android平臺上來緩存對象。計劃是在我得到它的時候提取一個抽象類,但現在它是最終類實現的一部分。一個映射的反思

我希望緩存的對象剛剛被實例化並傳遞給store(Object, Object)方法,該方法將成爲最終版本中抽象類的一部分,因此它需要使用內省來確定如何存儲交給它的數據。

算法不是很複雜:

1)。掃描查找@Id屬性的對象的方法,如果發現使用它來獲取對象的關鍵。 2)。掃描store()方法自己的類,以獲得實現put(key.getClass(), value.getClass())方法的字段並使用它來緩存該對象。部分(1)工作得很好,部分(2)我無法工作。我得到:

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方法和已經下降,雖然在仔細檢查邏輯(這將有被刪除時,我謹方法抽象類)。

一如既往,非常感謝您的幫助。

史蒂夫

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; 
    } 
} 

更新

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; 
} 
} 

回答

0

Class.getMethod()需要:

對於任何人在將來讀這篇文章,對於查找工作put方法的代碼如下實際聲明的參數類型。所以,對於地圖來說,那將是getMethod("put", Object.class, Object.class)。如果您只想找到一個可以接受您所使用的鍵和值類型的方法,則需要遍歷該類的方法並使用Class.isAssignableFrom()檢查參數。

+0

謝謝羅素,沒有必要遍歷方法,我只是使用'getMethod(「put」,Object.class,Object.class)'然後檢查參數。但是在我的代碼中還有一個錯誤,我正在'Field'類而不是在所討論的對象上搜索'put(...)'。 – Dobbo 2013-02-13 16:16:32