Стирание типа Java, общие списки с непроверенным назначением - PullRequest
0 голосов
/ 01 ноября 2018

В настоящее время я пишу программу, в которой у меня есть следующее утверждение.

List<BaseballStatistic> q = BaseballStatistic.FIND.where().eq("teamID", "CHN").query();

Здесь жалуется

Непроверенное назначение: «java.util.List» для «java.util.List». Причина: 'BaseballStatistic.FIND.where (). Eq ("teamID", "CHN") "имеет необработанный тип, поэтому результат запроса стирается подробнее ...

У меня есть интерфейс, который выглядит следующим образом

public interface Query<T> {
  ...
  List<T> execute();
}

затем абстрактный класс, который реализует этот интерфейс

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();
}

и, наконец, конкретная реализация:

public class SimpleQuery<T> extends AbstractQuery<T> {

public SimpleQuery(Class<T> type) {
  super(type);
}

, которая содержит следующую функцию .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();
}
}

Кажется, что здесь, при компиляции, возвращенный список потерял свой тип, что привело к предупреждению. Если я изменю исходное объявление переменной на List, предупреждение исчезнет, ​​что имеет смысл.

Есть ли что-нибудь вокруг этого или есть более важная фундаментальная проблема в игре?

РЕДАКТИРОВАТЬ:

Функция запроса, которая вызывает выполнение, находится здесь

 public List<T> query() {
   return _query.execute();
 }

А отношения между SimpleQuery и BaseballStatistic.Find таковы.

@Table(name = "baseballStats")
public class BaseballStatistic extends PinotModel {

  public static final Find FIND = new Find<BaseballStatistic (BaseballStatistic.class) { };
...

и 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();
  }
 }
}

1 Ответ

0 голосов
/ 01 ноября 2018

В двух местах вам не хватает параметров универсального типа.

  1. BaseballStatistic.FIND:

    public static final Find<BaseballStatistic> FIND = new Find<BaseballStatistic> (BaseballStatistic.class) { };

  2. PinotModel.select:

    public Query<T> select(String... s) { return new SimpleQuery<T>(type).select(s); }

Вам также не хватает параметров типа в PinotModel.where(). Clause также потребуется параметр типа, в том числе в поле AbstractQuery._clauses.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...