Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/188.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Kotlin泛型-递归泛型-强制转换已擦除类型的实例失败_Java_Android_Kotlin_Generics - Fatal编程技术网

Java Kotlin泛型-递归泛型-强制转换已擦除类型的实例失败

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时,由于类型擦除,我遇到了以下问题:

*如果我尝试检查其类型,我会得到:

无法检查已擦除类型的实例:UsesObjectPool

if(使用对象池)
{
it.objectPool.releaseObject(it)
}


  • 如果我用通配符*来检查,它会说:
“必需参数Nothing,找到Sprite和UsesObjectPool:

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()

}