2015-04-03 76 views
0

類型擦除我目前面臨的以下問題:泛型和Java中的問題

我想refactor遞歸算法,以一個迭代。這個遞歸算法所做的是:

方法1傳遞一些初始參數。基於在方法1開始處發生的處理,使用這些參數調用方法2。現在method2使用了一些條件,並基於滿足的條件再次使用適當的參數調用method1。

現在,根據我上面提供的鏈接上的答案,我做了同樣的事情。但是我有,所以我做了傳遞的參數如下:

Stack<ArrayList<Object>> stack(堆棧的ArrayList<Object>對象)

ArrayList<Object> parametersForSync = new ArrayList<Object>(); 
ArrayList<Object> paramForHandle = new ArrayList<Object>(); 

(每個對象數組列表參數被傳遞到的列表第一個數組列表用於第一個方法,第二個數組列表用於第一個方法)

假設我彈出並將數組列表正確地向下推入堆棧,我面臨以下問題,這是我的主要問題和原因這個問題:

在method2內我必須檢查對象(在數組列表中並且傳遞給方法)是否爲另一個類的instanceof。現在我有一些不是其實應該滿足的條件。

這是因爲java的類型擦除? 有沒有辦法克服這個問題?

如果我不清楚在我的解釋某一點,請讓我澄清。

編輯: 接下來的是,替換是這樣的遞歸代碼:

syncWithServer(parameter set x){ 
    handleResultArray(parameter set y); 
}; 
handleResultArray(parameter set){ 
    syncWithServer(parameter set w) 
} 

==================== =======================================

Stack<ArrayList<Object>> stack = new Stack<ArrayList<Object>>(); 
ArrayList<Object> paramList = new ArrayList<Object>(); 
paramList.add(oeHelper); 
paramList.add(false); 
paramList.add(domain); 
paramList.add(null); 
paramList.add(true); 
paramList.add(10000); 
paramList.add(true); 

stack.push(paramList); 
int counter = 0; 
ArrayList<Object> parametersForSync = new ArrayList<Object>(); 
ArrayList<Object> paramForHandle = new ArrayList<Object>(); 
while (!stack.isEmpty()) { 
    Log.d(TAG, "Loop: " + counter); 
    parametersForSync = stack.pop(); 
    paramForHandle = ((OEHelper) parametersForSync.get(0)) 
      .syncWithServer(
     // why error here? 
     (boolean) parametersForSync.get(1), 
     (OEDomain) parametersForSync.get(2), 
     (List<Object>) parametersForSync.get(3), 
     (boolean) parametersForSync.get(4), 
     (int) parametersForSync.get(5), 
     (boolean) parametersForSync.get(6)); 

    parametersForSync = ((OEHelper) paramForHandle.get(3)) 
      .handleResultArray(
     (OEFieldsHelper) paramForHandle.get(0), 
     (JSONArray) paramForHandle.get(1), 
     (boolean) paramForHandle.get(2)); 

    if (parametersForSync.size() != 0) { 
     stack.push(parametersForSync); 
    } 
    counter++; 

現在第一種方法:

public ArrayList<Object> syncWithServer(boolean twoWay, OEDomain domain, 
     List<Object> ids, boolean limitedData, int limits, 
     boolean removeLocalIfNotExists) { 
    Log.d(TAG, "syncWithServer"); 

    List<OEColumn> dbCols = mDatabase.getDatabaseColumns(); 
    List<OEColumn> dbFinalList = new ArrayList<OEColumn>(); 
    ArrayList<Object> parametersList = new ArrayList<Object>(); 

    Log.d(TAG, "Columns & finalList created"); 
    for (OEColumn col : dbCols) { 
     if (!mOne2ManyCols.contains(col.getName())) { 
      dbFinalList.add(col); 
     } 
    } 

    OEFieldsHelper fields = new OEFieldsHelper(dbFinalList); 
    try { 
     if (domain == null) { 
      domain = new OEDomain(); 
     } 
     if (ids != null) { 
      domain.add("id", "in", ids); 
     } 
     if (limitedData) { 
      mPref = new PreferenceManager(mContext); 
      int data_limit = mPref.getInt("sync_data_limit", 60); 
      domain.add("create_date", ">=", 
        OEDate.getDateBefore(data_limit)); 
     } 
     if (limits == -1) { 
      limits = 50; 
     } 
     Log.d(TAG, "*****.search_read() started"); 
     JSONObject result = *****.search_read(mDatabase.getModelName(), 
       fields.get(), domain.get(), 0, limits, null, null); 
     Log.d(TAG, "***.search_read() returned"); 
     mAffectedRows = result.getJSONArray("records").length(); 
     parametersList.add(fields); 
     parametersList.add(result.getJSONArray("records")); 
     parametersList.add(removeLocalIfNotExists); 
     parametersList.add(OEHelper.this); 

//這parametersList包含必須用來調用下一個方法

現在第二方法的參數:

================== ===============================

public ArrayList<Object> handleResultArray(
     OEFieldsHelper fields, JSONArray results, 
     boolean removeLocalIfNotExists) { 
    Log.d(TAG, "handleResultArray"); 

    ArrayList<Object> parametersList = new ArrayList<Object>(); 
    // ArrayList<Object> parameterStack = new ArrayList<Object>(); 
    try { 
     fields.addAll(results); 
     List<OERelationData> rel_models = fields.getRelationData(); 
     Log.d(TAG, "rel_models: "+rel_models.size()); 
     for (OERelationData rel : rel_models) { 

      // Handling many2many records 

      if (rel.getDb().getClass()==OEManyToMany.class 
        /*instanceof OEManyToMany*/) {//TODO type erasure? 
       Log.v(TAG, "Syncing ManyToMany Records"); 
       OEManyToMany m2mObj = (OEManyToMany) rel.getDb(); 
       OEHelper oe = ((OEDatabase) m2mObj.getDBHelper()) 
         .getOEInstance(); 

       parametersList.add(oe); 
       parametersList.add(false); 
       parametersList.add(null); 
       parametersList.add(rel.getIds()); 
       parametersList.add(false); 
       parametersList.add(0); 
       parametersList.add(false); 

       return parametersList; 
      } else if (rel.getDb().getClass()==OEManyToOne.class 
        /*instanceof OEManyToOne*/) { 

       // Handling many2One records 
       Log.v(TAG, "Syncing ManyToOne Records"); 
       // M2OCounter++; 
       OEManyToOne m2oObj = (OEManyToOne) rel.getDb(); 
       OEHelper oe = ((OEDatabase) m2oObj.getDBHelper()) 
         .getOEInstance(); 
       parametersList.add(oe); 
       parametersList.add(false); 
       parametersList.add(null); 
       parametersList.add(rel.getIds()); 
       parametersList.add(false); 
       parametersList.add(0); 
       parametersList.add(false); 
       // parametersMap.put(Counter, parametersList); 
       // parameterStack.add(parametersList); 
       return parametersList; 
      } else if (rel.getDb().getClass()==OEOneToMany.class 
        /*instanceof OEOneToMany*/) { 

       Log.v(TAG, "Syncing OneToMany Records"); 
       // O2MCounter++; 
       OEOneToMany o2mObj = (OEOneToMany) rel.getDb(); 
       OEHelper oe = ((OEDatabase) o2mObj.getDBHelper()) 
         .getOEInstance(); 
       oe.setOne2ManyCol(o2mObj.getColumnName()); 
       parametersList.add(oe); 
       parametersList.add(false); 
       parametersList.add(null); 
       parametersList.add(rel.getIds()); 
       parametersList.add(false); 
       parametersList.add(0); 
       parametersList.add(false); 
       // parametersMap.put(Counter, parametersList); 
       // parameterStack.add(parametersList); 
       return parametersList; 
      } else { 

       Log.v(TAG, "Syncing records with no relations" 
         + rel.getDb().getClass().getSimpleName()); 
       OEHelper oe = ((OEDatabase) rel.getDb()).getOEInstance(); 
       parametersList.add(oe); 
       parametersList.add(false); 
       parametersList.add(null); 
       parametersList.add(rel.getIds()); 
       parametersList.add(false); 
       parametersList.add(0); 
       parametersList.add(false); 
       return parametersList;//TODO when nothing matches this returns 
      } 
     } 
     List<Long> result_ids = mDatabase.createORReplace(
       fields.getValues(), removeLocalIfNotExists); 
     mResultIds.addAll(result_ids); 
     mRemovedRecordss.addAll(mDatabase.getRemovedRecords()); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return parametersList; 
} 

第二種方法應該從一個內部返回條件但沒有條件滿足

+6

如果沒有看到實際的代碼,我個人無法回答。 – EpicPandaForce 2015-04-03 12:18:48

+3

嗨,喬治。這聽起來像一個令人難以置信的複雜問題,需要用一個簡單的,可編輯的*核心概念*來解釋。 – christopher 2015-04-03 12:21:48

+1

在Java中使用泛型的好處是避免使用'Object'和'instanceof'並從一個類型轉換到另一個類型。難道你不能用適合你的問題的特定類型替換Object,或者使你的方法是通用的(這樣客戶端代碼可以直接指定有效載荷類型)? – Bobulous 2015-04-03 12:22:11

回答

0

否 - 這不是一個類型的擦除問題。正如Oracle所說:

類型擦除確保沒有爲參數化的 類型創建新類;因此,泛型不會導致運行時開銷。

所以在運行時,你的類只是普通的類,你的對象就是它們,但它不會去除基類型信息。

爲什麼不把日誌語句放入並打印出對象的類?

+0

'它不會去除基類型信息。'是的,但是我的基類型是'Object',因爲我的數組列表中的對象沒有共同的繼承。因此除了對象之外,其他類型的信息都被刪除。對? – 2015-04-03 13:56:55

+0

'instanceof'將查看存儲在數組中的實際對象的類型(永遠不會被擦除),而不是泛型聲明中的數組參數的類型(它不會被擦除,反正也沒有用)。 – rghome 2015-04-03 13:59:59

+0

讓我檢查一下,並會回覆你。 – 2015-04-03 14:15:29