Java问题中的泛型和类型擦除
我目前面临以下问题: 我正在尝试将递归算法转换为迭代算法。这个递归算法的作用是: 方法1传递一些初始参数。基于method1开始时发生的处理,method2使用这些参数调用。现在method2使用一些条件,并基于满足的条件,使用适当的参数再次调用method1 现在,根据我在上面提供的链接上的答案,我做了同样的事情。但我必须传递参数,所以我这样做:Java问题中的泛型和类型擦除,java,arrays,generics,arraylist,type-erasure,Java,Arrays,Generics,Arraylist,Type Erasure,我目前面临以下问题: 我正在尝试将递归算法转换为迭代算法。这个递归算法的作用是: 方法1传递一些初始参数。基于method1开始时发生的处理,method2使用这些参数调用。现在method2使用一些条件,并基于满足的条件,使用适当的参数再次调用method1 现在,根据我在上面提供的链接上的答案,我做了同样的事情。但我必须传递参数,所以我这样做: Stack-Stack(用于ArrayList对象的堆栈) ============================================
Stack-Stack
(用于ArrayList
对象的堆栈)
===========================================================
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> 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;
}
第二种方法应该在其中一个条件内返回,但没有一个条件满足否-这不是类型擦除问题。正如甲骨文所说: 类型擦除可确保不会为参数化类型创建新类 类型;因此,泛型不会产生运行时开销 所以在运行时,类只是普通类,对象就是它们,但它不会删除基类型信息
为什么不输入一条log语句并打印出对象的类呢?我个人无法在没有看到实际代码的情况下回答这个问题。嗨,乔治。这听起来像是一个极其复杂的问题,需要用一个简单、可编译的核心概念示例来概括。在Java中使用泛型的全部好处是避免使用
Object
和instanceof
以及从一种类型转换到另一种类型。您不能用适合您的问题的特定类型替换对象
,或使您的方法通用(以便客户端代码可以直接指定有效负载类型)?请提供特定的代码示例。@在一分钟内添加代码不会删除基本类型信息。
是,但是这里我的基本类型是Object
,因为数组列表中的对象没有公共继承。因此,除了对象之外的所有其他类型信息都将被删除。对吗?instanceof
将查看存储在数组中的实际对象的类型(永远不会被擦除),而不是泛型声明中数组参数的类型(它确实被擦除了,而且没有任何用处)。让我检查一下,然后再打给你。数组中存储的实际对象的类型没有被删除?数组参数的类型是什么意思?我指的是
位。系统无法区分ArrayList
和ArrayList
;它只是一个数组列表
。但您并不是在查看数组类型,而是在查看数组元素中的实际对象。
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);
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;
}