Reputation: 680
Suppose you have this variable :
Class<? extends AssetKey<?>> assetKeyClass;
Then I can only set assetKeyClass
to a subclass type of AssetKey
. Is there a way to do that plus allowing the AssetKey
class type itself?
Like this :
// Subclass
assetKeyClass = TextureKey.class;
// Class
assetKeyClass = AssetKey.class;
EDIT : Forgot to show some class code :
public class AssetKey<T> {
// ...
}
public class TextureKey extends AssetKey<Texture> {
// ...
}
Upvotes: 2
Views: 2153
Reputation: 122489
An extends
(or super
) bound always includes the bound itself.
The problem in your case is that a class literal, like AssetKey.class
, always has the type Class
parameterized by the non-parameterized form of that class. So AssetKey.class
has type Class<AssetKey>
. And Class<AssetKey>
is not a subtype of Class<? extends AssetKey<?>>
because the raw type AssetKey
is not a subtype of wildcard-parameterized type AssetKey<?>
. (According to Java rules, the raw and parameterized versions of a type are not subtypes of each other.)
On the other hand, TextureKey.class
has class Class<TextureKey>
, which is a subtype of Class<? extends AssetKey<?>>
, because the type TextureKey
(a non-generic class) is declared to be a subtype of AssetKey<Texture>
, which is a subtype of AssetKey<?>
.
If you drop the wildcard, and just declare it as Class<? extends AssetKey> assetKeyClass;
, it will work because AssetKey
is a subtype of AssetKey
, and thus Class<AssetKey>
is a subtype of Class<? extends AssetKey>
.
Upvotes: 3
Reputation: 680
As Johannes Kuhn commented, the answer is to remove the wild card so that it's :
Class<? extends AssetKey>.
Now I only need to know why it works.
Upvotes: 1
Reputation: 404
Usage with extends
Class<? extends AssetKey> assetKeyClass;
// Subclass
assetKeyClass = TextureKey.class;
// Class
assetKeyClass = AssetKey.class;
Usage with super
Class<? super TextureKey> assetKeyClass ;
// Subclass
assetKeyClass = TextureKey.class;
// Class
assetKeyClass = AssetKey.class;
Upvotes: 0