Classe Parametrizada evita casting?

11 respostas
E

Galera estou estudando pela apostila da caelum estrutura de dados. Em um determinado momento o autor dá um dica para eu criar uma classe parametrizada para evitar casting. O trecho segue abaixo. Se alguém puder me esclarecer eu agradeço.

// Inserindo uma String
lista.adiciona("Rafael");
// Fazendo um casting de String para Aluno. Erro de EXECUÇÃO.
Aluno aluno = (Aluno)lista.pega(0);

11 Respostas

B

Listas parametrizadas são aquelas do tipo:

List alunos = new ArrayList();

Dentro só vão conter objetos do tipo Aluno, checados em tempo de compilação.

Sem parametrizar, todos os objetos dentro são do tipo Object.

S
List<Aluno> list = new ArrayList<Aluno>();

list.add(new Aluno());

Aluno aluno = list.get(0);
E

Sim, mas a minha é que o autor coloca que por utilizar uma classe parametrizada eu não preciso fazer o casting.Tentei fazer essa classe parametrizada porém ele continua solicitando o casting:

VetorGenerico<Aluno> lista = new VetorGenerico<Aluno>();
		
		lista.adiciona(a1);
		lista.adiciona(a2);
		
		Aluno aluno1 = (Aluno)lista.pega(0); <------------
		Aluno aluno2 = (Aluno)lista.pega(1); <------------

Esse método lista.pega retorna um Object.

T

Qual é a declaração do método pega? Se ele retornar um Object (em vez de T) então ele realmente vai necessitar um cast.

Por favor, poste a declaração do seu método “pega”.

(Pega para mim, que sou um biólogo frustrado, é isso aqui:

alucardeck

se o metodo Pega… estiver retornando um objeto do tipo Aluno…
nao vai haver necessidade de fazer o cast…

mas tenho certeza q ele deve estar retornando um Object ou outra coisa =)

E

Questão de prova em galera…rs

Como falei ele está retornando um object. Olha só:

public Object pega(int posicao)
   {
      if (!this.posicaoOcupada(posicao))
      {
         throw new IllegalArgumentException("Posicao inválida");
      }

      return this.objects[posicao];
   }
T

E qual é a declaração da classe VetorGenericoAluno?

Se ela for algo parecido com:

public class VetorGenericoAluno<T> 
...

então a sua rotina “pega” tem de ser declarada mais ou menos assim:

public T pega(int posicao)
   {
      if (!this.posicaoOcupada(posicao))
      {
         throw new IllegalArgumentException("Posicao inválida");
      }

      return (T) this.objects[posicao]; // esta linha vai provocar um warning, mas você pode desconsiderá-lo.
   }
alucardeck

entao… ele deve retornar um Aluno… para evitar o casting na outra classe

public Aluno pega(int posicao)
   {
      if (!this.posicaoOcupada(posicao))
      {
         throw new IllegalArgumentException("Posicao inválida");
      }

      return this.objects[posicao];
   }

e o array da classe (cujo o nome é “objects[]”) deve ser um array de “Aluno”

q vai funcionar sem problemas e sem warnings

E
thingol:
E qual é a declaração da classe VetorGenericoAluno? Se ela for algo parecido com:
public class VetorGenericoAluno<T> 
...
então a sua rotina "pega" tem de ser declarada mais ou menos assim:
public T pega(int posicao)
   {
      if (!this.posicaoOcupada(posicao))
      {
         throw new IllegalArgumentException("Posicao inválida");
      }

      return (T) this.objects[posicao]; // esta linha vai provocar um warning, mas você pode desconsiderá-lo.
   }

Opa !!!! Deu certo, é isso mesmo ! O Eclipse solicitou para que eu colocasse isso :
@SuppressWarnings("unchecked")

Pode me explicar por que ele pede e se outra maneira dele não pedir ?

T

A explicação simples é que não é possível criar um array de T na versão atual de Generics do Java. Portanto, você cria um array de Object mesmo, e força o casting. O Java reclama mas “cala a boca” se você usar o tal de @SuppressWarnings.
Se você olhar o fonte de java.util.ArrayList, que tem um array de objetos como base, vai ver que ele tem exatamente o mesmo problema.

E

thingol:
A explicação simples é que não é possível criar um array de T na versão atual de Generics do Java. Portanto, você cria um array de Object mesmo, e força o casting. O Java reclama mas “cala a boca” se você usar o tal de @SuppressWarnings.
Se você olhar o fonte de java.util.ArrayList, que tem um array de objetos como base, vai ver que ele tem exatamente o mesmo problema.

Ok, entendido 100 %

Como ficou meu vetor generico:

public class VetorGenerico<T>
{
   private Object[] objects = new Object[3];
   private int totalDeobjects = 0;

   /**
    * DOCUMENT ME!
    *
    * @param object
    */
   public void adiciona(Object object)
   {
      this.garantaEspaco();
      this.objects[totalDeobjects] = object;
      totalDeobjects++;
   }

   /**
    * DOCUMENT ME!
    *
    * @param posicao
    * @param object
    */
   public void adiciona(int posicao, Object object)
   {
      this.garantaEspaco();

      if (!this.posicaoValida(posicao))
      {
         throw new IllegalArgumentException("Posicao inválida");
      }

      for (int i = this.totalDeobjects - 1; i >= posicao; i--)
      {
         this.objects[i + 1] = this.objects[i];
      }

      this.objects[posicao] = object;
      this.totalDeobjects++;
   }

   /**
    * DOCUMENT ME!
    *
    * @param object
    *
    * @return
    */
   public boolean contem(Object object)
   {
      for (int i = 0; i < this.totalDeobjects; i++)
      {
         if (object.equals(this.objects[i]))
         {
            return true;
         }
      }

      return false;
   }

   /**
    * DOCUMENT ME!
    *
    * @param posicao
    *
    * @return
    */
   @SuppressWarnings("unchecked")
   public T pega(int posicao)
   {
      if (!this.posicaoOcupada(posicao))
      {
         throw new IllegalArgumentException("Posicao inválida");
      }

      return (T) this.objects[posicao];
   }

   /**
    * DOCUMENT ME!
    *
    * @param posicao
    */
   public void remove(int posicao)
   {
      if (!this.posicaoPreenchida(posicao))
      {
         throw new IllegalArgumentException("Posicao inválida");
      }

      for (int i = posicao; i < (this.totalDeobjects - 1); i++)
      {
         this.objects[i] = this.objects[i + 1];
      }

      this.totalDeobjects--;
   }

   /**
    * DOCUMENT ME!
    *
    * @return
    */
   public int tamanho()
   {
      return this.totalDeobjects;
   }

   /**
    * DOCUMENT ME!
    *
    * @return
    */
   public String toString()
   {
      if (this.totalDeobjects == 0)
      {
         return "[]";
      }

      StringBuilder builder = new StringBuilder();
      builder.append("[");

      for (int i = 0; i < (this.totalDeobjects - 1); i++)
      {
         builder.append(this.objects[i]);
         builder.append(", ");
      }

      builder.append(this.objects[this.totalDeobjects - 1]);
      builder.append("]");

      return builder.toString();
   }

   /**
    * DOCUMENT ME!
    */
   private void garantaEspaco()
   {
      if (this.totalDeobjects == this.objects.length)
      {
         Object[] novaArray = new Object[this.objects.length * 2];

         for (int i = 0; i < this.objects.length; i++)
         {
            novaArray[i] = this.objects[i];
         }

         this.objects = novaArray;
      }
   }

   /**
    * DOCUMENT ME!
    *
    * @param posicao
    *
    * @return
    */
   private boolean posicaoOcupada(int posicao)
   {
      return (posicao >= 0) && (posicao < this.totalDeobjects);
   }

   /**
    * DOCUMENT ME!
    *
    * @param posicao
    *
    * @return
    */
   private boolean posicaoPreenchida(int posicao)
   {
      return (posicao >= 0) && (posicao < this.totalDeobjects);
   }

   /**
    * DOCUMENT ME!
    *
    * @param posicao
    *
    * @return
    */
   private boolean posicaoValida(int posicao)
   {
      return (posicao >= 0) && (posicao <= this.totalDeobjects) && (posicao < this.objects.length);
   }
}

Obrigadão a todos…

Criado 10 de junho de 2008
Ultima resposta 10 de jun. de 2008
Respostas 11
Participantes 5