Nivelamento Java: Entendendo Generics

Os generics foram introduzidos no Java 5 para fornecer tipagem forte às coleções e algoritmos. Os generics permitem que classes, interfaces e métodos possam trabalhar com diferentes tipos de dados de maneira segura e genérica.

O que são Generics?

Os generics permitem que classes, interfaces e métodos possam ser parametrizados por tipo. Isso significa que ao invés de operar em objetos do tipo Object, você pode especificar o tipo concreto com o qual deseja trabalhar.

Por exemplo, a interface List em Java trabalha com objetos do tipo Object:

List minhaLista = new ArrayList();
minhaLista.add("texto");
minhaLista.add(123);

Isso permite adicionar qualquer objeto à lista, o que não é muito seguro. Usando generics, podemos especificar o tipo da lista:

List<String> minhaLista = new ArrayList<>();
minhaLista.add("texto"); // ok
minhaLista.add(123); // erro de compilação!

Agora a lista só aceita strings, o que torna o código mais seguro.

Vantagens dos Generics

As principais vantagens dos generics são:

  • Tipo seguro - Detecta erros em tempo de compilação ao invés de falhar em tempo de execução.

  • Evita casts desnecessários - Remove a necessidade de realizar conversões entre tipos.

  • Reutilização de código - Permite escrever algoritmos e estruturas de dados genéricos que funcionam com qualquer tipo de dado.

Tipos de Generics

Existem dois tipos principais de generics:

Classes Genéricas

Definem placeholders para tipos nas declarações de classe:

public class Caixa<T> {

  private T coisa;

  public void set(T coisa) {
    this.coisa = coisa;
  }

  public T get() {
    return coisa;
  }
}

Podemos instanciar essa classe para diferentes tipos:

Caixa<String> caixaStr = new Caixa<>();
caixaStr.set("Olá");

Caixa<Integer> caixaInt = new Caixa<>();
caixaInt.set(123);

Métodos Genéricos

Permitem passar tipos como parâmetros para métodos:

public static <T> void imprimeArray(T[] array) {
  for(T item : array) {
    System.out.println(item);
  }
}

Pode ser chamado para qualquer tipo de array:

Integer[] intArray = { 1, 2, 3 };
imprimeArray(intArray);

String[] strArray = {"Olá", "Mundo"};
imprimeArray(strArray);

Wildcards

Os wildcards em Java, também conhecidos como wildcards genéricos, permitem que tipos genéricos sejam parametrizados de maneira flexível. Eles são representados pelo símbolo "?".

Os wildcards podem ser usados nas seguintes situações:

Wildcard sem restrições

O wildcard sem restrições, representado por "?", corresponde a qualquer tipo. Por exemplo:

List<?> myList = new ArrayList<>();

Neste caso, myList pode conter objetos de qualquer tipo. Porém, só é possível adicionar null a essa lista e pegar objetos de modo genérico Object.

Wildcard com limite superior

O wildcard com limite superior, representado por "? extends Type", corresponde ao tipo especificado Type ou a qualquer subtipo dele. Por exemplo:

List<? extends Number> myList = new ArrayList<Integer>();

Neste caso, myList só pode conter Number ou subtipos de Number, como Integer, Double, etc. É possível adicionar null e obter objetos de modo genérico como Number.

Wildcard com limite inferior

O wildcard com limite inferior, representado por "? super Type", corresponde ao tipo especificado Type ou a qualquer supertipo dele. Por exemplo:

List<? super Number> myList = new ArrayList<Object>();

Agora myList pode conter Number ou qualquer supertipo, como Object. É possível adicionar Number ou subtipos e obter objetos de modo genérico Object.

Exemplos de uso

  • Método que aceita qualquer tipo de lista:
public static void printList(List<?> list) {
  for(Object elem: list){
    System.out.print(elem + " ");
  }
}
  • Método que aceita lista de Number ou subtipos:
public static double sumOfList(List<? extends Number> list) {
  double sum = 0;
  for(Number num: list){
    sum += num.doubleValue();
  }
  return sum;
}
  • Método que aceita lista de Number ou supertipos:
public static void addNumbers(List<? super Number> list) {
  list.add(1);
  list.add(1.5);
  list.add(2L);
}

Os wildcards fornecem flexibilidade e reuso para código que trabalha com generics em Java. Eles permitem que um método opere em uma ampla gama de tipos relacionados.

Considerações Finais

Os generics adicionam segurança e flexibilidade às APIs Java. Eles permitem reaproveitar algoritmos e estruturas de dados para qualquer tipo de objeto.

Para entender mais a fundo os generics, vale a pena estudar as documentações e explorar os recursos disponíveis na linguagem Java. Com um bom domínio dos generics, você pode escrever APIs mais robustas e genéricas.

Referências

0
Subscribe to my newsletter

Read articles from 𝗥𝗔𝗙𝗔𝗘𝗟𝗩𝗜𝗘𝗜𝗥𝗔.🅳🅴🆅 directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

𝗥𝗔𝗙𝗔𝗘𝗟𝗩𝗜𝗘𝗜𝗥𝗔.🅳🅴🆅
𝗥𝗔𝗙𝗔𝗘𝗟𝗩𝗜𝗘𝗜𝗥𝗔.🅳🅴🆅

Sou Desenvolvedor Java apaixonado por essa linguagem de programação que me permitiu explorar e dominar os fundamentos do desenvolvimento de software. Minha jornada como engenheiro de software Java começou com a curiosidade por entender como os sistemas funcionam por baixo dos panos, levando-me a mergulhar profundamente no mundo da programação. Ao longo dos anos, desenvolvi uma habilidade excepcional em escrever código limpo, eficiente e seguro, utilizando as melhores práticas de design e arquitetura de software. Minha especialização em Java me permitiu trabalhar em uma variedade de projetos, desde aplicações web até sistemas de processamento de dados complexos. Além de minha experiência prática, tenho uma forte formação acadêmica em ciência da computação, o que me proporcionou uma base sólida em algoritmos, estruturas de dados e sistemas operacionais. Essa combinação de educação e experiência me permite abordar problemas complexos de maneira criativa e eficaz. No meu tempo livre, gosto de contribuir para a comunidade de desenvolvedores, compartilhando conhecimento e insights através de artigos de blog, tutoriais e palestras. Acredito que o compartilhamento de conhecimento é uma das melhores maneiras de aprender e crescer como profissional. Se você está procurando um desenvolvedor Java dedicado, com uma paixão por tecnologia e uma forte base em Java, estou aqui para ajudar. Entre em contato para discutir como posso contribuir para seus projetos de software.