Annotations em parâmetros de método genéricos não são obtidas

3 respostas
Ataxexe

Galera, estou fazendo um proxy para parâmetros de métodos e me deparei com um problema que explico abaixo.

A minha interface é uma interface genérica:

public interface Interf<E> {
 void foo(<E> param);
}

E eu consigo pegar as anotações dos parâmetros deste método na classe que implementar essa interface.

Até aí tudo bem, eu simplesmente vejo a anotação e faço alguma coisa conforme o tipo dela.

O problema vem quando eu crio as classes, eu criei uma classe sem utilizar a tipagem genérica e outra utilizando-a.

public class Class1 implements Interf {
 void foo(@Annot Object param){}
}

public class Class2 implements Interf<String> {
 void foo(@Annot String param){}
}

O problema é que as anotações dos parâmetros somente são retornadas quando a classe não utiliza Generics. Se a classe utilizar Generics ele consegue o método via reflexão mas o método getParameterAnnotations não me retorna nenhuma anotação.

Alguém já passou por este problema e conseguiu solucionar??

[EDITADO]
Acabei de fazer mais testes aqui e descobri que para a reflexão eu tenho dois métodos na classe genérica: um com a assinatura normal e outro com a assinatura "genérica" (utiliza os tipos genéricos declarados).

Pelo bytecode eu vi que o método sem os tipos genéricos serve de ponte para o outro, a VM apenas faz o cast dos parâmetros para os tipos declarados no outro método.

Acho que vou ter algumas dores de cabeça pra solucionar isso... Vai ser divertido!!
[/EDITADO]

3 Respostas

victorwss

generics + reflection = problemas

O type erasure fode a vida dos desenvolvedores nestes casos.

Ataxexe

É, eu consegui resolver, mas não ficou nada elegante.

Basicamente eu testo se o método é um bridge e, caso seja, eu varro todos os métodos da classe buscando o método com os mesmos argumentos compatíveis com os argumentos do bridge (o tipo de retorno também).

As vezes eu penso se realmente foi uma boa idéia da Sun manter a VM o mais compatível possível com as versões anteriores quando implementaram o Generics. Só o fato de não sabermos qual é o tipo genérico de um objeto já faz uma falta desgraçada.

Nesse ponto eu considero felizes os programadores C#…

victorwss

Ataxexe:
É, eu consegui resolver, mas não ficou nada elegante.

Basicamente eu testo se o método é um bridge e, caso seja, eu varro todos os métodos da classe buscando o método com os mesmos argumentos compatíveis com os argumentos do bridge (o tipo de retorno também).

As vezes eu penso se realmente foi uma boa idéia da Sun manter a VM o mais compatível possível com as versões anteriores quando implementaram o Generics. Só o fato de não sabermos qual é o tipo genérico de um objeto já faz uma falta desgraçada.

Nesse ponto eu considero felizes os programadores C#…

Pois é. O generics só não saiu antes por causa de problemas de compatibilidade. No java 7 querem fazer um novo generics por conta dos problemas que eles tem.

Criado 17 de julho de 2008
Ultima resposta 17 de jul. de 2008
Respostas 3
Participantes 2