Ce qui suit est affiché à tout le monde pour chaque malentendu.
1. Utilisation excessive de Null
Éviter une utilisation excessive de NULL est la meilleure pratique. Par exemple, une meilleure approche consiste à faire revenir la méthode au tableau ou à la collection vide au lieu de la valeur nulle, car cela peut empêcher le programme de lancer NullPointerException. Le fragment de code suivant obtiendra une collection à partir d'une autre méthode:
List <string> accoutid = person.getAccountIdS ();
Lorsqu'un chiffre n'a pas de compte, getAccountIdS () renvoie la valeur nul et le programme jettera l'exception de NullPointerException. Par conséquent, il est nécessaire de rejoindre la vérification de l'air pour résoudre ce problème. Si vous remplacez la valeur NULL renvoyée par une liste vide, NullPointerException n'apparaîtra pas. De plus, comme nous n'avons plus besoin de prendre un bref chèque de la variable CompteID, le code deviendra plus concis.
Lorsque vous souhaitez éviter les valeurs nulles, différents scénarios peuvent prendre différentes pratiques. Une méthode consiste à utiliser le type facultatif, qui peut être à la fois un objet vide ou un package de certaines valeurs.
Facultatif <string> optionalString = facultatif.OfNullable (nuldString);
En fait, Java8 fournit une manière plus concise:
Facultatif <string> optionalString = facultatif.ofNullable (nullialString);
Java a pris en charge le type facultatif de la version Java8, mais il a été largement connu dans le monde de la programmation fonctionnelle. Avant cela, il a été utilisé dans la première version de Java dans Google Guava.
2. Ignorer les anomalies
Nous ignorons souvent les anomalies. Cependant, la meilleure pratique consiste à les traiter pour les débutants et les programmeurs Java expérimentés. Le lancer anormal est généralement déterminé, donc dans la plupart des cas, il est nécessaire d'enregistrer des événements qui provoquent des anomalies. Ne sous-estimez pas cette question. Du moins, afin de faire connaître à d'autres développeurs la cause et l'effet, vous devez expliquer pourquoi ces anomalies n'ont pas été traitées.
Selfie = personne.shootaselfie (); essayez {selfie.show ();} catch (nullpointrexception e) {// peut-être, homme invisible.
Un moyen simple de mettre l'accent sur un certain nombre sans importance est d'utiliser ces informations comme un nom de variable anormal, comme ceci:
Copier le code du code comme suit:
essayez {selfie.delete ();} catch (nullpointterException sans importance) {}
3. Modifier les anomalies simultanément
Cette anomalie se produit dans l'objet de collection et n'utilise en même temps pas la méthode fournie par l'objet Iterator pour mettre à jour le contenu de la collection. Par exemple, il y a une liste de chapeaux ici, et vous souhaitez supprimer toutes les valeurs contenant des volets d'oreille:
List <ihats = new ArrayList <>); HaseArflaps ()) {hats.remove (hat);}}
Si ce code s'exécute, ConcurrentModificationException sera lancé, car le code le modifiera lors de la traversée de cette collection. Lorsque plusieurs processus agissent sur la même liste, lorsque l'un des processus traverse la liste, l'autre processus essaie de modifier le contenu de la liste, et les mêmes anomalies peuvent également se produire.
Il est très courant dans le contenu de la collection de modifications simultanés multi-thread, il est donc nécessaire d'utiliser la méthode couramment utilisée dans la programmation simultanée, telles que les verrous synchrones, des ensembles spéciaux pour une modification simultanée, etc. Java résout ce problème dans un seul fil et une situation multi-thread.
Collectez des objets et supprimez-les dans un autre cycle
La solution directe consiste à mettre des chapeaux avec des rabats d'oreille dans une liste, puis à le supprimer avec un autre cycle. Cependant, cela nécessite un ensemble supplémentaire pour stocker les chapeaux pour être supprimés.
List <ihatstoreMove = new LinkedList <> ();
Utilisez la méthode Iterator.Remove
Cette méthode est plus simple et en même temps n'a pas besoin de créer une collection supplémentaire:
Iterator <ihatitrator = hats.iterator ();
La méthode d'utilisation de ListIterator
Lorsque la collection de la collection de l'interface de liste est implémentée, l'itérateur de liste est un choix très approprié. Iterator qui implémente l'interface Listetoritor prend non seulement en charge les opérations de suppression, mais prend également en charge les opérations d'ajout et de définition. L'interface Listotrator implémente l'interface itérateur, donc cet exemple ressemble à la méthode de suppression de l'itérateur. La seule différence est le type d'itérateur de chapeau et nous obtenons la méthode de l'itérateur - en utilisant la méthode listotrator (). Les fragments suivants montrent comment utiliser la méthode listterator.remove et listotrator.add pour remplacer le chapeau des lambeaux d'oreille par som <ombreros.
Ihat sombrero = new sombrero (); ;
À l'aide de ListIterator, l'appel de suppression et d'ajout peut être remplacé pour appeler une seule méthode de jeu:
Ihat sombrero = new sombrero (); );
Utilisez la méthode du flux dans Java 8
Dans Java8, les développeurs peuvent convertir une collection en flux et flux de filtre en fonction de certaines conditions. Cet exemple indique comment les chapeaux de filtre API de flux et évitent la conception en conception concurrentModification. HATS = HATS.STREAM ().
Copier le code du code comme suit:
.Collect (collectionners.tocollection (ArrayList :: new));
La méthode Collectors.Tocollection créera une nouvelle liste Array, qui est responsable du stockage de la valeur des chapeaux filtrés. Si les conditions de filtrage sont filtrées un grand nombre d'entrées, une grande liste d'arraie sera générée ici. Par conséquent, vous devez l'utiliser avec prudence.
Utilisez la méthode List.Removeif dans Java 8
Vous pouvez utiliser une autre méthode plus concise et claire dans la méthode Java 8 -reMoveif:
Copier le code du code comme suit:
Hat.removeif (ihat :: Hasearflaps);
En bas, il utilise iterator.remove pour terminer cette opération.
Utilisez une collection spéciale
Si vous décidez d'utiliser CopyOnwriteArrayList au lieu de ArrayList au début, il n'y aura pas de problème. Étant donné que CopyOnwriteArrayList fournit des méthodes modifiées (telles que Set, Add, Supprimer), elle ne modifiera pas le tableau de collection d'origine, mais crée une nouvelle version modifiée. Cela permet à Traversal de modifier la version d'origine, de sorte que la conception concurrente de la conception n'est pas jetée. Les inconvénients de cette collection sont également très évidents - une nouvelle collection est générée pour chaque modification.
Il existe d'autres ensembles adaptés à différents scénarios, tels que CopyOnwriteSet et ConcurrentHashMap.
En ce qui concerne une autre erreur qui peut se produire lors de modifications simultanées, il crée un flux à partir d'une collection. Le critère général pour le flux consiste à éviter de modifier la collection arrière-end lors de la vérification du flux. L'exemple suivant montrera comment gérer correctement le flux:
List <ihat> filedHats = hats.stream ().
La méthode PEEK collecte tous les éléments et effectue des actions établies pour chaque élément. Ici, l'action est d'essayer de supprimer les données d'une liste de base, ce qui est évidemment faux. Pour éviter de telles opérations, vous pouvez essayer certaines méthodes expliquées ci-dessus.
4. Défense
Parfois, afin de mieux collaborer, le code fourni par la bibliothèque standard ou le tiers doit se conformer aux dépendances communes. Par exemple, il est nécessaire de se conformer à l'accord conjoint entre HashCode et est égal pour s'assurer qu'une série de classes de collecte dans le cadre de collection Java et d'autres classes à l'aide du HashCode et des méthodes égales peuvent fonctionner normalement. Ne respectez pas des erreurs telles que l'exception ou la détruire la compilation de code;
Le code d'erreur peut se faufiler dans l'environnement de production, provoquant de nombreux effets négatifs. Cela comprend une mauvaise expérience de l'interface utilisateur, des rapports de données erronés, des performances médiocres, une perte de données ou plus. Heureusement, ces erreurs catastrophiques ne se produisent pas souvent. Le HashCode et les égaux ont été mentionnés auparavant que la scène qu'il apparaît peut être: la collection dépend de la cible pour comparer les objets ou les comparaisons, tout comme Hashmap et HashSet. En termes simples, il existe deux critères pour cet accord:
Si les deux objets sont égaux, le code de hachage doit être égal.
Si les deux objets ont le même code de hachage, ils peuvent être égaux ou différents.
Le premier critère de destruction, lorsque vous essayez de récupérer des données à partir d'un hashmap, cela entraînera des erreurs. Le deuxième critère signifie que les objets avec le même code de hachage ne sont pas nécessairement égaux.
Jetons un coup d'œil aux conséquences de la destruction du premier critère:
Public Static Class Boat {Private String Name; GetClass ()! int hashcode () {return (int) (math.random () * 5000);}}
Comme vous pouvez le voir, la classe de bateau réécrit les méthodes égales et codées de hash. Cependant, il a détruit l'accord parce que HashCode a renvoyé la valeur aléatoire pour le même objet pour chaque appel. Le code suivant ne devrait pas trouver de bateau appelé Enterprise dans Hashset, bien que nous ayons en fait ajouté ce type de bateau à l'avance:
Public static void main (String [] args) {set <Aat> Boats = New Hashset <> (); (Nouveau bateau ("Enterprise"));};}
Un autre accord est la méthode finalisée. Voici une référence au document Java officiel sur sa description fonctionnelle:
L'accord conventionnel de Finalise est: lorsque la machine virtuelle Javatm détermine que tout thread ne peut plus accéder à l'objet spécifié, cette méthode sera appelée. La méthode Finalise a plusieurs fonctions, y compris l'utilisation de cet objet pour être à nouveau disponible pour d'autres threads; Par exemple, la méthode Finalize qui indique l'objet de connexion d'entrée / sortie peut exécuter la transaction d'E / S explicite pour interrompre la connexion avant l'objet écarté permanent.
Vous pouvez décider d'utiliser la méthode Finalise dans un processeur de fichiers pour libérer des ressources, mais cette utilisation est mauvaise. Parce qu'il est appelé pendant le recyclage des ordures et que le temps de GC n'est pas sûr, le temps de finalisation ne sera pas garanti.
5. Utilisez le type d'origine au lieu de paramétrage
Selon la description du document Java: Le type d'origine est soit non paramétré, soit un membre non statique de RM (également non hérité de R ou interface parent). Avant l'introduction du type générique Java, il n'y avait pas de type alternatif primitif. Java a pris en charge la programmation générique de la version 1.5, et il ne fait aucun doute qu'il s'agit d'une amélioration de fonction importante. Cependant, en raison de la compatibilité arrière, il y a un piège ici qui peut détruire l'intégralité du système de type. Efforcez l'exemple:
Listofnumbers = new ArrayList ();
Il s'agit d'une liste de nombres définis comme la liste Array d'origine. Puisqu'il ne spécifie pas les paramètres de type, il peut y ajouter n'importe quel objet. Cependant, la dernière ligne cartaque les éléments qu'il contient pour type int et multiplié par 2, a imprimé les données après le double des données de la sortie standard.
Ce code ne fera pas d'erreur pendant la compilation, mais une fois qu'il s'exécutera, il lancera une erreur lors de sa course, car il essaie de cartographier le type de caractère en chirurgie plastique. De toute évidence, si les informations nécessaires sont masquées, le système de type n'aidera pas à rédiger un code de sécurité.
Pour résoudre ce problème, vous devez spécifier le type spécifique des objets de la collection:
Liste <Integer> listofnumbers = new ArrayList <() ();
La seule différence par rapport au code précédent est la ligne qui définit la collection:
Copier le code du code comme suit:
List <Integer> listofNumbers = new ArrayList <();
La compilation de code modifiée ne peut pas être transmise car elle essaie d'ajouter une chaîne à la collection du seul plastique de stockage attendu. Le compilateur affichera un message d'erreur et pointera vers la ligne qui ajoute vingt caractères à la liste. Le type générique de paramétrage est une bonne idée. Dans ce cas, le compilateur peut vérifier les types possibles, afin que les chances anormales d'exécution en raison d'incohérences soient considérablement réduites.
Le principal résumé des cinq programmeurs Java ci-dessus fait souvent des erreurs, j'espère que tout le monde pourra l'aimer.