English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Tutorial Básico de Java

Controle de fluxo Java

Java Array

Java Orientação a Objetos (I)

Java Orientação a Objetos (II)

Java Orientação a Objetos (III)

Tratamento de Exceções Java

Java Lista (List)

Java Fila (Queue)

Mapa Java

Conjunto Java

Java Entrada/Saída (I/O)

Reader do Java/Writer

Outros tópicos do Java

Generics Java

No Java,GenéricoAjuda a criar classes, interfaces e métodos que podem ser usados com objetos (dados) de diferentes tipos. Portanto, permite que reusemos nosso código.

Nota:Significa:GenéricoOs generics não se aplicam aos tipos básicos (int, float, char, etc.).

Como usar generics no Java

Para entender como usarGenéricoPodemos usar classes do Java Collection Framework no ArrayList.

A classe ArrayList é um exemplo de classe genérica. Podemos usar ArrayList para armazenar qualquer tipo de dados. Por exemplo

import java.util.ArrayList;
class Main {
   public static void main(String[] args) {
      //Criar uma lista de arrays para armazenar dados de Integer
      ArrayList<Integer> list1 = new ArrayList<>();
      list1.add(4);
      list1.add(5);
      System.out.println("ArrayList de Integer: ") + list1);
      //Criar uma lista de arrays para armazenar dados de String
      ArrayList<String> list2 = new ArrayList<>();
      list2.add("Four");
      list2.add("Five");
      System.out.println("ArrayList de String: ") + list2);
      //Criar uma lista de array para armazenar dados do tipo Double
      ArrayList<Double> list3 = new ArrayList<>();
      list3.add(4.5);
      list3.add(6.5);
      System.out.println("ArrayList de Double:") + list3);
   }
}

Saída

ArrayList de Integer: [4, 5]
ArrayList de String: [Four, Five]
ArrayList de Double: [4.5, 6.5]

No exemplo acima, usamos a mesma classe ArrayList para armazenar elementos do tipo Integer, String e Double. Devido aGenericos Java, isso é possível.

Aqui, note esta linha,

ArrayList<Integer> list1 = new ArrayList<>();

Usamos Integer entre colchetes <> aqui. O colchete <> é chamado deParâmetros de tipo.

O parâmetro type é usado para especificar o tipo de objeto (dados) para o qual a classe ou método genérico é aplicável.

Criar classe genérica

Agora que sabemos como os genéricos funcionam no Java, vamos ver como criar nossa própria classe genérica.

Exemplo: criar classe genérica

class Main {
  public static void main(String[] args) {
    //Inicializar a classe genérica com dados de inteiro
    GenericsClass<Integer> intObj = new GenericsClass<>(5);
    System.out.println("Classe genérica retorna:") + intObj.getData());
    //Inicializar a classe genérica com dados de string
    GenericsClass<String> stringObj = new GenericsClass<>("Java Programming");
    System.out.println("Classe genérica retorna:") + stringObj.getData());
  }
}
class GenericsClass<T> {
  //Variável do tipo T
  private T data;
  public GenericsClass(T data) {
    this.data = data;
  }
  //Método que retorna uma variável do tipo T
  public T getData() {
    return this.data;
  }
}

Saída

Classe genérica retorna: 5
Classe genérica retorna: Java Programing

No exemplo acima, criamos uma classe genérica chamada GenericsClass. Esta classe pode ser usada para manipular qualquer tipo de dados.

class GenericsClass<T> {...}

Aqui, T representaParâmetros de tipoDentro da classe Main, criamos os objetos GenericsClass chamados intObj e stringObj.

  • Ao criar intObj, o parâmetro de tipo T é substituído por Integer. Isso significa que intObj usa GenericsClass para lidar com dados de inteiro.

  • Ao criar stringObj, o parâmetro de tipo T é substituído por String. Isso significa que stringObj usa GenericsClass para lidar com dados de string.

Criar método generics

Da mesma forma que podemos criar classes generics no Java, também podemos criar nossos próprios métodos generics.

Exemplo: Criar método generics

class Main {
  public static void main(String[] args) {
    //Inicializar a classe com Integer
    DemoClass demo = new DemoClass();
    demo.<String>genericMethod("Java Programming");
  }
}
class DemoClass {
  //Métodos generics
  public <T> void genericsMethod(T data) {
    System.out.println("Este é um método generics.");
    System.out.println("Os dados passados para o método são "); + data);
  }
}

Saída

Este é um método generics.
Os dados passados para o método são: Java Programming

No exemplo acima, criamos um método generics chamado genericsMethod dentro de uma classe comum (DemoClass).

public <T> void genericMethod(T data) {...}

Aqui, o parâmetro de tipo <T> é inserido após o modificador (public) e antes do tipo de retorno (void).

Podemos chamar o método generics colocando o tipo real <String> antes dos parênteses do nome do método.

demo.<String>genericMethod("Java Programming");

Atenção:Na maioria dos casos, podemos omitir o parâmetro de tipo ao chamar o método generics. Isso porque o compilador pode usar o valor passado ao método para coincidir com o parâmetro de tipo. Por exemplo,

demo.genericsMethod("Java Programming");

de tipo limitado

Normalmente,Parâmetro de tipopode aceitar qualquer tipo de dados (exceto tipos primitivos). Mas, se quisermos usar o generics apenas para alguns tipos específicos (por exemplo, aceitar dados de tipo número), podemos usar tipos bounded.

Usamos a palavra-chave extends. Por exemplo,

<T extends A>

Isso significa que T pode aceitar apenas tipos de dados que sejam subtipos de A.

Exemplo: Tipos Bounded

class GenericsClass<T extends Number> {
  public void display() {}}
    System.out.println("This is a bounded type generics class.");
  }
}
class Main {
  public static void main(String[] args) {
    //Criar um objeto GenericsClass
    GenericsClass<String> obj = new GenericsClass<>();
  }
}

No exemplo acima, criamos umde tipo limitadoda classe genérica. Aqui, note a expressão

<T extends Number>

Isso significa que T pode usar apenas tipos de dados subtipos de Number (Integer, Double, etc.).

Mas, já criamos um objeto da classe genérica usando String. É por isso que, quando executamos o programa, obtemos o seguinte erro.

GenericsClass<String> obj = new GenericsClass<>();
                                                 ^
    motivo: a variável de inferência T tem limites incompatíveis
      restrições de igualdade: String
      limites inferiores: Number
  onde T é um tipo-variável:
    T extends Number declarado na classe GenericsClass

Vantagens dos genéricos do Java

1. Reutilização de código

GenéricoPermite-nos escrever código que se aplica a diferentes tipos de dados. Por exemplo:

public <T> void genericsMethod(T data) {...}

Aqui, criamos um método genérico. Este método pode ser usado para operar com dados de inteiros, strings, etc.

2. Verificação de tipo no tempo de compilação

GenéricoParâmetro de tipoFornecer informações sobre o tipo de dados usado no código genérico.

Portanto, qualquer erro pode ser identificado no tempo de compilação, o que é mais fácil de corrigir do que um erro no tempo de execução. Por exemplo:

//Sem uso de genéricos
NormalClass list = new NormalClass();
//Chamando o método da classe NormalClass
list.display("String");

No código acima, temos uma classe comum. Chamamos o método display() da classe chamada NormalClass, passando dados de string.

Aqui, o compilador não sabe se o valor passado como parâmetro está correto. Mas, vamos ver o que acontece se usarmos uma classe genérica.

//Uso de generics
GenericsClass<Integer> list = new GenericsClass<>();
//Chame o método da classe GenericsClass
list2.display("String");
No código acima, temos uma classe genérica. Aqui, o parâmetro de tipo indica que a classe está manipulando dados do tipo Integer.
Portanto, quando dados de string são passados como parâmetro, o compilador gera um erro.

3.Uso de generics com coleções

A estrutura de coleções utiliza o conceito de generics do Java. Por exemplo:

// Crie uma ArrayList de tipo string
ArrayList<String> list1 = new ArrayList<>();
// Crie uma ArrayList de tipo inteiro
ArrayList<Integer> list2 = new ArrayList<>();

No exemplo acima, usamos a mesma classe ArrayList para manipular diferentes tipos de dados.

Como ArrayList, outras coleções (LinkedList, Queue, Maps, etc.) também são genéricas no Java.