Guia Linguagem Java

Java Generics: Um guia completo sobre como utilizar

Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Para efetuar o download você precisa estar logado. Clique aqui para efetuar o login
Confirmar voto
0
 (1)  (0)

Neste artigo apresentaremos a codificação de alguns exemplos visando demonstrar a importância do uso de Generics para as nossas aplicações.

Atenção: esse artigo tem um vídeo complementar. Clique e assista!

De que se trata o artigo:

Neste artigo apresentaremos a codificação de alguns exemplos visando demonstrar a importância do uso de Generics para as nossas aplicações.

Em que situação o tema é útil:

Este tema é importante a todo desenvolvedor interessado em aprimorar o seu código, aumentando sua legibilidade e reusabilidade, isto é, facilitando sua compreensão e a possibilidade de utilizar o mesmo código em outras aplicações, respectivamente.

Resumo DevMan:

Este artigo demonstra como criar um sistema simples para gerenciar um estacionamento sem utilizar o recurso de Generics do Java. Durante o mesmo, conheceremos alguns riscos de seguir com esta decisão.

Em um projeto de software utilizamos, em média, apenas 20% do tempo em desenvolvimento, e os outros 80%, em manutenção. A ocorrência de erros é um dos principais motivos para a alteração de código, e, em alguns casos, até a sua reescrita. Nesse contexto, é importante a adoção de boas práticas de programação para a escrita de códigos legíveis e de fácil alteração, pois a ocorrência de bugs diminui na medida em que as aplicamos.

Para ajudar o desenvolvedor na adoção destas práticas, foi introduzido Generics na versão 5 da plataforma Java. Um recurso adicionado para fazer a verificação, em tempo de compilação, de tipos manipulados por uma classe. Como exemplo, podemos citar as classes da Collections API voltadas ao uso de conjuntos (List, Set e Map). Um dos motivos para a inclusão de Generics é a garantia de que pelo menos um tipo de objeto será relacionado a estas classes, deixando claro para o profissional com quais elementos ele está trabalhando em uma coleção. Por exemplo, podemos ter um objeto List gerenciando outros Double e outra coleção responsável por objetos Calendar. Ao programar desta maneira, evitamos o uso de uma única lista para ambos, tornando o código mais claro para o desenvolvedor.

Outro objetivo da inclusão de Generics é a redução de bugs em tempo de execução. Com ele, é possível a captura de erros na compilação, alertando o desenvolvedor sobre a ocorrência de exceções comuns, como uma ClassCastException. Consequentemente, fornece um meio para a escrita de um código mais seguro.

A reusabilidade também faz parte do recurso. Utilizando novamente uma classe da API de Collections como exemplo, podemos criar listas de String, outras de Integer e outras para qualquer classe. Desta forma, evitamos a escrita de código repetido e desnecessário.

Nesse cenário, o objetivo deste artigo é a apresentação de Generics ao desenvolvedor, listando todos os benefícios de sua utilização. Por meio de exemplos, os problemas que podem ser causados pelo não uso deste são apontados ao leitor. E no segundo artigo da minissérie, os mesmos exemplos serão apresentados, mas aplicando o novo conceito e explicitando porque este é a solução para as falhas decorrentes.

Desenvolvimento antes de Generics

Para demonstrar como é realizada a codificação sem o uso de Generics, vamos imaginar o seguinte cenário: precisamos criar uma lista para o armazenamento de objetos de um determinado tipo. Para esta finalidade, vamos trabalhar com o exemplo a seguir: em um estacionamento, há vagas para vários tipos de veículo, como Carros, Motocicletas e Ônibus. A representação destes modelos está no diagrama de classes da Figura 1.

Diagrama
de classes da UML representando o Estacionamento e seus respectivos tipos de
veículo

Figura 1. Diagrama de classes da UML representando o Estacionamento e seus respectivos tipos de veículo

As implementações destas classes, que originarão os objetos a serem armazenados no estabelecimento, encontram-se nas Listagens 1, 2, 3 e 4.

Listagem 1. Veiculo.java: representa um veículo.

package br.com.devmedia.javamagazine.generics.estacionamento.veiculos;

   
  public abstract class Veiculo {
   
    protected String nome;
    protected String marca;
    protected String cor;
         
    public Veiculo(String nome, String marca, String cor) {
     this.nome = nome;
     this.marca = marca;
     this.cor = cor; 
    }
               
    public abstract String listarDados();
   
   // métodos representando funcionalidades de um veículo
   // como ligar, desligar, acelera e frear 
    
    // setters e getters omitidos
  }

Listagem 2. Carro.java: representa um carro .

package br.com.devmedia.javamagazine.generics.estacionamento.veiculos;
   
  public class Carro extends Veiculo {
         
    public Carro(String nome, String marca, String cor) {
      super(nome, marca, cor);            
    }
   
    @Override
    public void listarDados() {
      return "Nome do carro: " + nome + "\nMarca: " + marca + "\nCor: " + cor;     
    }
   
   // métodos representando funcionalidades de um veículo
   // como ligar, desligar, acelerar e frear 
    
    // setters e getters omitidos
  }

Listagem 3. Motocicleta.java: representa uma motocicleta.

package br.com.devmedia.javamagazine.generics.estacionamento.veiculos;
   
  public class Motocicleta extends Veiculo {
   
    public Motocicleta(String nome, String marca, String cor) {
      super(nome, marca, cor);            
    }
   
    @Override
    public String listarDados() {
      return "Nome da motocicleta: " + nome + "\nMarca: " + marca + "\nCor: " + cor;     
    }
   
   // métodos representando funcionalidades de um veículo
   // como ligar, desligar, acelerar e frear 
    
    // setters e getters omitidos
  }

Listagem 4. Onibus.java: representa um ônibus.

package br.com.devmedia.javamagazine.generics.estacionamento.veiculos;
   
  public class Onibus extends Veiculo {
   
    public Onibus(String nome, String marca, String cor) {
      super(nome, marca, cor);
    }
   
    @Override
    public String listarDados() {
      return "Nome do onibus: " + nome + "\nMarca: " + marca + "\nCor: " + cor;    
    }
         
   // métodos representando funcionalidades de um veículo
   // como ligar, desligar, acelerar e frear 
   
    // setters e getters omitidos
  }

A Listagem 1 apresenta o código de uma classe abstrata para um veículo com os seus métodos e atributos representando aspectos do mundo real, como acelerar(), frear() e cor, respectivamente. Já as Listagens 2, 3 e 4 são referentes aos tipos específicos de automóveis que podem ser armazenados no estacionamento. Para a demonstração do artigo, apenas três tipos de veículo foram criados: Carro, Motocicleta e Onibus. Para facilitar a compreensão de Generics, métodos comuns a um veículo, como ligar() e acelerar(), não estão presentes nas listagens.

Para a representação do estacionamento e respectivo controle e gerenciamento dos veículos cadastrados, codificamos a Listagem 5. Métodos para adicionar novos veículos no local (adicionar()) e para a listagem dos mesmos (listarVeiculos()) estão nesta classe para mostrar suas principais funcionalidades e características. O atributo veiculos, declarado como um objeto do tipo List, refere-se aos veículos a serem armazenados no local.

Listagem 5. Estacionamento.java: representa o local de armazenamento de veículos.

package br.com.devmedia.javamagazine.generics.estacionamento.semgenerics;
   
  import java.util.ArrayList;
  import java.util.List;
  import br.com.devmedia.javamagazine.generics.estacionamento.veiculos.Veiculo;
   
  public class Estacionamento {
   
   private String nome;
   private String localizacao;
   
   //lista dos veículos a serem armazenados no local
   private List veiculos;
   
   public Estacionamento() {
    veiculos = new ArrayList();
   }
   
   public void adicionar(Object o) {
    veiculos.add(o);
    System.out.println("Adicionado ao estacionamento = " + o.toString() + "\n");
   }
   
   //lista os veículos armazenados no estacionamento
   public void listarVeiculos() {
    for (Object o: veiculos) {
     Veiculo veiculo = (Veiculo)o;
     System.out.println(veiculo.listarDados());
    }
   }
    
   //getters e setters default
   
  }
"

A exibição deste artigo foi interrompida :(
Este post está disponível para assinantes MVP

 
Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Receba nossas novidades
Ficou com alguma dúvida?