Création de tableaux génériques en Java

Siddharth Swami 12 octobre 2023
  1. Utiliser des tableaux d’objets pour créer des tableaux génériques en Java
  2. Utiliser la classe Reflection pour créer des tableaux génériques en Java
Création de tableaux génériques en Java

Un tableau peut être défini comme une collection d’éléments stockés dans des emplacements de mémoire contigus. Un tableau générique est indépendant de tout type de données et dont le type d’information est évalué au moment de l’exécution.

Cependant, Java ne permet pas au tableau d’être générique car, en Java, les tableaux contiennent des informations associées à leurs composants, et ces informations au moment de l’exécution sont utilisées pour allouer de la mémoire.

Nous pouvons simuler des structures génériques de type tableau à l’aide de la fonction de tableau d’objets et de classe de réflexion en Java. Nous discuterons de ces méthodes ci-dessous.

Utiliser des tableaux d’objets pour créer des tableaux génériques en Java

Un tableau d’objets de type en tant que membre est utilisé dans cette approche. Nous utilisons les fonctions get() et set() pour lire et définir les éléments du tableau.

Le programme suivant montre l’utilisation d’un tableau d’objets pour créer un tableau générique.

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

Production:

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

Utiliser la classe Reflection pour créer des tableaux génériques en Java

Dans ce type d’approche, une classe de réflexion est utilisée pour créer un tableau générique dont le type ne sera connu qu’à l’exécution.

La seule différence entre l’approche précédente et cette approche est que la classe de réflexion est utilisée comme le constructeur lui-même. Après cela, la classe de réflexion initie un tableau d’objets en passant explicitement les données à la classe constructeur.

Le programme suivant montre l’utilisation de la réflexion pour créer un tableau générique.

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

Production:

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

Le tableau générique ne peut pas fournir une sécurité de type à moins qu’une vérification de type ou un mécanisme explicite ne soit implémenté car les classes génériques sont inconnues de ce type d’argument qu’elles ont créé lors de l’exécution.

Si nous voulons avoir un tableau précis sans aucune sécurité discutée ci-dessus en utilisant des génériques, cela peut être fait comme indiqué ci-dessous.

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

Ce code ne donnera aucun avertissement au moment de la compilation, et nous pouvons voir que dans la classe principale, le type d’instance de Gen_Set déclaré peut être affecté de la même manière au x d’un tableau de ce type, ce qui signifie à la fois tableau et les valeurs du tableau sont de types incorrects.

Article connexe - Java Array