I have some Guice binding code using generics that compiles and functions fine from Eclipse's compiler, but not from the Java (command-line) compiler. I upgraded to the latest (1.7.0_01) Java SDK but still get the following error.
[error] ...\BindCategorySelectorActivity.java:42: error: inconvertible types
[error] (Class extends ListAdapterDataProvider>>) CategoryDataProvider.class);
[error] ^
[error] required: Class extends ListAdapterDataProvider>>
[error] found: Class
[error] 1 error
[error] {file:/.../compile:compile: javac returned nonzero exit code
Relevant code:
public interface Category extends DatabaseItem {}
public class CategoryDataProvider implements
ListAdapterDataProvider> {}
public class BindListViewHandlerWithSpecificProvider extends AbstractModule {
public BindListViewHandlerWithSpecificProvider(
Class extends ListAdapterDataProvider>>
dataProviderClass) {}
}
@SuppressWarnings("unchecked")
// Error happens here:
final BindListViewHandlerWithSpecificProvider
bindListViewHandlerWithSpecificProvider =
new BindListViewHandlerWithSpecificProvider(
(Class extends ListAdapterDataProvider>>)
CategoryDataProvider.class);
解决方案
Do yourself a favor and do an upcast followed by a downcast:
Class<...> foo = (Class<...>)(Object)MyClass.class;
The issue is that CDP.class is of type Class, CDP being a raw type. While a parameterized type C is the subtype of the raw type C (§4.10.2), the inverse is not true: C is not a subtype of C. This only appears to be true due to unchecked conversion (§5.1.9). This is causing your issue: You expect CDP to "extend" (as in the upper bound of Class extends ...>) LADP>. This is not the case because type argument containment (§4.5.1.1) is defined over subtyping and does not consider unchecked conversion.
(Or to cut to the chase: javac has got this one right.)