Java泛型错误:命令行编译器中的不可转换类型
我有一些使用泛型的Guice绑定代码,这些泛型可以从Eclipse的编译器(而不是从Java(命令行)编译器)中编译并运行良好。我升级到了最新的(1.7.0_01)Java SDK,但仍然出现以下错误Java泛型错误:命令行编译器中的不可转换类型,java,eclipse,generics,guice,Java,Eclipse,Generics,Guice,我有一些使用泛型的Guice绑定代码,这些泛型可以从Eclipse的编译器(而不是从Java(命令行)编译器)中编译并运行良好。我升级到了最新的(1.7.0_01)Java SDK,但仍然出现以下错误 [error] ...\BindCategorySelectorActivity.java:42: error: inconvertible types [error] (Class<? extends ListAdapterD
[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
[error]…\BindCategorySelectorActivity.java:42:错误:不可转换的类型
[错误](类帮自己一个忙,先做一个向上的广播,然后再做一个向下的广播:
Class<...> foo = (Class<...>)(Object)MyClass.class;
Class foo=(Class)(Object)MyClass.Class;
问题是CDP.class
属于class
类型,而CDP
属于原始类型。虽然参数化类型C
是原始类型C
(§4.10.2)的子类型,但反过来则不正确:C
不是C
的子类型。这似乎只有在未经检查的转换情况下才是正确的(§5.1.9)。这导致了您的问题:您期望CDP
进行“扩展”(如类的上限我知道答案是可行的,并且被接受,但我相信向下转换不是完美的解决方案。此外,我的代码清理将删除过时的向下转换
1) eclipse和命令行没有产生相同问题的原因是eclipse设置。请转到preferences-java-compiler-Errors/Warnings并将泛型类型(未选中的泛型类型操作)设置为Warnings。然后,如果删除@SuppressWarnings(“未选中”)
2) 我遇到了一个类似的问题,一位朋友向我展示了另一个解决方案。要正确修复代码(无向下转换),只需将CategoryDataProvider.class更改为:
new CategoryDataProvider<Row<DatabaseItem>>().getClass()
new CategoryDataProvider().getClass()
然后放回去
@SuppressWarnings(“未选中”)
它成功地编译了,但我不确定向对象添加额外的强制转换是否只是掩盖了问题。Guice在尝试绑定时出现空指针异常而崩溃。它报告的行正在使用SpecificProvider访问bindListViewHandlerWithSpecificProvider
。请记住,这段相同的代码编译和执行时没有错误当在Eclipse中构建时。我承认这是一种奇怪的行为。对对象进行额外的强制转换除了欺骗javac退出sideCast
ing之外没有任何作用。您应该最终得到相同的程序。您是否熟悉Guice对泛型的新增支持,以及是否有更好的机制来传递参数化类型?有吗Scala是否能为传递参数化类型提供更好的支持?我很久以前就使用过Guice,它使用的是IIRC;我真的不知道它们是否能帮助你,以及如何帮助你。Scala提供了几乎相同的效果,只是编译器会为你推断它们。不过,这不太可能在这里帮助你。只有当类(在本例中为CategoryDataProvider)具有默认构造函数。在更复杂的情况下,此方法可能需要您进行大量准备和初始化,以恢复该类。
new CategoryDataProvider<Row<DatabaseItem>>().getClass()