É uma boa prática para substituir classe com Class estende Object> para avisos evitar?
Pergunta
Em um bando o' lugares no meu código, eu tenho algo parecido com isto:
public Class mySpecialMethod() {
return MySpecialClass.class;
}
que faz com que o aviso
Class é um tipo cru. As referências a tipo genérico classe deve ser parametrizado.
Mas, se eu substituir
Class
com
Class<? extends Object>
o aviso vai embora.
É este simples ok prática, ou poderia causar problemas mais tarde?
Solução
É a coisa correta a fazer somente se não há realmente nenhuma classe base comum ou interface que as necessidades objeto de classe para representar.
Além disso Class<?>
é efetivamente o mesmo que Class<? extends Object>
.
Outras dicas
Sim, é totalmente certo.
É uma exigência que você especificar o tipo. E se você não pode, você tem que especificar o curinga.
Além disso leitura: Java Specification Língua: Tipos parametrizados
Dependendo do que você deseja alcançar, você pode ser ainda mais preciso:
public Class<MySpecialClass> mySpecialMethod() {
return MySpecialClass.class;
}
Não é realmente um programador Java aqui, mas ler alguns bons artigos sobre os genéricos.
Sim, você deve adicionar um pouco de curinga ou o tipo exato (Class<MySpecialClass>
) para adicionar segurança. A razão é que Class é um genérico. Então, Class<Bar>
e Class<Foo>
são os mesmos apagamento depois de seu parâmetro de tipo genérico. Eles todos se tornam Class
, o chamado tipo cru. Isso apagamento acontece quando compilar. Alguns exemplos para ilustrar este onde o compilador ajuda você com fundição automática (manipulação de exceção omitido por brevidade):
class Mine { }
class Vara {
public static void main(String... args) {
{ // works. translated to Mine m = (Mine) c.newInstance();
Class<Mine> c = Mine.class;
Mine m = c.newInstance();
}
{ // doesn't work. need a cast: Mine m = (Mine) c.newInstance();
Class c = Mine.class; // also Class<?> or Class<? extends Object>
Object o = c.newInstance(); // but this works. pointing to a Mine
Mine m = (Mine) c.newInstance(); // needs a manual cast
}
}
}
Dizendo Class<?>
(eo Class<? extends Object>
equivalente), você diz ao compilador que você realmente queria uma classe cujo T
é objeto, e não usado acidentalmente o tipo cru. Mas isso não vai acrescentar quaisquer moldes de conveniência. Tudo o que os genéricos fazer é inserir moldes automáticos para você, para elenco de Object
para o tipo de destino. Os genéricos são o mesmo se usado com tipo U ou com o tipo T em tempo de execução por razões de compatibilidade com versões mais antigas do Java.