Genéricos: como implementar

Neste módulo veremos:

Utilizando genéricos

Vejamos agora como implementar uma pilha usando recursos de generecidade de objetos, ou seja, uma pilha que pode armazenar diversos tipos de objetos.

Eis o código que implementa uma pilha:

/** EPilha.java
 * pilha de tipo generico
 * @author EESR baseado em Deitel e Deitel
 */
public class EPilha<E> {
    private final int size;
    private int topo;
    private E[] info;

    public EPilha (int tam) {
	if (tam>0)
	    size=tam;
	else 
	    size=10;
	topo=-1; //pilha vazia
	//observe a coersao de tipo
	info = (E[]) new Object[size];
    }

    public EPilha() {
	this(10);
    }

    public void push (E valor) {
	if (topo == size-1) //pilha cheia
	    throw new PilhaCheiaExcecao();
	info[++ topo] = valor;
    }

    public E pop() {
	if (topo==-1) //pilha vazia
	    throw new PilhaVaziaExcecao();
	return info[topo--];
    }
}//EPilha

No entanto, vimos que este código depende das classes de exceções que vêm logo abaixo:

/** PilhaCheiaExcecao.java
 * based on Deitel e Deitel
 */
public class PilhaCheiaExcecao extends RuntimeException {
    public PilhaCheiaExcecao(){
	super("Pilha cheia.");
    }
}

e mais...

/** PilhaVaziaExcecao.java
 * based on Deitel e Deitel
 */
public class PilhaVaziaExcecao extends RuntimeException {
    public PilhaVaziaExcecao(){
	super("Pilha vazia.");
    }
}

Reparem que quando compilamos a classe EPilha.java podemos receber a seguinte mensagem:

Note: EPilha.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
e, seguindo a opção e compilando com Xlint vemos uma mensagem de alerta justamente para a linha de coerção de tipo, do tipo mais amplo Object para um genérico. O que o compilaldor quer nos dizer é que não é garantida o objeto pilha nunca receberá outros tipos além de E, o que poderia gerear erros de execução.

Agora um pequeno teste para verificar o funcionamento desta pilha genérica.

/** TestEPilha.java
 */

public class TestEPilha {
    private int[] inteiros = {5,6,7,8,9,10};
    private double[] duplos = {5.5, 6.6, 7.7, 8.8, 9.9, 10.1};
    private EPilha<Integer> pInteira;
    private EPilha<Double> pDupla;

    public TestEPilha () {

	pInteira = new EPilha<Integer>();
	pDupla = new EPilha<Double>();

	for (int x: inteiros) {
	    pInteira.push(x);
	}

	try {
	    int ret;
	    while (true) {
		ret = pInteira.pop();
		System.out.println(ret);
	    }
	}
	catch (PilhaVaziaExcecao falha) {
	    System.err.println();
	}

	for (double x: duplos) {
	    pDupla.push(x);
	}

	try {
	    double ret;
	    while (true) {
		ret = pDupla.pop();
		System.out.println(ret);
	    }
	}
	catch (PilhaVaziaExcecao falha) {
	    System.err.println();
	}

    }//TestEPilha

    public static void main (String args[]) {
	TestEPilha tst = new TestEPilha();
    }
}

E a saída deste primeiro teste seria assim:

10
9
8
7
6
5

10.1
9.9
8.8
7.7
6.6
5.5
Última modificação feita em: 18 de novembro de 2008
Evandro Eduardo Seron Ruiz, PhD (evandro at usp ponto br)