La * 3e édition effective de Java * que j'ai commandée est enfin arrivée, j'ai donc résumé les changements de la deuxième édition. J'ai sauté les notes personnelles et les parties qui ne sont pas différentes de la deuxième édition, alors pardonnez-moi toute omission. La deuxième édition faisant référence à la version japonaise, il peut y avoir des incohérences par rapport au texte traduit. Je vous serais reconnaissant de bien vouloir signaler toute erreur.
Citation de Effective Java Third Edition ou sa traduction
Texte brut - Impression individuelle
Item 2
Un générateur avec des paramètres récursifs a été ajouté.
Vous pouvez facilement concevoir des sous-classes en définissant le générateur retourné par la classe abstraite parente Pizza
sur Builder <T extend Builder <T >> ʻet le type renvoyé par sa méthode ʻaddTopping ()
sur T
. ..
** Les classes d'utilité statique et les singletons ne conviennent pas aux classes dont le comportement peut être paramétré par des ressources **
Fournisseur <T>
plutôt que Passez l'usine.Item 6
L'exemple de création d'objets inutiles est passé de l'utilisation de Calendar
à String.matches ()
(le problème est qu'il crée Pattern
à chaque fois).
Le nettoyeur ajouté dans Java 9 a été évoqué.
** Les nettoyants ne sont pas aussi dangereux que les finaliseurs, mais ils sont toujours imprévisibles, lents et généralement inutiles **
attaque du finaliseur --Utilisez le finaliseur pour laisser l'objet défectueux dans le tas et appeler la méthode (la description elle-même était dans la 2ème édition, mais elle est plus accentuée)
Devrait implémenter ʻAutoCloseable` à la place
Item 10
Personnellement, je n'aime pas beaucoup AutoValue, alors j'utilise Lombok ou je l'écris en Kotlin.
IDEs do not make careless mistakes, and humans do
Les IDE ne font pas d'erreurs par inadvertance, mais les humains le font
Item 11
L'exemple de code a été modifié pour utiliser «Type.hashCode ()» (comme «Short.hashCode ()») pour générer le code de hachage. En ce qui concerne la documentation pour générer hashCode, l'expression est devenue plus forte de "ne pas le faire" à "ne pas le faire" (la documentation rend impossible de changer dans le futur).
Item 12
toString ()
dans les classes utilitaires statiques ou les énumérateursItem 13
clonable
(peuvent être partagées sans copier en premier lieu)Item 14
Type.compare ()
Comparator.comparing ... ()
Item 15
Item 19
@ implSpec
Item 20
** Il n'est pas toujours possible d'écrire une méthode par défaut sans changer toutes les implémentations possibles ** ** Il est toujours primordial de faire très attention lors de la conception d'une interface **
synchronizedCollection
La méthode par défaut n'est pas synchronisée (jusqu'à ce qu'elle soit remplacée)!Supprimé, fusionné dans l'élément 42
Item 24
Vous pouvez écrire plusieurs classes publiques dans un langage comme Kotlin, mais je pense qu'il est préférable de les séparer autant que possible pour plus de lisibilité.
"Avec un nouveau code" est parti (pas de refactorisation forcée)
Item 27:
Description de l'opérateur diamant
Item 30
Avec l'ajout de l'opérateur losange, la description de la méthode utilitaire newHashMap
pour omettre les paramètres de type a disparu lors de la création d'une nouvelle collection.
generic singleton pattern
private static UnaryOperator<Object> IDENTITY_FN = (t) -> t;
@SuppressWarnings("unchecked")
public static <T> UnaryOperator<T> identityFunction() {
return (UnaryOperator<T>) IDENTITY_FN;
}
Je ne pense pas avoir beaucoup d'occasions de l'utiliser dans des batailles réelles.
@ SafeVarargs
et arrêtez en cas de dangerItem 34
Convertir de String en Enum
private static final Map<String, Operation> stringToEnum = Stream.of(values()).collect(toMap(Object::toString, e -> e));
public static Optional<Operation> fromString(String symbol) {
return Optional.ofNufllable(stringToEnum.get(symbol));
}
Je souhaite personnellement lever une exception (traitée au point 55).
Le «jour de la paie» a été subtilement remanié.
Item 37
Pourquoi avez-vous changé Herb en Plant et Type en Lifecycle?
Item 39
JUnit -> JUnit 3 JUnit 4 est basé sur des annotations, je suis donc exactement les conseils de cette section.
Les types de paramètres Lambda ne sont pas utilisés sauf si cela rend le programme plus propre. Lambda manque de nom et de documentation. N'utilisez pas de lambdas si le processus n'est pas explicite ou s'il dépasse quelques lignes.
Function :: identity
vs x-> x
)Le modèle "méthode modèle", dans lequel les sous-classes remplacent les "méthodes primitives" pour personnaliser le comportement des superclasses, est beaucoup moins attrayant. Une alternative moderne consiste à fournir une fabrique ou un constructeur statique qui accepte les objets fonction qui font la même chose.
Utilisez le standard plutôt que de créer votre propre interface fonctionnelle
Lors de la définition de votre propre interface fonctionnelle
Largement utilisé et bénéficiant de noms descriptifs
Si vous avez un contrat fortement lié
Si vous bénéficiez de votre propre méthode par défaut
Utilisez @ FunctionalInterface
Ne créez pas différentes méthodes surchargées qui ont des interfaces fonctionnelles différentes dans la même position que les arguments si elles peuvent être ambiguës pour le client.
Runnable
et Callable <T>
.just because you can doesn't mean you should
** La surutilisation des flux rend le programme difficile à lire et à maintenir **
Ça me fait mal aux oreilles
** L'utilisation de méthodes d'assistance dans le code qui utilise des pipelines de flux est encore plus importante que dans le code qui utilise des itérateurs. ** **
char
Le nom de la méthode (
primes
) est une nomenclature plurielle qui décrit les éléments du flux. Cette convention de dénomination améliore la lisibilité du pipeline de flux et est fortement recommandée pour toutes les méthodes qui renvoient un flux.
L'instruction
forEach
ne doit être utilisée que pour rapporter les résultats du traitement d'un flux, pas pour effectuer un traitement.
Il est facile de dire forEach (e-> list.add (e))
.
Si vous écrivez une API publique qui renvoie une séquence, vous devez l'écrire non seulement pour ceux qui veulent écrire des pipelines de flux, mais aussi pour ceux qui veulent écrire des instructions for-each.
** Ne stockez pas de grandes séquences en mémoire juste pour les renvoyer sous forme de collection. ** **
Envisagez d'implémenter une collection dans un but particulier.
** Si la source est
Stream.iterate
ou si la limite de l'opération intermédiaire` est utilisée, la parallélisation du pipeline n'améliorera pas les performances. ** **
** La mise en parallèle des flux d'instances ʻArrayList
,
HashMap,
HashSet,
ConcurrentHashMap, les tableaux, la plage ʻint
et la plagelongue
a le plus grand gain de performance. Faisons le. ** **
La parallélisation des flux non seulement ralentit les performances, mais peut également entraîner des résultats incorrects et un comportement imprévisible.
Différence entre forEach
et forEachOrdered
Guide approximatif: les performances peuvent s'améliorer si `` éléments de flux x lignes de code> 100000 '' est dépassé Source dans le livre: Quand utiliser des flux parallèles
Il est important de se rappeler que la parallélisation de flux est une optimisation des performances. Comme pour toute optimisation, vous devez mesurer les performances avant et après la modification pour vous assurer que vous devez le faire.
Item 49
Item 50
**
Date
est obsolète et ne devrait plus être utilisée dans le nouveau code **
** Les types de conteneurs et les options telles que les cartes, les flux et les tableaux ne doivent pas être facultativement enveloppés. Déclarez une méthode pour renvoyer ʻOptional
`si elle ne renvoie pas de résultat, * et *, et que le client doit faire quelque chose de spécial. ** **
Utilisez ʻOptionalInt, ʻOptionalLong
, ʻOptionalDouble. Si c'est ʻOptional <T>
, la boxe automatique se produira et les performances se détérioreront.
N'utilisez pas d'options pour les clés de collection ou de tableau, les valeurs ou les éléments
La sauvegarde des options dans les champs est souvent un code "odorant", mais cela peut aussi être justifié (par exemple, si vous avez beaucoup de champs optionnels et que vous avez juste besoin de renvoyer le optionnel du getter).
Item 56
@ implSpec
Item 59
ThreadLocalRandom
plutôt que Random
Effacer
Item 75
comme argument à ʻIndexOutOfBoundsException
dans Java 9.Le flux a été ajouté en tant que candidat.
Le danger de la sérialisation est fortement souligné.
** Le meilleur moyen d'éviter les vulnérabilités de sérialisation est de ne rien désérialiser ** ** Il n'y a aucune raison d'utiliser la sérialisation Java sur les systèmes nouvellement écrits **
La meilleure chose à faire est de ** ne jamais désérialiser les données non fiables **
java.io.ObjectInputFilter
En conclusion, la sérialisation est dangereuse et ne doit pas être utilisée.
Vieux | Nouveau |
---|---|
AMD Opteron 170 | Core i7-4770K |
2GB RAM | DDR3-1866 16GB RAM |
Windows XP | Windows 7 Professional SP1 |
JDK 1.6 Java HotSpot | Azul Zulu 9.0.0.15 |
Recommended Posts