我有一些Guice绑定(bind)代码使用泛型,这些泛型可以从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);

最佳答案

帮自己一个忙,先高调后低调:

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正确地做到了这一点。)

07-24 21:36