Pergunta

Eu tento converter um objeto para a minha classe de Ação, mas resulta em um aviso:

Type safety: Unchecked cast from Object to Action<ClientInterface>

Action<ClientInterface> action = null;
try {
 Object o = c.newInstance();
 if (o instanceof Action<?>) {
  action = (Action<ClientInterface>) o;
 } else {
  // TODO 2 Auto-generated catch block
  throw new InstantiationException();
 }
 [...]

Obrigado por qualquer ajuda

Foi útil?

Solução

Sim - esta é uma consequência natural de tipo de apagamento. Se o é realmente uma instância de Action<String> Isso não será pego pelo elenco - você só verá o problema quando tentar usá -lo, passando em um ClientInterface em vez de uma string.

Você pode se livrar do aviso usando:

@SuppressWarnings("unchecked")

Como anotação de funções, mas você não pode resolver facilmente o problema subjacente :(

Outras dicas

Como sempre, Jon Skeet está certo.

Para elaborar a parte não fácil de sua resposta:

Dado

class ClientAction implements Action<ClientInterface> {}

Você pode escrever:

Class<? extends Action<ClientInterface>> c = ClientAction.class;
Action<ClientInterface> action = c.newInstance();

Isso elimina o elenco e o aviso, ao preço de introduzir um tipo não genérico para que você possa usar .class para obter uma digitada suficientemente com precisão Class objeto.

O aviso significa que o compilador não pode garantir a segurança do tipo, mesmo que a fundição funcione bem em tempo de execução. Devido ao apagamento, em tempo de execução, o elenco é simplesmente um elenco à ação. É possível que a classe genérica subjacente não seja do tipo ClientInterface conforme o esperado. Nesse caso, o problema aparecerá mais tarde (talvez até muito mais tarde), como uma ClassCastException.

Neste caso específico, recomendo suprimir este aviso específico pela seguinte diretiva do compilador:

@SuppressWarnings("unchecked")

Não se preocupe. É porque o compilador Java não tem como saber, qual é o tipo real do objeto.

Você perdeu o tipo de informação, porque de apagamento (i.é., o parametrizada tipos foram apagadas), daí o aviso.Você não pode fazer nada sobre isso, e outras que limpar o código ao redor, de modo que os genéricos são usados com mais freqüência, assim você pode passar o tipo genérico de informação e evitar fundição em tudo.

Este é um abatido. É o elenco dinâmico em que o compilador não tem idéia do objeto real ao qual a referência está apontando.

Você recebe esse aviso porque o tipo de alvo do elenco Action<ClientInterface> é um Tipo parametrizado e o compilador não pode garantir que o tipo de objeto escalado seja do mesmo tipo.

Se você não deseja suprimir esse aviso e não se importa com o parâmetro de tipo, você pode alterar o código para isso usando cards selvagens:

Action<?> action = null;
try {
 Object o = c.newInstance();
 if (o instanceof Action<?>) {
  action = (Action<?>) o;
 } else {
  // TODO 2 Auto-generated catch block
  throw new InstantiationException();
 }
 [...]

Isso é muito mais seguro porque o instanceof Não posso verificar isso o é um objeto de Action<ClientInterface>, apenas verifique se o é um objeto de Action Como mais informações genéricas do tipo genérico serão apagado em tempo de execução.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top