java从类转换对象以适应泛型
我有一个接收Class<? extends EntityBase>
并给出GenericRenderer<? extends EntityBase>
的映射。在GenericRenderer<? extends EntityBase>
内部,有一个名为draw
的方法,它接受一个SpriteBatch
和一个extends EntityBase
的对象(因为GenericRenderer将<? extends EntityBase>
作为泛型)
我使用map来保存所有实体的渲染器,但是当我调用draw
方法时,Eclipse显示了以下错误:
The method draw(SpriteBatch, capture#3-of ? extends EntityBase) in the type GenericRenderer is not applicable for the arguments (SpriteBatch, capture#4-of ? extends EntityBase)
下面是我用来迭代实体、将它们转换到EntityBase、获取它们的渲染器并运行它们的代码:
for(Entity entity : gameStage.getEntityEngine().getEntities()) {
if(entity instanceof EntityBase) {
EntityBase entityBase = (EntityBase) entity;
GenericRenderer<? extends EntityBase> renderer =
Betley.instance.renderer.getRenderer(entityBase.getClass());
renderer.draw(batch, entityBase.getClass().cast(entityBase));
}
}
# 1 楼答案
? extends EntityBase
意味着它可能被限制为一个子类型,但你不知道是什么子类型。这意味着编译器无法确定您传递的对象实际上是正确的类型假设您有一对名为
Foo
和Bar
的类,它们都扩展了EntityBase
。如果renderer
变量是GenericRenderer<? extends EntityBase>
,这意味着它引用的对象可以是GenericRenderer<Foo>
,也可以是GenericRenderer<Bar>
。编译器不知道是哪个,而且它可能因实体而异因此,当您调用
draw
时,您已经将entityBase
引用转换为一个特定类型,如Foo
或Bar
,但编译器无法确定它是正确的类。您可能试图将Foo
传递给实际上是Renderer<Bar>
的渲染器,反之亦然。这就是为什么你会出错? extends EntityBase
并不意味着“接受EntityBase
的任何子类”,它意味着“可能被限制为一个我们不知道的单个子类”我怀疑您的基本设计与Java泛型的工作方式不太兼容:如果您有一个
Map
,其值为GenericRenderer<? extends EntityBase>
,这意味着您计划有一些GenericRenderer<Foo>
,一些是GenericRenderer<Bar>
,等等。但是在编译时没有关于每个渲染器需要哪种类型的实体的可用信息,因此编译器无法检查您是否将正确类型的实体传递给每个渲染器您可能需要将地图的值类型更改为
GenericRenderer<EntityBase>
,并在每个渲染器的draw
方法中放置一个强制转换,以检查(在运行时)是否传递了正确类型的实体。或者,想出一个设计,不涉及在一个集合中混合不同类型的渲染器