Cet article analyse les différences entre JDK1.4, JDK1.5 et JDK1.6 dans la programmation Java en combinaison avec des exemples. Partagez-le pour votre référence, comme suit:
Autrement dit: il existe deux plus grandes différences entre 1,4 et 1,5. La première est que 1,5 a des génériques, et l'autre 1,5 peut encapsuler automatiquement les types de données encapsulées de huit types de données de base. C'est-à-dire, entier a = 4 n'est pas autorisé. Il n'y a pas beaucoup de différence entre 1,5 et 1,6. 1.6 Je pense que le plus grand nombre de changements sont l'interface graphique, qui fournit beaucoup de gestion et d'extension de mise en page pratique.
Au cours de cette période, j'ai rejoint une entreprise de gouvernement électronique et utilisé WebLogic8. Ensuite, utilisons JDK1.4. Eclipse a changé la version JDK. Cependant, les projets précédents sont essentiellement devenus populaires.
★ Nouvelles fonctionnalités de JDK1.5:
1. Génériques
2 Emballage / déballage automatique
3 pour chaque
4 importation statique
5 paramètres de longueur variable
1. Génériques (évitez les erreurs d'exécution qui peuvent être causées par la coulée de type)
Par exemple:
ArrayList list = new ArrayList (); list.add (nouvel entier (3)); list.add (nouvel entier (4)); int i = ((entier) (list.get (0))). parseInt ();
Très gênant
ArrayList <Integer> list = new ArrayList <Integer> (); list.add (nouvel entier (3)); list.add (nouvel entier (4)); int i = list.get (0) .parseint ();
2 Emballage / déballage automatique
La dernière phrase de l'exemple ci-dessus peut être changée en:
La copie de code est la suivante: int i = list.get (0);
Parce que le type d'origine et la classe de wrapper correspondante n'ont pas besoin d'être explicitement converti
3 pour chaque
Amélioration des boucles
int a [] = {......}; // initialiser pour (int i: a) {......}N'utilisez pas le précédent i = 0; i <a.Length; i ++
4 importation statique
Java.math précédemment réglé
La copie de code est la suivante: math.sqrt ();
Maintenant statique import java.lang.math.sqrt;
sqrt ();
Cela équivaut à avoir cette méthode dans votre propre classe
5 paramètres de longueur variable
int sum (int ... intList) {int sum; sum = 0; for (int i = 0; i <intList.length; i ++) {sum + = intList [i]; } Retour Sum;}Il y a un paramètre, traitez-le comme un tableau
★ Nouvelles fonctionnalités de JDK6.0
Enhanced pour l'énumération d'annotation de l'énoncé de boucle des paramètres variadiques de méthode statique "cachés" (VARARG)
Les caractères génériques et le retour de covariance améliorés pour les déclarations de boucle
Pour itérer les ensembles et les tableaux, la boucle améliorée pour la boucle fournit une syntaxe simple et compatible. Il y a deux points à mentionner:
1. Dans une boucle, l'expression d'initialisation n'est calculée qu'une seule fois. Expression int
Non amélioré pour:
int sum = 0; Nombres entiers [] = composeTenumbers (); pour (int i = 0; i <nombres.length; i ++) sum + = nombres [i];
Amélioré pour:
int sum = 0; for (int number: composeTenumbers ()) sum + = nombre;
limitation
L'itérateur ou l'indice ne peut pas être accessible lors d'une amélioration pour l'itération de la boucle
Veuillez consulter l'exemple suivant:
pour (int i = 0; i <nombres.length; i ++) {if (i! = 0) System.out.print (","); System.out.print (nombres [i]);}Voici un autre exemple:
for (iterator <nteger> it = n.iterator (); it.hasnext ();) if (it.next () <0) it.remove ();
Commentaires
Le traitement des commentaires est un grand sujet. Étant donné que cet article se concentre uniquement sur les fonctionnalités de la langue centrale, nous n'avons pas l'intention de couvrir toutes ses formes et pièges possibles. Nous discuterons des annotations intégrées (suppresswarnings, dépréciées et remplacés) et les limites du traitement général de l'annotation.
Supprimer les avertissements
Ce commentaire désactive les avertissements du compilateur au niveau de la classe ou de la méthode. Parfois, vous savez plus clairement que le compilateur que le code doit utiliser une méthode rejetée ou effectuer une action qui ne peut pas déterminer statistiquement si le type-safe est-être-sa-sécurité et l'utilisation:
@SuppressWarnings ("Deprécation") public static void selfestruct () {thread.currentThread (). Stop ();}C'est probablement la chose la plus utile à propos des annotations intégrées. Malheureusement, Javac pour 1.5.0_04 ne le prend pas en charge. Mais 1.6 le prend en charge, et Sun travaille sur le portage en arrière dans 1,5.
Cette annotation est prise en charge dans Eclipse 3.1, et d'autres IDE peuvent également le prendre en charge. Cela vous permet de libérer complètement le code de l'avertissement. S'il y a un avertissement au moment de la compilation, vous pouvez être sûr que vous venez de l'ajout - pour aider à afficher le code qui peut être dangereux. Avec l'ajout de génériques, il sera plus pratique à utiliser.
Déprécié
Malheureusement, la dépréciation n'est pas si utile. Il était initialement destiné à remplacer la balise Javadoc @Deprecated, mais comme il ne contient aucun champ, il n'y a aucun moyen de suggérer les utilisateurs de classes ou de méthodes obsolètes devraient utiliser comme remplacement. la plupart
Les deux usages nécessitent la balise Javadoc et cette annotation.
Outrepasser
Override indique que la méthode qu'il annote devrait remplacer les méthodes avec la même signature dans la superclasse:
@OverridePublic int hashcode () {...}En regardant l'exemple ci-dessus, si "C" n'est pas capitalisé dans HashCode, il n'y aura pas d'erreurs au moment de la compilation, mais la méthode ne sera pas appelée comme prévu au moment de l'exécution. En ajoutant la balise de remplacement, le compilateur invitera s'il a réellement effectué la réécriture.
Ceci est également utile dans les situations où les superclasses changent. Si un nouveau paramètre est ajouté à la méthode et que la méthode elle-même est renommée, la sous-classe ne sera soudainement pas compilée car elle ne réécrit plus rien de la superclasse.
Autres notes
Les commentaires sont très utiles dans d'autres scénarios. Lorsqu'il ne s'agit pas de modifier directement le comportement mais d'améliorer le comportement, en particulier lors de l'ajout de code de passe-partout, l'annotation fonctionne très bien dans des cadres tels que EJB et les services Web.
Les commentaires ne peuvent pas être utilisés comme préprocesseurs. La conception de Sun empêche spécifiquement la modification du bytecode de la classe entièrement en raison de commentaires. Cela vous permet de comprendre correctement les résultats de la langue, et des outils comme IDE peuvent également effectuer une analyse et une refactorisation de code approfondis.
Le commentaire n'est pas une solution miracle. Lorsque je l'ai rencontré pour la première fois, les gens ont essayé d'essayer diverses techniques. Veuillez consulter les suggestions suivantes obtenues des autres:
classe publique foo {@propertyprivate int bar;}L'idée est de créer automatiquement des méthodes Getter et Setter pour la barre de champ privée. Malheureusement, il y a deux échecs dans cette idée: 1) cela ne fonctionne pas et 2) cela rend le code difficile à lire et à traiter. Il est impossible de mettre en œuvre, car comme mentionné précédemment, Sun empêche spécifiquement la modification des classes avec des commentaires.
Même si possible, ce n'est pas une bonne idée car cela rend le code mal lisible. La première fois que vous voyez ce code, vous ne saurez pas que le commentaire crée la méthode. De plus, si vous devez effectuer certaines opérations à l'intérieur de ces méthodes à l'avenir, les commentaires sont inutiles. En bref, n'essayez pas de faire des choses que le code ordinaire peut faire avec les commentaires.
énumérer
L'énume ressemble beaucoup à une déclaration publique d'intm statique publique, qui a été utilisée comme valeur d'énumération depuis de nombreuses années. L'amélioration la plus importante et la plus évidente de l'INT est la sécurité de type - vous ne pouvez pas remplacer par erreur un autre type par un type d'énumération, qui est différent de INT, et tous les INT sont les mêmes pour le compilateur. À quelques exceptions près, toutes les structures INT de style enum doivent généralement être remplacées par des instances d'énumération.
L'énumération offre quelques fonctionnalités supplémentaires. Les deux classes pratiques énumap et énumset sont des implémentations de jeu standard spécialement optimisées pour l'énumération. Si vous savez qu'une collection ne contient que des types d'énumération, vous devez utiliser ces collections spéciales au lieu de HashMap ou HashSet.
Dans la plupart des cas, vous pouvez utiliser ENUM pour remplacer tous les INTS finaux statiques publics dans le code. Ils sont comparables et peuvent être importés statiquement, donc les références semblent être équivalentes, même pour les classes intérieures (ou les types d'énumérage intérieure). Notez que lors de la comparaison des types d'énumération, les instructions qui les déclarent indiquent leurs valeurs séquentielles.
Méthode statique "cachée"
Deux méthodes statiques apparaissent dans toutes les déclarations de type d'énumération. Parce que ce sont des méthodes statiques sur les sous-classes d'énumération, et non des méthodes d'énumération elle-même, elles n'apparaissent pas dans Javadoc de Java.lang.enum.
Le premier est valeurs (), qui renvoie un tableau de toutes les valeurs possibles du type d'énumération.
La seconde est ValueOf (), qui renvoie un type d'énumération pour la chaîne fournie, qui doit correspondre exactement à la déclaration de code source.
méthode
L'un de nos aspects préférés sur les types d'énumérage est qu'il peut avoir des méthodes. Dans le passé, vous devrez peut-être écrire du code pour convertir le public statique final INT et le convertir du type de base de données en URL JDBC. Maintenant, le type d'énumération lui-même peut être fait avec un complet
Méthodes de manipulation du code. Voici un exemple, y compris la méthode abstraite de type d'énumération de données de données et l'implémentation fournie dans chaque instance d'énumération:
public Enum databasetype {oracle {public String getJDBcurl () {...}}, mysql {public String getJDBcurl () {...}}; public abstract String getJDBcurl ();}Désormais, le type d'énumération peut fournir directement ses méthodes pratiques. Par exemple:
Databasetype dbType = ...; String jdbcurl = dbtype.getjdbcurl ();
Pour obtenir l'URL, vous devez savoir à l'avance où se trouve la méthode d'utilité.
Vararg
L'utilisation de paramètres mutables nettoie correctement un code indésirable. Un exemple typique est une méthode de journal avec un nombre variable de paramètres de chaîne:
Log.log (chaîne de code) log.log (code de chaîne, chaîne arg) log.log (code de chaîne, chaîne arg1, chaîne arg2) log.log (code de chaîne, chaîne [] args)
Lorsque vous discutez des paramètres variables, il est intéressant de noter que si vous remplacez les quatre premiers exemples par de nouveaux paramètres variables, il sera compatible:
Copiez le code comme suit: log.log (code de chaîne, chaîne ... args)
Tous les paramètres mutables sont compatibles sur les sources - c'est-à-dire que si tous les programmes d'appel de la méthode log () sont recompilés, les quatre méthodes peuvent être remplacées directement. Cependant, si une compatibilité binaire en arrière est nécessaire, les trois premières méthodes doivent être abandonnées. Seule la dernière méthode avec un paramètre de tableau de chaîne est équivalente à la version variadique, il peut donc être remplacé par la version variadique.
Plâtre de type
Si vous souhaitez que l'appelant sache quel type de paramètres doit être utilisé, vous devez éviter de taper la coulée avec des paramètres mutables. En regardant l'exemple suivant, le premier espoir est String, et le deuxième espoir est l'exception:
Log.log (objet ... objets) {String Message = (String) objets [0]; if (objets.length> 1) {exception e = (exception) objets [1]; // faire quelque chose avec l'exception}} La signature de la méthode doit être la suivante, et les paramètres mutables correspondants sont déclarés respectivement en utilisant la chaîne et l'exception:
La copie de code est la suivante: log.log (message de chaîne, exception e, objet ... objets) {...}
N'utilisez pas de paramètres variables pour détruire le système de type. Il ne peut être utilisé que lorsqu'il est fortement dactylographié. Pour cette règle, printStream.printf () est une exception intéressante: elle fournit des informations de type comme premier argument afin que ces types puissent être acceptés plus tard.
Retour de covariance
L'utilisation de base du retour covariant consiste à éviter le coulage de type lorsque le type de retour d'une implémentation est connu pour être plus spécifique que l'API. Dans l'exemple suivant, il existe une interface zoo qui renvoie un objet animal. Notre implémentation renvoie un objet AnimalImpl, mais avant JDK 1.5, il doit être déclaré pour renvoyer un objet animal. :
Interface publique Zoo {public animal getanimal ();} classe publique Zooimpl implémente zoo {public animal getanimal () {return new animalImpl ();}}L'utilisation de rendements covariants remplace trois anti-motifs:
Accès direct au champ. Pour contourner les limitations de l'API, certaines implémentations exposent des sous-classes directement dans les champs:
Copiez le code comme suit: zooimpl._animal
Un autre formulaire consiste à effectuer une conversion en bas dans le programme d'appel, sachant que l'implémentation est en fait une sous-classe spécifique:
La copie de code est la suivante: ((animalImpl) zooimpl.getanimal ()). Implmethod ();
La dernière forme que j'ai vue est une méthode concrète utilisée pour éviter les problèmes causés par une signature complètement différente:
La copie de code est la suivante: zooimpl._getanimal ();
Ces trois modes ont leurs problèmes et leurs limites. Soit il n'est pas suffisamment soigné, soit il expose les détails de mise en œuvre inutiles.
Covariance
Le mode de retour covariant est plus propre, plus sûr et plus facile à entretenir, et il ne nécessite pas de coulée de type ou de méthodes ou champs spécifiques:
public AnimalImpl Getanimal () {return new AnimalImpl (); } Utiliser les résultats:
La copie de code est la suivante: zooimpl.getanimal (). Implmethod ();
Utilisation de génériques
Nous apprendrons les génériques sous deux perspectives: utiliser des génériques et construire des génériques. Nous ne discutons pas de l'utilisation évidente de la liste, du set et de la carte. Il suffit de savoir que les collections génériques sont puissantes et doivent être utilisées fréquemment.
Nous discuterons de l'utilisation des méthodes génériques et de la méthode du compilateur pour déduire les types. Habituellement, aucun de ces éléments ne va mal, mais lorsque quelque chose ne va pas, le message d'erreur peut être très déroutant, vous devez donc savoir comment résoudre ces problèmes.
Méthodes génériques
En plus des types génériques, Java 5 présente également des méthodes génériques. Dans cet exemple de java.util.collections, une liste d'éléments unique est construite. Le type d'élément de la nouvelle liste est déduit en fonction du type de l'objet passé dans la méthode:
Copiez le code comme suit: STATIC <T> Liste <T> Collection.Singletonlist (T O)
Exemple d'utilisation:
Liste publique <Integer> getListofone () {return Collection.Singletonlist (1);}Dans l'exemple d'utilisation, nous passons dans un int. Ainsi, le type de retour de la méthode est List <Integer>. Le compilateur déduit T en entier. Ceci est différent des types génériques, car vous n'avez généralement pas besoin de spécifier explicitement les paramètres de type.
Cela montre également l'interaction entre l'autoboxing et les génériques. Le paramètre de type doit être un type de référence: c'est pourquoi nous obtenons List <Integer> au lieu de la liste <nt>.
Méthodes génériques sans paramètres
La méthode videList () est introduite avec des génériques comme une permutation de type de type du champ vide_list dans java.util.collections:
Copiez le code comme suit: statique <T> Liste <T> Collection.EmptyList ()
Exemple d'utilisation:
Liste publique <Integer> getNointegers () {return CollectionS.EmptyList ();}Contrairement à l'exemple précédent, cette méthode n'a pas de paramètres, alors comment le compilateur déduit le type de T? Fondamentalement, il essaiera d'utiliser le paramètre une fois. Si cela ne fonctionne pas, il essaie de réutiliser le type de retour ou d'affectation. Dans cet exemple, le retour est List <Integer>, donc t est déduit comme entier.
Que se passe-t-il si une méthode générique est appelée en dehors de l'instruction de retour ou de l'instruction Affectation? Ensuite, le compilateur ne pourra pas effectuer le deuxième transfert de l'inférence de type. Dans l'exemple suivant, videList () est appelé de l'intérieur de l'opérateur conditionnel:
Liste publique <Integer> getNointegers () {return x? Collection.EmptyList (): null;} Parce que le compilateur ne peut pas voir le contexte de retour et ne peut pas déduire t, il abandonne et prend l'objet. Vous verrez un message d'erreur comme: "Impossible de convertir la liste <Object> pour List <Integer>."
Pour corriger cette erreur, les paramètres de type doivent être passés explicitement à l'appel de la méthode. De cette façon, le compilateur n'essaiera pas de déduire les paramètres de type et peut obtenir le résultat correct:
La copie de code est la suivante: Retour x? Collections. <Integer> videList (): null;
Un autre endroit où cela se produit est souvent dans les appels de méthode. Si une méthode prend un paramètre List <string> et doit appeler le PASSED LIDELLIST () pour ce paramètre, cette syntaxe est également requise.
En dehors de la collection
Voici trois exemples de types génériques, qui ne sont pas des collections, mais utilisent des génériques d'une manière nouvelle. Les trois exemples proviennent des bibliothèques Java standard:
Copiez le code comme suit: Classe <T>
La classe est paramétrée sur le type de classe. Cela permet de construire une nouvelleInstance sans moulage de type.
Copiez le code comme suit: comparable <T>
Comparable est paramétré par le type de comparaison réel. Cela fournit des appels plus forts par rapport aux appels (). Par exemple, String implémente <string> comparable. L'appel compareto () sur autre chose que String échouera au moment de la compilation.
Copiez le code comme suit: Enum <e étend enum <e>>
L'enain est paramétré par le type d'énumération. Un type d'énumération nommé Couleur étendra l'énumération <ouleurs>. La méthode getDeclaredClass () renvoie un objet de classe de type énumération, dans cet exemple, un objet couleur. C'est différent de GetClass (), qui peut renvoyer une classe sans nom.
Magazine
La partie la plus complexe des génériques est la compréhension des caractères génériques. Nous discuterons de trois types de caractères génériques et de leurs utilisations.
Comprenons d'abord comment les tableaux fonctionnent. Vous pouvez attribuer une valeur à partir d'un entier [] à un nombre []. Si vous essayez d'écrire un flotteur sur numéro [], il peut être compilé, mais il échouera au moment de l'exécution et un ArrayStoreException apparaît:
Entier [] ia = nouvel entier [5]; nombre [] na = ia; na [0] = 0,5; // compile, mais échoue à l'exécution
Si vous essayez de convertir l'exemple directement en générique, il échouera au moment de la compilation car l'affectation n'est pas autorisée:
List <Integer> iList = new ArrayList <Integer> (); list <umber> nlist = iList; // non autorisénList.add (0,5);
Si vous utilisez des génériques, vous ne rencontrerez pas de ClassCastException d'exécution tant que le code n'apparaîtra pas lors de la compilation.
Limite supérieure
Ce que nous voulons, c'est une liste du type d'élément exact inconnu, qui est différent des tableaux.
List <borld> est une liste dont le type d'élément est le numéro de type spécifique.
Liste <? Extend Number> est une liste du type d'élément exact inconnu. C'est le nombre ou son sous-type.
Limite supérieure
Si nous mettons à jour l'exemple initial et attribuons la valeur à la liste <? Étend le numéro>, alors l'affectation réussira maintenant:
List <Integer> ilist = new ArrayList <Neger> (); list <? étend le nombre> nList = iList; nombre n = nlist.get (0); nList.add (0,5); // pas autorisé
Nous pouvons obtenir le numéro de la liste car nous pouvons l'affecter au numéro quel que soit le type d'élément exact de la liste (flotteur, entier ou numéro).
Nous ne pouvons toujours pas insérer des types de points flottants dans la liste. Cela échouera au moment de la compilation car nous ne pouvons pas prouver que c'est sûr. Si nous voulons ajouter des types de points flottants à la liste, il brisera la sécurité initiale de l'ILIST - il stocke uniquement entier.
Les caractères génériques nous donnent plus de puissance expressive que les tableaux.
Pourquoi utiliser les jilèges
Dans l'exemple suivant, les caractères génériques sont utilisés pour masquer les informations de type aux utilisateurs de l'API. En interne, l'ensemble est stocké sous forme de client. Les utilisateurs d'API savent seulement qu'ils obtiennent un ensemble à partir duquel ils peuvent lire le client.
Les caractères génériques sont nécessaires ici car il est impossible d'attribuer des valeurs pour définir <lient> à partir de Set <SustmerImpl>:
classe publique CustomerFactory {private Set <Sust clientImpl> _Customers; public set <? étend le client> getCustomers () {return _Customers;}}La joker et le retour covariant
Une autre utilisation courante des personnages génériques est de l'utiliser avec un retour covariant. Les mêmes règles que l'attribution peuvent être appliquées aux rendements covariants. Si vous souhaitez renvoyer un type générique plus spécifique dans une méthode réécrite, la méthode déclarée doit utiliser un joker:
Interface publique NumberGenerator {Liste publique <? Extend Number> generate ();} public class fibonaccigenerator étend NumberGenerator {public list <Integer> generate () {...}}Si vous souhaitez utiliser un tableau, l'interface peut renvoyer le numéro [], tandis que l'implémentation peut renvoyer entier [].
Limite inférieure
Ce dont nous parlons, c'est principalement de la limite de limite supérieure. Il y a aussi un joker à limite inférieure. Liste <? Super Number> est une liste du "type d'élément" exact inconnu, mais il peut être Mnumber, ou le supertype de numéro. Il peut donc s'agir d'une liste <bor Swember> ou d'une liste <Bject>.
Les caractères génériques à faible limite sont beaucoup moins courants que les caractères génériques à limite supérieure, mais ils sont nécessaires lorsqu'ils sont nécessaires.
Limite inférieure et supérieure
Liste <? Extend Number> readList = new ArrayList <Integer> (); nombre n = readList.get (0); list <? super numéro> writeList = new ArrayList <Bject> (); writeList.add (new Integer (5));
Le premier est une liste de nombres qui peuvent être lus.
Le second est une liste de nombres auxquels vous pouvez écrire.
Joker illimité
Enfin, le contenu d'une liste de liste <?> Peut être de n'importe quel type, et il est presque le même que la liste <? étend l'objet>. Les objets peuvent être lus à tout moment, mais le contenu ne peut pas être écrit sur la liste.
CARTEURS DES API PUBLIQUES
En bref, comme mentionné précédemment, les caractères génériques sont très importants pour cacher les détails de la mise en œuvre de l'appelant, mais même si les caractères génériques de la liaison inférieure semblent fournir un accès en lecture seule, ils ne sont pas le cas en raison de méthodes non génériques comme la suppression (position int). Si vous voulez une collection vraiment inchangée, vous pouvez utiliser la méthode sur java.util.collection comme unmodifiabeblelist ().
N'oubliez pas les caractères génériques lors de la rédaction d'API. Généralement, lorsque vous passez des types génériques, vous devriez essayer d'utiliser les caractères génériques. Il permet à plus d'appels d'accéder à l'API.
En recevant la liste <? étend le numéro> au lieu de la liste <grombre>, la méthode suivante peut être appelée par de nombreux types de listes différents:
La copie de code est la suivante: VOID Removenegatives (Liste <? Extend Number> List);
Construire des types génériques
Nous allons maintenant discuter de la construction de nos propres types génériques. Nous montrerons quelques exemples où la sécurité des types peut être améliorée en utilisant des génériques, et nous discuterons également de certains problèmes courants lors de la mise en œuvre de types génériques.
Fonctions de collection
Le premier exemple de classe générique est un exemple de style de collecte. La paire a deux paramètres de type, et le champ est une instance de type:
Paire de classe finale publique <a, b> {public final a premier; public final b second; paire publique (un premier, b second) {this.first = premier; this.second = seconde;}}Cela permet de retourner deux éléments d'une méthode sans écrire une classe dédiée pour chaque combinaison de deux types. Une autre façon consiste à renvoyer l'objet [], qui est le type dangereux ou en désordre.
Dans l'utilisation suivante, nous renvoyons un fichier et un booléen de la méthode. Le client de la méthode peut utiliser des champs directement sans casting de type:
public paire <file, boolean> getFileAndWriteStatus (String path) {// Créer un fichier et statutreturn new paire <fichier, boolean> (fichier, status);} paire <fichier, boolean> result = getFileAndWriteStatus ("..."); file f = result.first; Boolean Writeable = Result.second;En dehors de la collection
Dans l'exemple suivant, les génériques sont utilisés pour une sécurité supplémentaire en temps de compilation. En paramétrant la classe DBFactory au type de pair créé, vous obligez en fait la sous-classe d'usine à renvoyer un sous-type spécifique d'un pair:
La classe publique abstraite dbfactory <T étend dbpeer> {abstract protégé t createEmpTypeer (); public list <t> get (String Contrainte) {list <t> Peers = new ArrayList <T> (); // database magicreturn Peers;}}En mettant en œuvre DBFactory <Simité>, CustomerFactory doit renvoyer un client de CreateEmpTypeer ():
classe publique CustomerFactory étend DBFactory <Simité> {Customer public CreateEmpTypeer () {return new Customer ();}}Méthodes génériques
Que vous souhaitiez imposer des contraintes aux types génériques entre les paramètres et entre les paramètres et les types de retour, vous pouvez utiliser des méthodes génériques:
Par exemple, si la fonction d'inversion écrite est inversée sur la position sur place, une méthode générique peut ne pas être nécessaire. Cependant, si vous souhaitez que l'inversion renvoie une nouvelle liste, vous pouvez vouloir que le type d'élément de la nouvelle liste soit le même que le type de liste entrante. Dans ce cas, une méthode générique est nécessaire:
Copiez le code comme suit: <T> Liste <T> Reverse (liste <T> Liste)
Béton
Lors de la mise en œuvre d'une classe générique, vous voudrez peut-être construire un tableau T []. Parce que les génériques sont mis en œuvre par effacement, cela n'est pas autorisé.
Vous pouvez essayer de lancer un objet [] pour t []. Mais ce n'est pas sûr.
Solutions de béton
Selon la convention des tutoriels génériques, la solution utilise un "jeton de type". En ajoutant un paramètre de classe <T> au constructeur, vous pouvez forcer le client à fournir l'objet de classe correct pour les paramètres de type de la classe:
classe publique ArrayExample <T> {classe privée <T> Clazz; public ArrayExample (class <T> Clazz) {this.clazz = Clazz;} public t [] getArray (int size) {return (t []) array.newinstance (Clazz, size);}}Afin de construire un arrayExample <string>, le client doit passer String.class au constructeur car le type de string.class est class <string>.
Avoir un objet de classe permet de construire un groupe d'un type d'élément correct
J'espère que cet article sera utile à la programmation Java de tous.