Génériques Java

Les génériques Java sont une nouvelle fonctionnalité introduite dans JDK 5. Les génériques fournissent un mécanisme de vérification de la sécurité de type à la compilation qui permet aux programmeurs de détecter les types illégaux au moment de la compilation.

L'essence des génériques réside dans les types paramétrés, c'est-à-dire que le type de données sur lequel on opère est spécifié comme paramètre.

Supposons que nous ayons une exigence comme celle-ci : écrire une méthode de tri qui peut trier des tableaux d'entiers, des tableaux de chaînes, ou même des tableaux de tout autre type. Comment cela peut-il être mis en œuvre ?

La réponse est d'utiliserles génériques Java。

En utilisant le concept des génériques Java, nous pouvons écrire une méthode générique pour trier un tableau d'objets. Ensuite, appelez cette méthode générique pour trier des tableaux d'entiers, des tableaux de nombres à virgule flottante, des tableaux de chaînes, etc.


Méthodes génériques

Vous pouvez écrire une méthode générique qui peut recevoir des paramètres de types différents lorsqu'elle est appelée. En fonction des types d'arguments passés à la méthode générique, le compilateur gère chaque appel de méthode de manière appropriée.

Voici les règles pour définir des méthodes génériques :

  • Toutes les déclarations de méthodes génériques ont une section de déclaration de paramètres de type (délimitée par des chevrons). Cette section de déclaration de paramètres de type apparaît avant le type de retour de la méthode (dans l'exemple ci-dessous, le<E>)。
  • Chaque section de déclaration de paramètre de type contient un ou plusieurs paramètres de type, séparés par des virgules. Un paramètre générique, également appelé variable de type, est un identifiant utilisé pour spécifier un nom de type générique.
  • Les paramètres de type peuvent être utilisés pour déclarer des types de retour et peuvent servir de substituts aux types de paramètres réels obtenus par la méthode générique.
  • La déclaration du corps d’une méthode générique est identique à celle des autres méthodes. Notez que les paramètres de type ne peuvent représenter que des types de référence, et non des types primitifs (tels queint、double、charetc.).

Marqueurs génériques en Java :

  • E- Élément (utilisé dans les collections, car les collections stockent des éléments)
  • T- Type (classe Java)
  • K- Clé
  • V- Valeur
  • N- Nombre (type numérique)
  • ?- représente un type Java indéterminé

Exemple

L’exemple suivant montre comment utiliser une méthode générique pour afficher des éléments de tableau de différents types :

Exemple

public class GenericMethodTest { //Méthode générique printArray public static < E > void printArray( E[] inputArray ) { //Affichage des éléments du tableau for ( E element : inputArray ){ System.out.printf( "%s ", element ); } System.out.println(); } public static void main( String args[] ) { //Création de tableaux de différents types : Integer, Double et 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( "Les éléments du tableau Integer sont :" ); printArray( intArray ); //Passage d'un tableau d'entiers System.out.println( "\nLes éléments du tableau à double précision sont :" ); printArray( doubleArray ); //Passage d'un tableau à double précision System.out.println( "\nLes éléments du tableau de caractères sont :" ); printArray( charArray ); //Passage d'un tableau de caractères } }

Compilez le code ci-dessus, et le résultat de l'exécution est le suivant :

整型数组元素为:
1 2 3 4 5 

双精度型数组元素为:
1.1 2.2 3.3 4.4 

字符型数组元素为:
H E L L O 

Paramètres de type bornés :

Il peut arriver que vous souhaitiez restreindre la plage de types pouvant être passés à un paramètre de type. Par exemple, une méthode qui opère sur des nombres peut ne vouloir accepter que des instances de Number ou de ses sous-classes. C'est le but des paramètres de type bornés.

Pour déclarer un paramètre de type borné, listez d'abord le nom du paramètre de type, suivi du mot-clé extends, puis sa borne supérieure.

Exemple

L'exemple suivant montre comment "extends" est utilisé au sens général de "extends" (classes) ou "implements" (interfaces). La méthode générique de cet exemple renvoie le maximum de trois objets comparables.

Exemple

public class MaximumTest { //Comparer trois valeurs et renvoyer le maximum public static <T extends Comparable<T>> T maximum(T x, T y, T z) { T max = x; //Supposons que x soit le maximum initial if ( y.compareTo( max ) > 0 ){ max = y; //y est plus grand } if ( z.compareTo( max ) > 0 ){ max = z; //Maintenant z est plus grand } return max; //Retourne l'objet maximum } public static void main( String args[] ) { System.out.printf( "Le plus grand de %d, %d et %d est %d\n\n", 3, 4, 5, maximum( 3, 4, 5 ) ); System.out.printf( "Le plus grand de %.1f, %.1f et %.1f est %.1f\n\n", 6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 ) ); System.out.printf( "Le plus grand de %s, %s et %s est %s\n","poire", "pomme", "orange", maximum( "poire", "pomme", "orange" ) ); } }

Compilez le code ci-dessus, et le résultat de l'exécution est le suivant :

3, 4 和 5 中最大的数为 5

6.6, 8.8 和 7.7 中最大的数为 8.8

pear, apple 和 orange 中最大的数为 pear

Classes génériques

La déclaration d'une classe générique est similaire à celle d'une classe non générique, sauf qu'une section de déclaration de paramètre de type est ajoutée après le nom de la classe.

Comme les méthodes génériques, la section de déclaration des paramètres de type d'une classe générique contient également un ou plusieurs paramètres de type, séparés par des virgules. Un paramètre générique, également appelé variable de type, est un identifiant utilisé pour spécifier un nom de type générique. Comme elles acceptent un ou plusieurs paramètres, ces classes sont appelées classes paramétrées ou types paramétrés.

Exemple

L'exemple suivant montre comment nous définissons une classe générique :

Exemple

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("Example")); System.out.printf("Valeur Integer : %d\n\n", integerBox.get()); System.out.printf("String: %s\n", stringBox.get()); } }

Compilez le code ci-dessus, et le résultat de l'exécution est le suivant :

整型值为 :10

字符串为 :Example

Jokers de type

1. Les jokers de type utilisent généralement?pour remplacer des paramètres de type spécifiques. Par exempleList<?>est logiquementList<String>,List<Integer>et toutes lesList<arguments de type spécifiques>classes parentes.

Exemple

import java.util.*; public class GenericTest { public static void main(String[] args) { List<String> name = new ArrayList<String>(); List<Integer> age = new ArrayList<Integer>(); List<Number> number = new ArrayList<Number>(); name.add("icon"); age.add(18); number.add(314); getData(name); getData(age); getData(number); } public static void getData(List<?> data) { System.out.println("data :" + data.get(0)); } }

Le résultat de sortie est:

data :icon
data :18
data :314

Analyse :Parce quegetData()le paramètre de la méthode estList<?>type, doncname,age,numberpeuvent tous être utilisés comme arguments de cette méthode ; c'est le rôle des jokers.

2. La borne supérieure du joker de type est définie par la forme List

Exemple

import java.util.*; public class GenericTest { public static void main(String[] args) { List<String> name = new ArrayList<String>(); List<Integer> age = new ArrayList<Integer>(); List<Number> number = new ArrayList<Number>(); name.add("icon"); age.add(18); number.add(314); //getUperNumber(name);//1 getUperNumber(age);//2 getUperNumber(number);//3 } public static void getData(List<?> data) { System.out.println("data :" + data.get(0)); } public static void getUperNumber(List<? extends Number> data) { System.out.println("data :" + data.get(0)); } }

Résultat de sortie :

data :18
data :314

Analyse :Dans//1Une erreur se produira à la position cargetUperNumber()le paramètre de la méthode a déjà limité la borne supérieure générique du paramètre àNumber, donc le type générique étantStringn'est pas dans cette plage, donc une erreur est signalée.

3. La borne inférieure du joker de type est définie via la formeList<? super Number>pour la définir, ce qui signifie que le type ne peut accepter queNumberet ses types de superclasses au-dessus, commeObjectinstances du type.

Autres extensions