Java - Genéricos
Seria bom se pudéssemos escrever um único método de classificação que pudesse classificar os elementos em um array Integer, um array String ou um array de qualquer tipo que suporte ordenação.
Java Genérico métodos e classes genéricas permitem que os programadores especifiquem, com uma única declaração de método, um conjunto de métodos relacionados ou com uma única declaração de classe, um conjunto de tipos relacionados, respectivamente.
Os genéricos também fornecem segurança de tipo em tempo de compilação que permite aos programadores capturar tipos inválidos em tempo de compilação.
Usando o conceito Java Generic, podemos escrever um método genérico para ordenar um array de objetos, então invocar o método genérico com arrays Integer, arrays Double, arrays String e assim por diante, para ordenar os elementos do array.
Métodos genéricos
Você pode escrever uma única declaração de método genérico que pode ser chamada com argumentos de diferentes tipos. Com base nos tipos de argumentos passados para o método genérico, o compilador trata cada chamada de método apropriadamente. A seguir estão as regras para definir Métodos Genéricos -
-
Todas as declarações de métodos genéricos têm uma seção de parâmetro de tipo delimitada por colchetes angulares () que precede o tipo de retorno do método ( no próximo exemplo).
-
Cada seção de parâmetro de tipo contém um ou mais parâmetros de tipo separados por vírgulas. Um parâmetro de tipo, também conhecido como variável de tipo, é um identificador que especifica um nome de tipo genérico.
-
Os parâmetros de tipo podem ser usados para declarar o tipo de retorno e atuar como espaços reservados para os tipos de argumentos passados para o método genérico, que são conhecidos como argumentos de tipo real.
-
O corpo de um método genérico é declarado como o de qualquer outro método. Observe que os parâmetros de tipo podem representar apenas tipos de referência, não tipos primitivos (como int, double e char).
Exemplo
O exemplo a seguir ilustra como podemos imprimir uma matriz de tipo diferente usando um único método genérico -
Demonstração ao vivo
public class GenericMethodTest { // generic method printArray public static < E > void printArray( E[] inputArray ) { // Display array elements for(E element : inputArray) { System.out.printf("%s ", element); } System.out.println(); } public static void main(String args[]) { // Create arrays of Integer, Double and Character Integer[] intArray = { 1, 2, 3, 4, 5 }; Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 }; Character[] charArray = { 'H', 'E', 'L', 'L', 'O' }; System.out.println("Array integerArray contains:"); printArray(intArray); // pass an Integer array System.out.println("\nArray doubleArray contains:"); printArray(doubleArray); // pass a Double array System.out.println("\nArray characterArray contains:"); printArray(charArray); // pass a Character array } }
Isso produzirá o seguinte resultado -
Saída
Array integerArray contains: 1 2 3 4 5 Array doubleArray contains: 1.1 2.2 3.3 4.4 Array characterArray contains: H E L L O
Parâmetros de tipo limitado
Pode haver momentos em que você desejará restringir os tipos de tipos que podem ser passados para um parâmetro de tipo. Por exemplo, um método que opera em números pode aceitar apenas instâncias de Number ou suas subclasses. É para isso que servem os parâmetros de tipo limitado.
Para declarar um parâmetro de tipo limitado, liste o nome do parâmetro de tipo, seguido pela palavra-chave extends, seguida por seu limite superior.
Exemplo
O exemplo a seguir ilustra como extends é usado em um sentido geral para significar "extends" (como em classes) ou "implements" (como em interfaces). Este exemplo é o método genérico para retornar o maior de três objetos comparáveis -
Demonstração ao vivo
public class MaximumTest { // determines the largest of three Comparable objects public static <T extends Comparable<T>> T maximum(T x, T y, T z) { T max = x; // assume x is initially the largest if(y.compareTo(max) > 0) { max = y; // y is the largest so far } if(z.compareTo(max) > 0) { max = z; // z is the largest now } return max; // returns the largest object } public static void main(String args[]) { System.out.printf("Max of %d, %d and %d is %d\n\n", 3, 4, 5, maximum( 3, 4, 5 )); System.out.printf("Max of %.1f,%.1f and %.1f is %.1f\n\n", 6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 )); System.out.printf("Max of %s, %s and %s is %s\n","pear", "apple", "orange", maximum("pear", "apple", "orange")); } }
Isso produzirá o seguinte resultado -
Saída
Max of 3, 4 and 5 is 5 Max of 6.6,8.8 and 7.7 is 8.8 Max of pear, apple and orange is pear
Aulas genéricas
Uma declaração de classe genérica se parece com uma declaração de classe não genérica, exceto que o nome da classe é seguido por uma seção de parâmetro de tipo.
Assim como nos métodos genéricos, a seção de parâmetro de tipo de uma classe genérica pode ter um ou mais parâmetros de tipo separados por vírgulas. Essas classes são conhecidas como classes parametrizadas ou tipos parametrizados porque aceitam um ou mais parâmetros.
Exemplo
O exemplo a seguir ilustra como podemos definir uma classe genérica -
Demonstração ao vivo
public class Box<T> { private T t; public void add(T t) { this.t = t; } public T get() { return t; } public static void main(String[] args) { Box<Integer> integerBox = new Box<Integer>(); Box<String> stringBox = new Box<String>(); integerBox.add(new Integer(10)); stringBox.add(new String("Hello World")); System.out.printf("Integer Value :%d\n\n", integerBox.get()); System.out.printf("String Value :%s\n", stringBox.get()); } }
Isso produzirá o seguinte resultado -
Saída
Integer Value :10 String Value :Hello World
Java