Class X{
Class<B> object;
public setObject( Class<B> a ){....}
}
Interface B{}
Interface C extends B {}
I instantiate X like this,
X x = new X();
x.setObject( C.class );
When i build the code it complains required Class<B>
found Class<C>
. Since C extends B, can i not use C.class? If so can some one explain why?
I i do the same thing using Spring`s XML based bean creating it works just fine. The bean definition would be
<bean id="dummy" class="X">
<property name"object" value="C">
</bean>
This works just fine. Im not getting why instantiating in java would fail.
The same way a List<Dog>
is not assignable to List<Animal>
, Class<C>
is not assignable to Class<B>
, even if C
is a subtype of B
.
Using XML configuration, you are ignoring all type safety rules. It's as if every parametrized type usage was erased, as if you were using raw types. A Class<C>
becomes a Class
and a Class<B>
becomes a Class
. A Class
is assignable to a Class
.
It's normal that setObject(Class<B>)
won't take a Class<C>
parameter, for the same reason that someMethod(List<Object>)
won't take a List<Integer>
parameter: List<Integer>
is not a subclass of List<Object>
, even though Integer
is a subclass of Object
.
To make it work, you can change your method signature to this:
public setObject(Class<? extends B> a) {....}
this is not valid Java code
It works because there is type erasure done for parameters <>
the java bytecode looks exactly the same as the one for
class X{
Class object;
public void setObject( Class a ){....}
}
interface B{}
interface C extends B {}
It looses the type checks information, it is only used at compile time.
You can use this to make it work in the code:
class X{
Class<? extends B> object;
public void setObject( Class<? extends B> a ){....}
}
interface B{}
interface C extends B {}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.