Java问题中的泛型和类型擦除

时间:2015-04-03 12:12:19

标签: java arrays generics arraylist type-erasure

我目前面临以下问题:

我正在尝试refactor递归算法到迭代算法。这种递归算法的作用是:

method1 传递了一些初始参数。基于在method1开头发生的处理,使用这些参数调用 method2 。现在,method2使用了一些条件,并且基于满足的条件,再次使用适当的参数调用method1。

现在,基于我在上面提供的链接上的答案,我做了同样的事情。但我必须传递参数,所以我这样做了:

Stack<ArrayList<Object>> stackArrayList<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;
}

第二种方法应该从一种条件中返回,但不满足任何条件

1 个答案:

答案 0 :(得分:0)

不 - 这不是类型擦除问题。正如Oracle所说:

  

类型擦除确保不会为参数化创建新类   类型;因此,泛型不会产生运行时开销。

因此,在运行时,您的类只是普通的类,您的对象就是它们,但它不会删除基类型信息。

为什么不在日志声明中打印并打印出对象的类?