Generics e reflection

5 respostas
C

Olá pessoal!

Tenho uma classe mais ou menos assim:

public class XXX<T> implements III<T> {
  public T mmm() {
  
  }
}

Eu preciso, dentro do método mmm(), criar uma instância de T e popular alguns atributos, por meio de reflexão. Contudo, não estou conseguindo obter o Class do T para criar a instância e chamar seus métodos.

Como eu posso fazê-lo? Obrigado!

5 Respostas

L

Cara, há alguns dias eu comentei sobre isso no meu blog. Você pode ver a problemática e a solução que eu criei no link: http://objectzilla.wordpress.com/2007/09/16/nem-tudo-em-java-sao-flores/

Ok?

rmarin

Só conheço um modo de fazer isso, mas infelizmente você tem que ter na mão um objeto do tipo T.

@SuppressWarnings("unchecked")
    public T mmm(T t) throws InstantiationException, IllegalAccessException {
        T newInstance = (T) t.getClass().newInstance();
        return newInstance;
    }

Se preferir você pode receber pelo construtor. Algumas vezes utilizamos o recebimento do tipo através da classe dele, mais ou menos assim:

class XXX<T> implements III<T> {

    private Class<T> type;
    
    public XXX(Class<T> type) {
        this.type = type;
    }
    
    public T mmm(T t) throws InstantiationException, IllegalAccessException {
        T newInstance = type.newInstance();
        return newInstance;
    }
    
}
sergiotaborda

Leonardo3001:
Cara, há alguns dias eu comentei sobre isso no meu blog. Você pode ver a problemática e a solução que eu criei no link: http://objectzilla.wordpress.com/2007/09/16/nem-tudo-em-java-sao-flores/

Só um comentário

GenericBuilder<MyInterface> gb2 = new GenericBuilder<MyInterface>(MyInterface.class);

é redundante pq vc fez assim. Poderia ser

GenericBuilder<MyInterface> gb2 = GenericBuilder.getInstance(MyInterface.class);

O que já não é redundante e mostra exactamente o papel de GenericBuilder. Ser um abstract factory.

C

rmarin

Já tinha visto a abordagem de passar o tipo como parâmetro no construtor, contudo, fica bastante reduntante né?

XXX&lt;String&gt; x = new XXX&lt;String&gt;(String.class);

Mas pelo visto não há outra alternativa né?

Que coisa estranha, não esperava algo do tipo em generics :S

rmarin

Cara, eu ia falar que faço isso em DAOs genericos usando hibernate, quando resolvi dar uma pesquisada.

Encontrei isto.

Na loucura pra tentar implementar, descobri que é necessário que o tipo genérico seja passado em tempo de compilação, não vale fazer new X<Date>, você precisa ter uma subclasse com o tipo genérico pré-definido em tempo de compilação, como no código abaixo, mas pelo menos há uma maneira. :smiley:

// isto que eu chamo de "tipo genérico pré-definido em tempo de compilação"
public class Main extends X&lt;Date&gt; {

	public static void main(String[] args) throws InstantiationException, IllegalAccessException {
		new Main().teste();
	}

}

abstract class X&lt;T&gt; {

	private Class&lt;T&gt; c;

	public void teste() throws InstantiationException, IllegalAccessException {
		c = (Class&lt;T&gt;) ((ParameterizedType) this.getClass().getGenericSuperclass())
				.getActualTypeArguments()[0];
		T t = c.newInstance();
		System.out.println(t);
	}
}

Bom, agora é só decidir se vale a pena usar um código “rebuscado” desses ou não… :stuck_out_tongue:

Criado 18 de setembro de 2007
Ultima resposta 19 de set. de 2007
Respostas 5
Participantes 4