[英]Java Type Erasure, Generic Lists with Unchecked Assignment
Currently I'm writing a program where I have the following statement. 目前,我正在编写一个程序,其中有以下语句。
List<BaseballStatistic> q = BaseballStatistic.FIND.where().eq("teamID", "CHN").query();
Here, it complains 在这里,它抱怨
Unchecked assignment: 'java.util.List' to 'java.util.List'. 未经检查的分配:从“ java.util.List”到“ java.util.List”。 Reason: 'BaseballStatistic.FIND.where().eq("teamID", "CHN")' has raw type, so result of query is erased more...
原因:'BaseballStatistic.FIND.where()。eq(“ teamID”,“ CHN”)'具有原始类型,因此查询结果被删除了更多...
I have an interface which looks like this 我有一个看起来像这样的界面
public interface Query<T> {
...
List<T> execute();
}
then an abstract class that implements this interface 然后是实现此接口的抽象类
public abstract class AbstractQuery<T> implements Query<T> {
Statement _statement = null;
String _tableName;
List<Clause> _clauses;
Class<T> _type;
AbstractQuery(Class<T> type) {
_type = type;
_clauses = new ArrayList<>();
_tableName = type.getAnnotation(Table.class).name();
}
...
public abstract List<T> execute();
}
and finally a concrete implementation: 最后是一个具体的实现:
public class SimpleQuery<T> extends AbstractQuery<T> {
public SimpleQuery(Class<T> type) {
super(type);
}
which houses the following .query function which looks like: 其中包含以下.query函数,如下所示:
@Override
public List<T> execute() {
try {
JSONObject jsonObject = Peanut.getClient().listStatistics(buildQuery());
if (jsonObject == null || !jsonObject.has("results")) {
return Collections.emptyList();
}
JSONArray columnNames = jsonObject.getJSONArray("columns");
Map<String, Integer> columnNameMap = new HashMap<>();
for (int i = 0; i < columnNames.length(); i++) {
columnNameMap.put((String) columnNames.get(i), i);
}
JSONArray results = jsonObject.getJSONArray("results");
List<T> ts = new ArrayList<>();
for (int i = 0; i < results.length(); i++) {
JSONArray result = results.getJSONArray(i);
T t = _type.newInstance();
for (Field field : ObjectUtils.getFieldsUpTo(t.getClass(), PinotModel.class)) {
if (field.getAnnotation(Column.class) == null) {
continue;
}
Object obj = ObjectUtils.getDefaultValue(field.getType());
String columnName = field.getAnnotation(Column.class).name();
if (columnNameMap.containsKey(columnName)) {
int idx = columnNameMap.get(columnName);
field.setAccessible(true);
field.set(t, ObjectUtils.convertObject(obj, result.get(idx)));
}
}
ts.add(t);
}
return ts;
} catch (Exception e) {
// TODO: Throw Peanut specific error.
Peanut.LOG.error(e);
return Collections.emptyList();
}
}
It seems like here, at compilation, the returned list has lost it's type leading to the warning. 似乎在这里,在编译时,返回的列表丢失了导致警告的类型。 If I change the original variable declaration to List the warning will leave, which makes sense.
如果我将原始变量声明更改为List,则警告将消失,这很有意义。
Is there anyway around this or is there a larger fundamental issue at play? 无论如何还是在解决更大的基本问题?
EDIT: 编辑:
Query Function that calls execute is here 调用执行的查询功能在这里
public List<T> query() {
return _query.execute();
}
And the relationship between SimpleQuery and BaseballStatistic.Find is as follows. 并且SimpleQuery与BaseballStatistic.Find之间的关系如下。
@Table(name = "baseballStats")
public class BaseballStatistic extends PinotModel {
public static final Find FIND = new Find<BaseballStatistic (BaseballStatistic.class) { };
...
and PinotModel looks like 和PinotModel看起来像
public class PinotModel {
public static class Find<T> {
private final Class<T> type;
protected Find(Class<T> type) {
this.type = type;
}
public Query select(String... s) {
return new SimpleQuery<T>(type).select(s);
}
public Clause where() {
return new SimpleQuery<T>(type).where();
}
public Clause limit(Integer n) {
return new SimpleQuery<T>(type).limit(n);
}
public Clause top(Integer n) {
return new SimpleQuery<T>(type).top(n);
}
public Clause orderBy(String columnName, Order o) {
return new SimpleQuery<T>(type).orderBy(columnName, o);
}
public String tableName() {
return new SimpleQuery<T>(type).getTableName();
}
}
}
There are 2 places that you're missing generic type parameters. 您缺少2个通用类型参数的地方。
BaseballStatistic.FIND
: BaseballStatistic.FIND
:
public static final Find<BaseballStatistic> FIND = new Find<BaseballStatistic> (BaseballStatistic.class) { };
PinotModel.select
: PinotModel.select
:
public Query<T> select(String... s) { return new SimpleQuery<T>(type).select(s); }
You're also missing type parameters on PinotModel.where()
. 您还缺少
PinotModel.where()
上的类型参数。 Clause
would also need a type parameter, including on the AbstractQuery._clauses
field. Clause
还需要一个类型参数,包括AbstractQuery._clauses
字段上的参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.