Java Kotlin泛型-递归泛型-强制转换已擦除类型的实例失败
当我迭代精灵列表并检查它们是否实现UsesObjectPool时,由于类型擦除,我遇到了以下问题:Java Kotlin泛型-递归泛型-强制转换已擦除类型的实例失败,java,android,kotlin,generics,Java,Android,Kotlin,Generics,当我迭代精灵列表并检查它们是否实现UsesObjectPool时,由于类型擦除,我遇到了以下问题: *如果我尝试检查其类型,我会得到: 无法检查已擦除类型的实例:UsesObjectPool if(使用对象池) { it.objectPool.releaseObject(it) } 如果我用通配符*来检查,它会说: “必需参数Nothing,找到Sprite和UsesObjectPool: if(使用对象池) { it.objectPool.releaseObject(it) }
*如果我尝试检查其类型,我会得到: 无法检查已擦除类型的实例:UsesObjectPool
if(使用对象池)
{
it.objectPool.releaseObject(it)
}
- 如果我用通配符*来检查,它会说:
if(使用对象池)
{
it.objectPool.releaseObject(it)
}
*如果我将其转换为UsesObjectPool,我会得到: 类型参数不在其范围内。应为: 已找到UsesObjectPool:Sprite
if(使用对象池)
{
(它作为UsesObjectPool.objectPool.releaseObject(it)使用)
}
泛型类和接口:
接口UsesObjectPool,其中T:UsesObjectPool,T:Sprite
{
val对象池:BaseObjectPool
}
抽象类BaseObjectPool,其中T:UsesObjectPool,T:Sprite
{
fun releaseObject(实例:T)
{
//实施
}
}
这里的问题是,您实际上并不是说T
应该是实现类型(在某些语言中称为Self
)。就Kotlin编译器而言,T
可以是实现UsesObjectPool
的任何其他类型。这就是为什么不能将它
传递给releaseObject
以下是一个例子:
class EvilObjectPool<T>: BaseObjectPool<T>() where T : UsesObjectPool<T>, T : Sprite
class Implementation : Sprite(), UsesObjectPool<Implementation> {
override val objectPool: BaseObjectPool<Implementation>
get() = EvilObjectPool()
}
class EvilImplementation : Sprite(), UsesObjectPool<Implementation> {
override val objectPool: BaseObjectPool<Implementation>
get() = EvilObjectPool()
}
class-objectpool:BaseObjectPool()其中T:UsesObjectPool,T:Sprite
类实现:Sprite(),UsesObjectPool{
覆盖val对象池:BaseObjectPool
get()=对象池()
}
类实现:Sprite(),UsesObjectPool{
覆盖val对象池:BaseObjectPool
get()=对象池()
}
请注意,这是可以编译的。一般来说,作为人类,我们认识到这种“自绑定泛型”模式,并且永远不会编写类似于的东西,但编译器不知道:(
现在假设it
是evillimplementation
it.objectPool.releaseObject
将接受实现
,但您正在给它一个evillimplementation
无论如何,我认为您需要重新考虑您的设计,因为Kotlin不像在其他一些语言中那样支持Self
另请参见。有趣而又可笑。现在我不知道该如何处理新设计。如果您有任何想法或建议,并且愿意将其添加到您的答案中,我们将不胜感激。@DeveloperKurt我想说,这里的信息太少了。例如,每种类型都是用于什么的,它们的作用是什么y表示?为什么releaseObject
应该接受T
?我建议问一个包含更多上下文的新问题,特别是关于如何重新设计模型的问题。UsesObjectPool接口用于区分由对象池而不是垃圾收集器创建和发布的精灵类型。要为了能够释放它们,精灵类型的对象池对其精灵字段和对象池字段都进行操作。我个人的意见是,在精灵
中添加一个释放如果需要
方法。我开始认为这可能更适合于SoftwareEngineering.SE或因此…@DeveloperKurtI在考虑你的答案,我认为对T是什么存在误解。T是SPRITE_类型。它不会扩展BaseObjectPool,其他ObjectPool也不会有自己的泛型类型,它们只会将SPRITE类型传递给BaseObjectPool。
if(it is UsesObjectPool<*>)
{
it.objectPool.releaseObject(it)
}
if(it is UsesObjectPool<*>)
{
(it as UsesObjectPool<Sprite>).objectPool.releaseObject(it)
}
interface UsesObjectPool<T> where T :UsesObjectPool<T>, T : Sprite
{
val objectPool: BaseObjectPool<T>
}
abstract class BaseObjectPool<T> where T : UsesObjectPool<T>, T : Sprite
{
fun releaseObject(instance: T)
{
//Implementation
}
}
class EvilObjectPool<T>: BaseObjectPool<T>() where T : UsesObjectPool<T>, T : Sprite
class Implementation : Sprite(), UsesObjectPool<Implementation> {
override val objectPool: BaseObjectPool<Implementation>
get() = EvilObjectPool()
}
class EvilImplementation : Sprite(), UsesObjectPool<Implementation> {
override val objectPool: BaseObjectPool<Implementation>
get() = EvilObjectPool()
}