Antes de procurar na minha estrutura de dados genérica o índice de um valor, gostaria de ver se até mesmo uma instância do tipo this
foi parametrizada.
Mas o Eclipse reclama quando faço isso:
@Override
public int indexOf(Object arg0) {
if (!(arg0 instanceof E)) {
return -1;
}
Esta é a mensagem de erro:
Não é possível executar instanceof check no parâmetro de tipo E. Use seu apagamento Object, pois as informações genéricas do tipo serão apagadas no tempo de execução
Qual é a melhor maneira de fazer isso?
java
generics
instanceof
typechecking
Nick Heiner
fonte
fonte
Class.isAssignableFrom
.Duas opções para verificação do tipo de tempo de execução com genéricos:
Opção 1 - Corrompa seu construtor
Vamos supor que você esteja substituindo indexOf (...) e deseje verificar o tipo apenas para desempenho, para economizar a iteração de toda a coleção.
Faça um construtor imundo como este:
Em seguida, você pode usar isAssignableFrom para verificar o tipo.
Cada vez que você instancia seu objeto, você precisa se repetir:
Você pode decidir que não vale a pena. Na implementação de ArrayList.indexOf (...) , eles não verificam se o tipo corresponde.
Opção 2 - Deixe falhar
Se você precisar usar um método abstrato que exija seu tipo desconhecido, tudo o que você realmente deseja é que o compilador pare de chorar sobre instanceof . Se você tem um método como este:
Você pode usá-lo assim:
Você está convertendo o objeto para T (seu tipo genérico), apenas para enganar o compilador. Seu elenco não faz nada em tempo de execução , mas você ainda receberá uma ClassCastException ao tentar passar o tipo errado de objeto para o seu método abstrato.
OBSERVAÇÃO 1: Se você estiver fazendo conversões adicionais não verificadas no seu método abstrato, suas ClassCastExceptions serão capturadas aqui. Isso pode ser bom ou ruim, então pense bem.
NOTA 2: Você recebe uma verificação nula gratuita ao usar instanceof . Como você não pode usá-lo, pode ser necessário verificar nulo com as próprias mãos.
fonte
Postagem antiga, mas uma maneira simples de fazer a verificação de instanceOf genérica.
fonte
Desde que sua classe estenda uma classe com um parâmetro genérico, você também pode obtê-lo em tempo de execução via reflexão e usá-lo para comparação, ou seja,
No caso acima, em tempo de execução, você obterá String.class de getParameterizedClass (), e ele fará cache, para que você não receba nenhuma sobrecarga de reflexão após várias verificações. Observe que você pode obter os outros tipos parametrizados por índice no método ParameterizedType.getActualTypeArguments ().
fonte
Eu tive o mesmo problema e aqui está a minha solução (muito humilde, @george: desta vez compilando E trabalhando ...).
Meu probem estava dentro de uma classe abstrata que implementa o Observer. O Observable aciona a atualização do método (...) com a classe Object que pode ser qualquer tipo de Object.
Eu só quero manipular objetos do tipo T
A solução é passar a classe para o construtor para poder comparar tipos em tempo de execução.
Para a implementação, basta passar a classe para o construtor
fonte
Ou você pode pegar uma tentativa fracassada de lançar em E eg.
fonte
Tecnicamente, você não precisa, esse é o ponto dos genéricos, para que você possa fazer a verificação do tipo de compilação:
mas o @Override pode ser um problema se você tiver uma hierarquia de classes. Caso contrário, veja a resposta de Yishai.
fonte
O tipo de tempo de execução do objeto é uma condição relativamente arbitrária para filtrar. Sugiro manter essa imundície longe de sua coleção. Isso é simplesmente conseguido ao delegar sua coleção a um filtro passado em uma construção.
fonte
Comparator
ou similar.)