Ошибка Generics Java: необратимые типы из компилятора командной строки - PullRequest
9 голосов
/ 14 ноября 2011

У меня есть некоторый код привязки Guice с использованием обобщений, которые прекрасно компилируются и функционируют из компилятора Eclipse, но не из компилятора Java (командной строки).Я обновил Java SDK до последней (1.7.0_01), но все равно получаю следующую ошибку:

[error] ...\BindCategorySelectorActivity.java:42: error: inconvertible types
[error]                                 (Class<? extends ListAdapterDataProvider<Row<? extends DatabaseItem>>>) CategoryDataProvider.class);
[error]                                                                                                                             ^
[error]   required: Class<? extends ListAdapterDataProvider<Row<? extends DatabaseItem>>>
[error]   found:    Class<CategoryDataProvider>
[error] 1 error
[error] {file:/.../compile:compile: javac returned nonzero exit code

Соответствующий код:

public interface Category extends DatabaseItem {}
public class CategoryDataProvider implements 
 ListAdapterDataProvider<Row<Category>> {}
public class BindListViewHandlerWithSpecificProvider extends AbstractModule {
    public BindListViewHandlerWithSpecificProvider(
     Class<? extends ListAdapterDataProvider<Row<? extends DatabaseItem>>>
      dataProviderClass) {}
}

@SuppressWarnings("unchecked")
// Error happens here:
final BindListViewHandlerWithSpecificProvider 
 bindListViewHandlerWithSpecificProvider = 
  new BindListViewHandlerWithSpecificProvider(
   (Class<? extends ListAdapterDataProvider<Row<? extends DatabaseItem>>>)
    CategoryDataProvider.class);

Ответы [ 2 ]

6 голосов
/ 15 ноября 2011

Сделайте себе одолжение и сделайте upcast, за которым следует downcast:

Class<...> foo = (Class<...>)(Object)MyClass.class;

Проблема в том, что CDP.class имеет тип Class<CDP>, CDP является необработанным типом.Хотя параметризованный тип C<T1,...,Tn> является подтипом необработанного типа C (§4.10.2), обратное неверно: C не является подтипом C<T1,...,Tn>.Это только кажется правдой из-за непроверенного преобразования (§5.1.9).Это вызывает вашу проблему: вы ожидаете, что CDP «расширится» (как в верхней границе Class<? extends ...>) LADP<Row<? extends DI>>.Это не так, потому что содержание аргумента типа (§4.5.1.1) определено над подтипом и не учитывает неконтролируемое преобразование.

(Или, чтобы перейти к погоне: javac понял это правильно).*

1 голос
/ 12 февраля 2014

Я знаю, что ответ работает и принят, но я считаю, что удручение - не идеальное решение. Кроме того, мой код очистки удаляет устаревшие приведения вниз ...

1) причина, по которой eclipse и командная строка не дают такой же проблемы, связана с настройками eclipse. Перейдите в настройки - java - compiler - Errors / Warnings и установите для универсальных типов (операция непроверенного универсального типа) предупреждение. Тогда вы обнаружите ту же проблему, если вы удалите @SuppressWarnings("unchecked")

2) У меня была похожая проблема, и друг показал мне другое решение. Чтобы исправить код правильно (без приведения вниз), просто измените ClassDataProvider.class на это:

new CategoryDataProvider<Row<DatabaseItem>>().getClass()

Тогда положи обратно @SuppressWarnings("unchecked")

...