Classe Abstrata - Instanciar atributos do tipo T

4 respostas
E

Olá… Gostaria de Saber se é possível instanciar um atributo do tipo que foi passado na classe abstrata, deste modo:

public abstract class ClasseAbstrata<T extends OutraClasse, ID extends Serializable> {
    protected T entidade;
    
    public ClasseAbstrata()
        entidade = // nova Classe do tipo T
    }
}

Desde já obrigado!

4 Respostas

L

Não da porque os tipos genericos não “existem” depois de compilados, é algo que existe só para ajudar a programar hehe mesmo porque, fazendo T = new T(), vc naum saberia se o tipo T tem um construtor sem parâmetros dessa forma.

Vc pode fazer dessa forma:

class Base
{
   public Base ()
   {

   }
}

public class Teste<T extends Base>
{

   public T t;

   public Teste (Class<T> clazz) throws InstantiationException, IllegalAccessException
   {
      t = clazz.newInstance();
   }

   public T getT()
   {
      return t;
   }

}

Obriga ter algo a mais no codigo, passar o tipo generic por parâmetro, a vantagem eh vc ter um getT() personalizado (varia de acordo com o tipo generic), mas mesmo assim a classe do tipo T precisa ter um construtor sem parâmetros (dai o porque de colocar ela como sendo algo extends Base, ja que Base tem esse contrutor)

E

Muito obrigado luBS, era isso mesmo que eu precisava!

Valeu! :grin:

L

Sua outra duvida la é a mesma dessa, uma sugestão é vc fazer algo parecido com isso

abstract class Pai<T>
{
   public T t;

   public Pai (Class<T> clazz)
   {
      try
      {
         t = clazz.newInstance();
      }
      catch (InstantiationException e)
      {
         e.printStackTrace();
      }
      catch (IllegalAccessException e)
      {
         e.printStackTrace();
      }
   }

   protected T getT()
   {
      return t;
   }

   abstract void fazAlgo();
}

class FilhaString extends Pai<String>
{

   public FilhaString ()
   {
      // ele te obriga a criar esse construtor
      super(String.class);
   }

   @Override
   void fazAlgo()
   {
      System.out.println(getT().getClass().getName());
   }
}

class FilhaGenerica<T> extends Pai<T>
{

   public FilhaGenerica (Class<T> clazz)
   {
      // ele te obriga a criar esse construtor
      super(clazz);
   }

   @Override
   void fazAlgo()
   {
      System.out.println(getT().getClass().getName());
   }
}

public class Teste
{
   public static void main(String[] args)
   {
      new FilhaString().fazAlgo();
      new FilhaGenerica<String>(String.class).fazAlgo();
      new FilhaGenerica<Teste>(Teste.class).fazAlgo();
   }
}

Da mesma forma, como estou usando newInstance o tipo generico T precisa ter um construtor sem parâmetros (por exemplo não funciona para Integer pois Integer não tem esse construtor, da para fazer o mesmo esquema de usar uma extends class Base que tem esse construtor para funcionar e usar um padrão chamado Adapter para adaptar outras classes que não extendam Base). Nesse exemplo, a classe FilhaString é mais simples de usar, mas ela só serve para String (fixo no construtor dela), já FilhaGenerica serve para tudo, inclusive criar uma filha igual a filha string.

E

Ótima explicação!

Muito obrigado!

Criado 16 de abril de 2007
Ultima resposta 16 de abr. de 2007
Respostas 4
Participantes 2