有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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) 个答案

  1. # 1 楼答案

    ? extends EntityBase意味着它可能被限制为一个子类型,但你不知道是什么子类型。这意味着编译器无法确定您传递的对象实际上是正确的类型

    假设您有一对名为FooBar的类,它们都扩展了EntityBase。如果renderer变量是GenericRenderer<? extends EntityBase>,这意味着它引用的对象可以是GenericRenderer<Foo>,也可以是GenericRenderer<Bar>。编译器不知道是哪个,而且它可能因实体而异

    因此,当您调用draw时,您已经将entityBase引用转换为一个特定类型,如FooBar,但编译器无法确定它是正确的类。您可能试图将Foo传递给实际上是Renderer<Bar>的渲染器,反之亦然。这就是为什么你会出错? extends EntityBase并不意味着“接受EntityBase的任何子类”,它意味着“可能被限制为一个我们不知道的单个子类”

    我怀疑您的基本设计与Java泛型的工作方式不太兼容:如果您有一个Map,其值为GenericRenderer<? extends EntityBase>,这意味着您计划有一些GenericRenderer<Foo>,一些是GenericRenderer<Bar>,等等。但是在编译时没有关于每个渲染器需要哪种类型的实体的可用信息,因此编译器无法检查您是否将正确类型的实体传递给每个渲染器

    您可能需要将地图的值类型更改为GenericRenderer<EntityBase>,并在每个渲染器的draw方法中放置一个强制转换,以检查(在运行时)是否传递了正确类型的实体。或者,想出一个设计,不涉及在一个集合中混合不同类型的渲染器