Maison Java javaDidacticiel Explication détaillée des génériques en Java

Explication détaillée des génériques en Java

Jan 18, 2017 am 10:54 AM

Les soi-disant génériques : ils permettent de spécifier des paramètres de type lors de la définition des classes et des interfaces. Ce paramètre de type sera déterminé lors de la déclaration des variables et de la création d'objets (c'est-à-dire en transmettant des paramètres de type réels, qui peuvent également être appelés arguments de type).

Classe ou interface générique

Syntaxe "Diamond"

//定义
 
public interface List<E> extends Collection<E>  
 
public class HashMap<K,V> extends AbstractMap<K,V>  implements Map<K,V>, Cloneable, Serializable 
//使用
 
List<String> list = new ArrayList();
 
//Java7以后可以省略后面尖括号的类型参数
 
List<String> list = new ArrayList<>();
Copier après la connexion

Dérivation d'une sous-classe à partir d'une classe générique

//方式1
 
public class App extends GenericType<String>
 
//方式2
 
public class App<T> extends GenericType<T>
 
//方式3
 
public class App extends GenericType
Copier après la connexion

Pseudo-générique

Il n'y a pas de véritable classe générique. Les classes génériques sont transparentes pour la machine virtuelle Java. La JVM ne connaît pas l'existence des classes génériques et des classes ordinaires. Par conséquent, les paramètres de type ne sont pas autorisés dans les méthodes statiques, les blocs d’initialisation statiques et les variables statiques.
- Les méthodes suivantes sont toutes fausses

private static T data;
 
static{
 
    T f;
 
}
 
public static void func(){
 
    T name = 1;
 
}
Copier après la connexion

L'exemple suivant peut vérifier de côté qu'il n'y a pas de classe générique

public static void main(String[] args){
 
        List<String> a1 = new ArrayList<>();
        List<Integer> a2 = new ArrayList<>();  
    System.out.println(a1.getClass() == a2.getClass());
 
    System.out.println(a1.getClass());
 
    System.out.println(a2.getClass());
 
}
Copier après la connexion

Sortie

true
 
class java.util.ArrayList
 
class java.util.ArrayList
Copier après la connexion

Tapez le caractère générique

Tout d'abord, il doit être clair que si Foo est la classe parent de Bar, mais List n'est pas la classe parent de List. classes parentes, Java utilise "? " pour représenter les caractères génériques. Autrement dit, List représente la classe parent de diverses listes génériques avec ce caractère générique ne peut pas définir (définir) des éléments, mais peut uniquement obtenir (obtenir) éléments. Le programme ne pouvant pas déterminer le type dans la liste, il ne peut pas ajouter l'objet. Mais l’objet obtenu doit être de type Objet.

Les méthodes suivantes compileront les erreurs :

List<?> list = new ArrayList<>();
 
list.add(new Object());
Copier après la connexion

Quelques idées :

1. Les objets List est Say : La classe List n'est pas une sous-classe de la classe List

2. Les tableaux et les génériques sont différents : en supposant que Foo est un sous-type (sous-classe ou sous-interface) de Bar, alors Foo[] est toujours un sous-type de Bar[] mais G ;Barre>.

3. Afin de représenter la classe parent de diverses listes génériques, nous devons utiliser des caractères génériques de type est un point d'interrogation (?). , écrivant : List< ?> (signifiant Liste d'éléments de type inconnu). Ce point d'interrogation (?) est appelé caractère générique et son type d'élément peut correspondre à n'importe quel type.

La limite supérieure des caractères génériques

List représente la classe parent de toutes les listes génériques SuperType ou elle-même. Les génériques avec des limites supérieures génériques ne peuvent pas avoir de méthodes définies, ils obtiennent uniquement des méthodes.

Définir la limite supérieure des caractères génériques peut résoudre les problèmes suivants : Dog est une sous-classe d'Animal, et il existe une méthode getSize pour obtenir le nombre de listes entrantes. Le code est le suivant

abstract class Animal {
    public abstract void run();
}
class Dog extends Animal {
    public void run() {
        System.out.println("Dog run");
    }
}
public class App {
    public static void getSize(List<Animal> list) {
        System.out.println(list.size());
    }
    public static void main(String[] args) {
        List<Dog> list = new ArrayList<>();
        getSize(list); // 这里编译报错
    }
}
Copier après la connexion
<. 🎜>La raison de l'erreur de programmation ici est que List n'est pas la classe parent de List. La première solution consiste à modifier le paramètre formel List dans la méthode getSize en List, mais dans ce cas, une conversion de type forcée est requise à chaque fois que l'objet est obtenu, ce qui est plus gênant. L'utilisation de la limite supérieure générique résout très bien ce problème. Vous pouvez remplacer List par List


Limite inférieure du caractère générique

List Les génériques avec des limites supérieures génériques ne peuvent pas avoir de méthodes get, mais uniquement des méthodes set.

Méthodes génériques

Si vous définissez des classes et des interfaces sans utiliser de paramètres de type, mais que vous souhaitez définir vous-même les paramètres de type lors de la définition des méthodes, cela est également possible dans JDK1.5. . La signature de méthode d'une méthode générique contient plus de déclarations de paramètres de type que la signature de méthode d'une méthode ordinaire. Les déclarations de paramètres de type sont placées entre crochets. Plusieurs paramètres de type sont séparés par des virgules (,). modificateurs et types de valeurs de retour de méthode. Le format de syntaxe est le suivant :

修饰符 返回值类型 方法名(类形列表){
 
//方法体
 
}
Copier après la connexion
Les méthodes génériques permettent d'utiliser des paramètres de type pour exprimer les dépendances de type entre un ou plusieurs paramètres de la méthode, ou la dépendance de type entre les méthodes. valeur de retour et paramètres. S’il n’existe pas de dépendance de type, les méthodes génériques ne doivent pas être utilisées. La méthode de copie de Collections utilise la méthode générique :

 public static <T> void copy(List<? super T> dest, List<? extends T> src){ ...}
Copier après la connexion
Cette méthode nécessite que le type src soit une sous-classe du type dest ou lui-même.

Effacer et convertir

Dans le code générique strict, les classes avec des déclarations génériques doivent toujours porter des paramètres de type. Cependant, afin d'être cohérent avec l'ancien code Java, il est également autorisé d'utiliser des classes avec des déclarations génériques sans spécifier de paramètres de type. Si aucun paramètre de type n'est spécifié pour cette classe générique, le paramètre de type est appelé type brut et prend par défaut le premier type de limite supérieure spécifié lors de la déclaration du paramètre.

Lors de l'affectation d'un objet avec des informations génériques à une autre variable sans informations génériques, toutes les informations de type entre crochets angulaires sont supprimées. Par exemple, si un type List est converti en List, la vérification de type des éléments de collection de List devient la limite supérieure de la variable de type (c'est-à-dire Object). Cette situation est appelée effacement.

Exemple

class Apple<T extends Number>
 
{
 
 T size;
 
 public Apple()
 
 {
 
 }
 
 public Apple(T size)
 
 {
 
  this.size = size;
 
 }
 
 public void setSize(T size)
 
 {
 
  this.size = size;
 
 }
 
 public T getSize()
 
 {
 
  return this.size;
 
 }
 
}
 
public class ErasureTest
 
{
 
 public static void main(String[] args)
 
 {
 
  Apple<Integer> a = new Apple<>(6);    // ①
 
  // a的getSize方法返回Integer对象
 
  Integer as = a.getSize();
 
  // 把a对象赋给Apple变量,丢失尖括号里的类型信息
 
  Apple b = a;      // ②
 
  // b只知道size的类型是Number
 
  Number size1 = b.getSize();
 
  // 下面代码引起编译错误
 
  Integer size2 = b.getSize();  // ③
 
 }
 
}
Copier après la connexion
Pour des articles plus détaillés sur les génériques en Java, veuillez faire attention au site Web PHP chinois !

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment fonctionne le mécanisme de chargement de classe de Java, y compris différents chargeurs de classe et leurs modèles de délégation? Comment fonctionne le mécanisme de chargement de classe de Java, y compris différents chargeurs de classe et leurs modèles de délégation? Mar 17, 2025 pm 05:35 PM

Le chargement de classe de Java implique le chargement, la liaison et l'initialisation des classes à l'aide d'un système hiérarchique avec Bootstrap, Extension et Application Classloaders. Le modèle de délégation parent garantit que les classes de base sont chargées en premier, affectant la classe de classe personnalisée LOA

Comment implémenter la mise en cache à plusieurs niveaux dans les applications Java à l'aide de bibliothèques comme la caféine ou le cache de goyave? Comment implémenter la mise en cache à plusieurs niveaux dans les applications Java à l'aide de bibliothèques comme la caféine ou le cache de goyave? Mar 17, 2025 pm 05:44 PM

L'article examine la mise en œuvre de la mise en cache à plusieurs niveaux en Java à l'aide de la caféine et du cache de goyave pour améliorer les performances de l'application. Il couvre les avantages de configuration, d'intégration et de performance, ainsi que la gestion de la politique de configuration et d'expulsion le meilleur PRA

Comment puis-je utiliser JPA (Java Persistance API) pour la cartographie relationnelle des objets avec des fonctionnalités avancées comme la mise en cache et le chargement paresseux? Comment puis-je utiliser JPA (Java Persistance API) pour la cartographie relationnelle des objets avec des fonctionnalités avancées comme la mise en cache et le chargement paresseux? Mar 17, 2025 pm 05:43 PM

L'article discute de l'utilisation de JPA pour la cartographie relationnelle des objets avec des fonctionnalités avancées comme la mise en cache et le chargement paresseux. Il couvre la configuration, la cartographie des entités et les meilleures pratiques pour optimiser les performances tout en mettant en évidence les pièges potentiels. [159 caractères]

Comment utiliser Maven ou Gradle pour la gestion avancée de projet Java, la création d'automatisation et la résolution de dépendance? Comment utiliser Maven ou Gradle pour la gestion avancée de projet Java, la création d'automatisation et la résolution de dépendance? Mar 17, 2025 pm 05:46 PM

L'article discute de l'utilisation de Maven et Gradle pour la gestion de projet Java, la construction de l'automatisation et la résolution de dépendance, en comparant leurs approches et leurs stratégies d'optimisation.

Mar 17, 2025 pm 05:45 PM

L'article discute de la création et de l'utilisation de bibliothèques Java personnalisées (fichiers JAR) avec un versioning approprié et une gestion des dépendances, à l'aide d'outils comme Maven et Gradle.

See all articles