Informação de tipo genérico existe em tempo de compilação e é apagada no bytecode, onde um List de String é só um List com casts inseridos pelo compilador. Então você não pode checar instanceof contra um tipo parametrizado, criar um array de um parâmetro de tipo, nem sobrecarregar dois métodos que diferem apenas pelo argumento genérico. O compilador adiciona bridge methods para manter o polimorfismo funcionando, e casts unchecked podem causar heap pollution.
Por que os entrevistadores perguntam isso
Isso explica uma família inteira de erros de compilação confusos, então o entrevistador quer ver que você entende o mecanismo em vez de contorná lo no feeling. Citar wildcards com limites e a regra producer extends consumer super mostra que você sabe desenhar uma API genérica, não só consumir uma. Também aparece sempre que alguém precisa do tipo real em runtime, por exemplo num deserializador.
Como estruturar sua resposta
- Defina erasure e o que o bytecode realmente contém.
- Liste as restrições concretas que ele causa.
- Explique a regra dos wildcards para assinaturas flexíveis.
- Diga como você recupera informação de tipo em runtime quando precisa.
Exemplo de resposta
Generics são um recurso de tempo de compilação. Depois de compilar, um List de String é só um List, com o compilador tendo inserido os casts, e foi isso que manteve generics retrocompatíveis. As consequências visíveis são que eu não consigo perguntar se algo é instância de um tipo parametrizado, não consigo instanciar um array de um parâmetro de tipo sem um cast unchecked, e não consigo sobrecarregar um método com dois argumentos genéricos diferentes porque os dois apagam para a mesma assinatura. É também por isso que um aviso de cast unchecked importa: uma lista com tipo errado pode guardar o elemento errado e falhar depois num cast sem relação, o que é heap pollution e é genuinamente chato de rastrear. Quando eu desenho uma API eu uso wildcards com limites para deixá la usável, seguindo a regra producer extends consumer super, então um método que lê de uma coleção recebe um wildcard estendendo o tipo. Quando eu realmente preciso do tipo em runtime, por exemplo para dizer a uma biblioteca JSON no que desserializar, eu passo um objeto class ou uso uma type reference que captura o parâmetro por meio de uma subclasse anônima, já que o argumento de tipo numa classe é retido na assinatura.
Vai encarar essa entrevista em breve? O GhostPilot escuta a sua chamada ao vivo, identifica a pergunta no instante em que ela é feita e coloca uma resposta estruturada na sua tela em tempo real. Teste na sua próxima entrevista simulada ou pegue um Session Pass de $29, sem assinatura, para a hora da verdade.
Veja como funcionaPerguntas de acompanhamento que você pode esperar
- O que a regra producer extends consumer super significa na prática?
- Por que o compilador gera bridge methods?
- Como uma type reference captura um tipo genérico apesar do erasure?
Mais perguntas para Desenvolvedor Java
Seu entrevistador vai fazer a própria versão desta. Cole a descrição real da vaga no Question Predictor gratuito e receba as 20 perguntas que essa vaga tem mais chance de fazer, com o que cada uma está de fato sondando.
Prever minhas perguntas