Обобщения Java: подстановочный знак расширяет класс и включает этот класс - PullRequest
0 голосов
/ 21 мая 2018

Предположим, у вас есть эта переменная:

Class<? extends AssetKey<?>> assetKeyClass;

Тогда я могу установить для assetKeyClass только тип подкласса AssetKey.Есть ли способ сделать это плюс разрешение самого типа класса AssetKey?

Примерно так:

// Subclass
assetKeyClass = TextureKey.class;
// Class
assetKeyClass = AssetKey.class;

РЕДАКТИРОВАТЬ: Забыли показать какой-нибудь код класса:

public class AssetKey<T> {
// ...
}

public class TextureKey extends AssetKey<Texture> {
// ...
}

Ответы [ 3 ]

0 голосов
/ 21 мая 2018

Как прокомментировал Йоханнес Кун , ответ состоит в том, чтобы убрать подстановочный знак так:

Class<? extends AssetKey>.

Теперь мне нужно только знать, почему он работает.

0 голосов
/ 28 мая 2018

Граница extends (или super) всегда включает саму границу.

Проблема в вашем случае состоит в том, что литерал класса, такой как AssetKey.class, всегда имеет параметризованный тип Classпо непараметрической форме этого класса.Так что AssetKey.class имеет тип Class<AssetKey>Class<AssetKey> не является подтипом Class<? extends AssetKey<?>>, поскольку необработанный тип AssetKey не является подтипом параметризованного подстановочного знака типа AssetKey<?>.(Согласно правилам Java, необработанные и параметризованные версии типа не являются подтипами друг друга.)

С другой стороны, TextureKey.class имеет класс Class<TextureKey>, который равен подтип Class<? extends AssetKey<?>>, потому что тип TextureKey (неуниверсальный класс) объявляется как подтип AssetKey<Texture>, который является подтипом AssetKey<?>.

Если вы отброситеподстановочный знак, и просто объявить его как Class<? extends AssetKey> assetKeyClass;, он будет работать, потому что AssetKey является подтипом AssetKey, и, таким образом, Class<AssetKey> является подтипом Class<? extends AssetKey>.

0 голосов
/ 21 мая 2018

Использование с расширяется

Class<? extends AssetKey> assetKeyClass;

// Subclass
assetKeyClass = TextureKey.class;
// Class
assetKeyClass = AssetKey.class;

Использование с супер

Class<? super TextureKey> assetKeyClass ;

// Subclass
assetKeyClass = TextureKey.class;
// Class
assetKeyClass = AssetKey.class;
...