简体   繁体   English

从类转换对象以适合通用

[英]Casting Object From Class To Fit Generic

I have a Map that receives a Class<? extends EntityBase> 我有一个接收Class<? extends EntityBase>的地图Class<? extends EntityBase> Class<? extends EntityBase> and gives a GenericRenderer<? extends EntityBase> Class<? extends EntityBase>并给出GenericRenderer<? extends EntityBase> GenericRenderer<? extends EntityBase> . GenericRenderer<? extends EntityBase> Inside the GenericRenderer<? extends EntityBase> GenericRenderer<? extends EntityBase>里面GenericRenderer<? extends EntityBase> GenericRenderer<? extends EntityBase> , there's a method called draw that takes a SpriteBatch and an object that extends EntityBase (since the GenericRenderer is holding <? extends EntityBase> as the generic). GenericRenderer<? extends EntityBase> ,有一个名为draw的方法,它接受一个SpriteBatch和一个extends EntityBase的对象(因为GenericRenderer持有<? extends EntityBase>作为泛型)。

I'm using the map to hold the renderers for all of my entities, but when I call the draw method, Eclipse shows this error: 我正在使用地图来保存所有实体的渲染器,但是当我调用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) GenericRenderer类型中的方法绘制(SpriteBatch,捕获#3-of?extends EntityBase)不适用于参数(SpriteBatch,捕获#4-of?extends EntityBase)

Here is the code I use to iterate through my entities, cast them to EntityBase, grab their renderer, and run them through it: 这是我用来遍历我的实体的代码,将它们转换为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));
    }
}

The ? extends EntityBase ? extends EntityBase ? extends EntityBase means that it might be restricted to a subtype, but you don't know what subtype. ? extends EntityBase意味着它可能仅限于子类型,但您不知道哪个子类型。 That means the compiler can't be sure that the object you're passing is actually of the correct type. 这意味着编译器无法确定您传递的对象实际上是否为正确的类型。

Imagine that you have a pair of classes named Foo and Bar that both extend EntityBase . 想象一下,你有一对名为FooBar的类都扩展了EntityBase If your renderer variable is a GenericRenderer<? extends EntityBase> 如果你的renderer变量是GenericRenderer<? extends EntityBase> GenericRenderer<? extends EntityBase> , that means the object it refers to could be a GenericRenderer<Foo> , or it could be a GenericRenderer<Bar> . GenericRenderer<? extends EntityBase> ,这意味着它引用的对象可以是GenericRenderer<Foo> ,也可以是GenericRenderer<Bar> The compiler doesn't know which, and it could vary from entity to entity. 编译器不知道哪个,它可能因实体而异。

So when you call draw , you've cast your entityBase reference to a specific type like Foo or Bar , but the compiler can't determine that it's the right class. 因此,当您调用draw ,您已将您的entityBase引用转换为特定类型,如FooBar ,但编译器无法确定它是否为正确的类。 You might be trying to pass a Foo to a renderer that's actually a Renderer<Bar> , or vice versa. 您可能正在尝试将Foo传递给实际上是Renderer<Bar>Renderer<Bar> ,反之亦然。 That's why you get the error. 这就是你得到错误的原因。 ? extends EntityBase ? extends EntityBase doesn't mean "accepts any subclass of EntityBase ", it means "might be restricted to a single subclass that we don't know". ? extends EntityBase并不意味着“接受EntityBase任何子类”,它意味着“可能仅限于我们不知道的单个子类”。

I suspect your basic design isn't really compatible with how Java's generics work: if you have a Map whose values are GenericRenderer<? extends EntityBase> 我怀疑你的基本设计与Java的泛型工作方式并不完全兼容:如果你有一个Map值为GenericRenderer<? extends EntityBase> GenericRenderer<? extends EntityBase> , that means you plan to have some values that are GenericRenderer<Foo> , some that are GenericRenderer<Bar> , and so on. GenericRenderer<? extends EntityBase> ,这意味着你计划有一些GenericRenderer<Foo> ,一些是GenericRenderer<Bar> ,依此类推。 But there's no information available at compile time about which type of entity each renderer needs, so the compiler can't check that you're passing the correct type of entity to each renderer. 但是在编译时没有关于每个渲染器需要哪种类型的实体的信息,因此编译器无法检查您是否将正确类型的实体传递给每个渲染器。

You might need to change your map's value type to GenericRenderer<EntityBase> and put a cast in each renderer's draw method to check (at runtime) that the correct type of entity was passed. 您可能需要将地图的值类型更改为GenericRenderer<EntityBase>并在每个渲染器的draw方法中放置一个GenericRenderer<EntityBase> ,以检查(在运行时)是否传递了正确的实体类型。 Alternatively, come up with a design that doesn't involve mixing different types of renderers in a single collection. 或者,提出一种不涉及在单个集合中混合不同类型的渲染器的设计。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM