2012-01-04 106 views
0

這可能嗎?我從一個JSON字符串使用此代碼創建一個對象:設置通用Java Bean的屬性

String obj = new Gson().toJson(jsonArray.getJSONObject(i)); 
String className = getClassName(jsonArray.getJSONObject(i)); 

Class targetClass = null; 
try { 
    targetClass = Class.forName(className); 
} catch (ClassNotFoundException e) { 
       e.printStackTrace(); 
} 

//Create Object 
Object data = new Gson().fromJson(obj, targetClass); 

我然後做一些數據庫的東西,得到一個返回鍵的值,我想使用它的SETID設置bean對象上鍵()的setter ,但我不想將特定類型的對象轉換爲泛型對象,因爲這需要我多次重複完全相同的代碼才能投射對象。

key = contactsListDAO.manageDataObj(data, sql, true); 
((PhoneNumber) data).setId(key); 

我可以使用某種形式的if語句來檢查對象包含一個id屬性,然後設置一般對象的ID而無需進行轉換?

回答

0

反射可以做到這一點,但我想也許在這裏你應該做點別的。 寫效用函數

public static <T> T fromJson(String json, Class<T> clzz) 
{ 
return (T) new Gson().fromJson(obj, targetClass); 
} 

,然後你可以調用它像這樣

PhoneNumber data = fromJson(obj, PhoneNumber.class); 

沒有更多的轉換。

編輯:如果使用「對象」是一種約束,你可以使用反射

public void setIdOnObject(Object obj, Object id) 
    { 
     try{ 
     Method m = obj.getClass().getMethod("setId",id.getClass()); 
      m.invoke(obj, id); 

     }catch(NoSuchMethodException e){ return false; } catch (InvocationTargetException e) { 
      e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. 
     } catch (IllegalAccessException e) { 
      e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. 
     } 
    } 

這裏是工作示例我有,只是複製粘貼運行。

import java.lang.reflect.InvocationTargetException; 
public class Reflection 
{ 

    public static void main(String[] args) 
    { 
     MyParent p = new MyParent(); 
     setParentKey(p, "parentKey"); 

     MyObj o = new MyObj(); 
     setParentKey(o, "myParentKey"); 
     setMyKey(o, "myKey"); 

     System.out.println("p = " + p); 
     System.out.println("o = " + o); 

    } 



    public static void invokeMethod(Object p, Object k, String methodName) 
    { 
     try 
     { 
      p.getClass().getMethod(methodName, k.getClass()).invoke(p, k); 
     } 
     catch (NoSuchMethodException e) 
     { 
      e.printStackTrace(); 
     } 
     catch (InvocationTargetException e) 
     { 
      e.printStackTrace(); 
     } 
     catch (IllegalAccessException e) 
     { 
      e.printStackTrace(); 
     } 
    } 

    public static void setParentKey(Object p, Object k) 
    { 
      invokeMethod(p,k,"setParentKey"); 
    } 

    public static void setMyKey(Object p, Object k) 
    { 
     invokeMethod(p,k,"setMyKey"); 
    } 

    public static class MyParent 
    { 
     private Object parentKey; 
     public void setParentKey(String k) 
     { 
      parentKey = k; 
     } 

     @Override 
     public String toString() 
     { 
      return "MyParent{" + 
          "parentKey=" + parentKey + 
          '}'; 
     } 
    } 

    public static class MyObj extends MyParent 
    { 
     private Object myKey; 
     public void setMyKey(String k) 
     { 
      myKey = k; 
     } 

     @Override 
     public String toString() 
     { 
      return "MyObj{" + 
          "myKey=" + myKey + 
          "} " + super.toString(); 
     } 
    } 
} 

和預期的輸出結果是:

p = MyParent{parentKey=parentKey} 
o = MyObj{myKey=myKey} MyParent{parentKey=myParentKey} 
+0

我不想通過它的類型調用對象。我有多個訪問這個類的bean類型,並且完全一樣。它們都有一個id屬性,因此它可以安全地將我的密鑰設置在任何將訪問該類的對象上。但是,驗證其可用的檢查會很好。 – ryandlf 2012-01-04 05:35:24

+0

我知道這個班,所以這看起來像是一個檢查房產的好方法。那麼如何設置對象上的鍵而不用強制bean類型呢? – ryandlf 2012-01-04 05:58:50

+0

更改了我的編輯以滿足您的需求 - 無需轉換任何內容。它檢查是否有方法並調用它。 – 2012-01-04 06:03:20

0

如果你有(你提到)「多豆種」和「他們都有一個id屬性」,你爲什麼不定義使用setId方法的bean的通用接口?

你會得到你的bean,並只投射到接口,這將是一個安全的和麪向對象的方法。對你來說這是一個可行的解決方案嗎?

+0

bean的id屬性是唯一匹配的屬性。你的解決方案仍然是一個更好的方法? – ryandlf 2012-01-04 06:11:43

+0

當然。使用任何類型的非Object類型都會更好,因爲java是強類型語言。如果您使用接口,則可以使用我之前提出的功能。 'public static T fromJson(String json,Class clzz)' – 2012-01-04 07:53:26

0

這是我的工作代碼。出於某種原因,我永遠無法找到使用class.getMethod()的方法,所以我必須遍歷一組方法,並將名稱與我知道存在的setId方法進行匹配。從那裏使用invoke是正確設置屬性的關鍵。

public void setIdOnObject(Object obj, int id, Class<?> targetClass) { 
    Method[] methods = targetClass.getMethods(); 
    for(Method i : methods) { 
     if(i.getName().equals("setId")) { 
      try { 
       i.invoke(obj, id); 
      } catch (IllegalArgumentException e) { 
       e.printStackTrace(); 
      } catch (IllegalAccessException e) { 
       e.printStackTrace(); 
      } catch (InvocationTargetException e) { 
       e.printStackTrace(); 
      } 
     }   
    } 
} 
相關問題