Java泛型错误:来自命令行编译器的不可逆类型

时间:2011-11-14 19:01:27

标签: java eclipse generics guice

我有一些使用泛型的Guice绑定代码,可以从Eclipse的编译器编译和编译,但不能从Java(命令行)编译器编译。我升级到最新的(1.7.0_01)Java SDK但仍然出现以下错误。

[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 个答案:

答案 0 :(得分:6)

帮自己一个忙,然后做一个向上看,然后是一个沮丧的人:

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 :(得分:1)

我知道答案是有效的并且已被接受,但我相信这种沮丧的人不是完美的解决方案。此外,我的代码清理删除了过时的向下转换...

1)eclipse和命令行没有产生同样问题的原因是因为eclipse设置。转到首选项 - java - 编译器 - 错误/警告并将通用类型(未经检查的泛型类型操作)设置为警告。然后,如果删除@SuppressWarnings("unchecked")

,您将检测到同样的问题

2)我有一个类似的问题,一位朋友给我看了另一个解决方案。要正确修复代码(不使用向下转换),只需将CategoryDataProvider.class更改为:

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

然后把它放回去     @SuppressWarnings("unchecked")