Criação de array genérico em Java

Siddharth Swami 12 outubro 2023
  1. Use Arrays de Objetos para Criar Arrays Genéricos em Java
  2. Use a classe Reflection para criar matrizes genéricas em Java
Criação de array genérico em Java

um array pode ser definida como uma coleção de itens armazenados em locais de memória contíguos. um array genérica é independente de qualquer tipo de dados e cujo tipo de informação é avaliada em tempo de execução.

No entanto, o Java não permite que o array seja genérico porque, em Java, os arrays contêm informações associadas a seus componentes, e essas informações em tempo de execução são usadas para alocar memória.

Podemos simular estruturas genéricas semelhantes a array usando array de objetos e recurso de classe de reflexão em Java. Discutiremos esses métodos a seguir.

Use Arrays de Objetos para Criar Arrays Genéricos em Java

um array de objetos de tipo como um membro é usada nesta abordagem. Usamos as funções get() e set() para ler e definir os elementos do array.

O programa a seguir demonstra o uso de um array de objeto para criar um array genérica.

import java.util.Arrays;

class Generic_Array<E> {
  private final Object[] obj_array; // object array
  public final int length;
  // class constructor
  public Generic_Array(int len) {
    // new object array
    obj_array = new Object[len];
    this.len = len;
  }
  // get new object array(obj_array[i])
  E get(int j) {
    @SuppressWarnings("unchecked") final E e = (E) object_array[j];
    return e;
  }
  // set e at new object array(obj_array[i])
  void set(int j, E e) {
    object_array[j] = e;
  }
  @Override
  public String toString() {
    return Arrays.toString(object_array);
  }
}
class Main {
  public static void main(String[] args) {
    final int len = 5;
    // creating an integer array
    Generic_Array<Integer> int_Array = new Generic_Array(len);
    System.out.print("Generic Array <Integer>:"
        + " ");
    for (int i = 2; i < len; i++) int_Array.set(i, i * 2);
    System.out.println(int_Array);
    // creating a string array
    Generic_Array<String> str_Array = new Generic_Array(len);
    System.out.print("Generic Array <String>:"
        + " ");
    for (int i = 0; i < len; i++) str_Array.set(i, String.valueOf((char) (i + 97)));
    System.out.println(str_Array);
  }
}

Resultado:

Generic Array <Integer>: [2, 4, 6, 8, 10]
Generic Array <String>: [a, b, c, d, e]

Use a classe Reflection para criar matrizes genéricas em Java

Nesse tipo de abordagem, uma classe de reflexão é usada para criar um array genérica cujo tipo será conhecido apenas em tempo de execução.

A única diferença entre a abordagem anterior e essa abordagem é que a classe de reflexão é usada como o próprio construtor. Depois disso, a classe de reflexão inicia um array de objeto passando explicitamente os dados para a classe construtora.

O programa a seguir demonstra o uso de reflexão para criar um array genérica.

import java.util.Arrays;
class Generic_Array<E> {
  private final E[] objArray;
  public final int length;
  // constructor class
  public Generic_Array(Class<E> dataType, int length) {
    // creatting a new array with the specified data type and length at runtime using reflection
    // method.
    this.objArray = (E[]) java.lang.reflect.Array.newInstance(dataType, len);
    this.len = len;
  }
  // get element at obj_Array[i]
  E get(int i) {
    return obj_Array[i];
  }
  // assign e to obj_Array[i]
  void set(int i, E e) {
    obj_Array[i] = e;
  }
  @Override
  public String toString() {
    return Arrays.toString(obj_Array);
  }
}
class Main {
  public static void main(String[] args) {
    final int len = 5;
    // create array with Integer as data type
    Generic_Array<Integer> int_Array = new Generic_Array(Integer.class, len);
    System.out.print("Generic Array<Int>:"
        + " ");
    for (int i = 2; i < len; i++) int_Array.set(i, i + 10);
    System.out.println(int_Array);
    // create an array with String as data type
    Generic_Array<String> str_Array = new Generic_Array(String.class, len);
    System.out.print("Generic Array<Str>:"
        + " ");
    for (int i = 0; i < len; i++) str_Array.set(i, String.valueOf((char) (i + 65)));
    System.out.println(str_Array);
  }
}

Resultado:

Generic Array<Int>: [12, 13, 14, 15, 16]
Generic Array<Str>: [A, B, C, D, E]

O array genérico não pode fornecer segurança de tipo, a menos que uma verificação de tipo ou mecanismo explícito seja implementado, pois as classes genéricas são desconhecidas para aquele tipo de argumento que criaram em tempo de execução.

Se quisermos ter um array precisa sem nenhuma segurança discutida acima usando genéricos, isso pode ser feito conforme mostrado abaixo.

import java.lang.reflect.Array;

public class Gen_Set<E> {
  private E[] x;

  public Gen_Set(Class<E[]> cla, int len) {
    x = cla.cast(Array.newInstance(cla.getComponentType(), len));
  }

  public static void main(String[] args) {
    Gen_Set<String> foo = new Gen_Set<String>(String[].class, 1);
    String[] bar = foo.x;
    foo.x[0] = "xyzzy";
    String baz = foo.a[0];
  }
}

Este código não dará nenhum aviso em tempo de compilação, e podemos ver que na classe principal, o tipo de instância de Gen_Set declarado pode ser atribuído o mesmo ax para um array desse tipo, ou seja, array e os valores do array são tipos incorretos.

Artigo relacionado - Java Array