Creazione di array generici in Java

Siddharth Swami 12 ottobre 2023
  1. Usa array di oggetti per creare array generici in Java
  2. Usa la classe Reflection per creare array generici in Java
Creazione di array generici in Java

Un array può essere definito come una raccolta di elementi archiviati in locazioni di memoria contigue. Un array generico è indipendente da qualsiasi tipo di dati e il cui tipo di informazioni viene valutato in fase di esecuzione.

Tuttavia, Java non consente che l’array sia generico perché, in Java, gli array contengono informazioni associate ai loro componenti e queste informazioni in fase di esecuzione vengono utilizzate per allocare memoria.

Possiamo simulare strutture generiche simili a array utilizzando array di oggetti e funzionalità di classe di riflessione in Java. Discuteremo questi metodi di seguito.

Usa array di oggetti per creare array generici in Java

In questo approccio viene utilizzata una matrice di oggetti di tipo come membro. Usiamo le funzioni get() e set() per leggere e impostare gli elementi dell’array.

Il seguente programma mostra l’uso di un array di oggetti per creare un array generico.

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);
  }
}

Produzione:

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

Usa la classe Reflection per creare array generici in Java

In questo tipo di approccio, viene utilizzata una classe di riflessione per creare un array generico il cui tipo sarà noto solo in fase di esecuzione.

L’unica differenza tra l’approccio precedente e questo approccio è che la classe di riflessione viene utilizzata come costruttore stesso. Successivamente, la classe reflection avvia un array di oggetti passando esplicitamente i dati alla classe costruttore.

Il seguente programma dimostra l’uso della riflessione per creare un array generico.

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);
  }
}

Produzione:

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

L’array generico non può fornire l’indipendenza dai tipi a meno che non venga implementato un controllo del tipo o un meccanismo esplicito poiché le classi generiche sono sconosciute al tipo di argomento creato in fase di esecuzione.

Se vogliamo avere un array preciso senza alcuna sicurezza discussa sopra usando i generici, può essere fatto come mostrato di seguito.

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];
  }
}

Questo codice non darà avvisi in fase di compilazione, e possiamo vedere che nella classe principale, il tipo di istanza di Gen_Set dichiarato può essere assegnato lo stesso alla x a un array di quel tipo, il che significa sia array che i valori dell’array sono tipi non corretti.

Articolo correlato - Java Array