Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

273
Visualizações
Kotlin Generics - recursive generic - casting the instance of erased type fails

When I iterate over a list of Sprites and check whether they implement UsesObjectPool or not, I am encountering these problems due to type erasure:

*If I try to check its type I get:

Cannot check for instance of erased type: UsesObjectPool

  if(it is UsesObjectPool<Sprite>)
        {
            it.objectPool.releaseObject(it)
        }



  • If I use the wildcard * to check, it says that:

"required parameter Nothing, found Sprite & UsesObjectPool:

  if(it is UsesObjectPool<*>)
            {
                it.objectPool.releaseObject(it)
            }



*If I cast the it to UsesObjectPool, I get:

Type argument is not within its bounds. Expected: UsesObjectPool Found: Sprite

 if(it is UsesObjectPool<*>)
            {
                (it as UsesObjectPool<Sprite>).objectPool.releaseObject(it)
            }



The generic class and interface:

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
       }
    }
over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

The problem here is that you are not actually saying that T should be the implementing type (known as Self in some languages). As far as the Kotlin compiler is concerned, T can be any other type that implements UsesObjectPool<T>. This is why you can't pass it to releaseObject.

Here is an example:

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

}

Notice that this compiles. Generally we as humans recognise this "self-bound generics" pattern, and will never write something like EvilImplementation, but the compiler doesn't know that :(

Now imagine that it is EvilImplementation. it.objectPool.releaseObject would accept an Implementation, but you are giving it an EvilImplementation!

Anyway, I think you'd need to re-think your design, since Kotlin does not support Self as in some other languages.

See also a similar problem in Java.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda