Efficacité de Java 3rd Edition Chapitre 4 Classes et interfaces
[Effective Java 3rd Edition](https://www.amazon.co.jp/Effective-Java-%E7%AC%AC3%E7%89%88-%E3%], qui est un livre indispensable pour les utilisateurs Java intermédiaires et supérieurs. 82% B8% E3% 83% A7% E3% 82% B7% E3% 83% A5% E3% 82% A2% E3% 83% BB% E3% 83% 96% E3% 83% AD% E3% 83% 83% E3% 82% AF-ebook / dp / B07RHX1K53) a une version Kindle, donc je vais le résumer.
Précédent: Méthodes efficaces du chapitre 3 de Java 3rd Edition communes à tous les objets
Suivant: Génériques du chapitre 5 de Java 3e édition efficaces
Point 15 Minimiser l'accessibilité aux classes et aux membres
- Chaque classe ou membre doit être aussi inaccessible que possible.
Classes et interfaces de premier niveau
--Il y a public et package private, et il devrait être package private autant que possible. Parce qu'il ne s'agit plus d'une API publique pour les packages.
- Si une classe ou une interface privée de package de niveau supérieur est utilisée par une seule classe, envisagez d'en faire une classe imbriquée privée dans cette classe.
Membres (champs, méthodes, classes imbriquées, interfaces imbriquées)
- Tout doit être privé au début et le package privé uniquement lorsque vous devez accéder à d'autres classes du même package.
- En ce qui concerne les membres de la classe publique, si le paquet passe de privé à protégé, l'accessibilité sera considérablement augmentée.
- Le besoin de membres protégés devrait être relativement rare.
- Lors du remplacement d'une méthode d'une super-classe, le niveau d'accès de la méthode dans la super-classe ne peut pas être restreint dans la sous-classe (spécification Java).
- Dans une certaine mesure, le relâchement des restrictions d'accès aux classes, interfaces et membres est autorisé à faciliter les tests. Du privé au packaging privé. Rien de plus n'est accepté.
- Le champ d'instance ne doit pas être public. Lorsqu'il s'agit d'une référence d'objet variable non finale, il renonce à limiter les valeurs qui peuvent être stockées dans ce champ. Par conséquent, les classes avec des champs de variables publiques ne sont généralement pas thread-safe.
--Utilisez public static final pour exposer les constantes. Il est d'usage d'utiliser des noms en majuscules séparés par des traits de soulignement. Il est impératif d'avoir un type de données de base ou une référence à un objet immuable. Parce que la valeur va changer. Notez que les tableaux de longueur non nulle sont toujours variables.
//Faille de sécurité potentielle (le contenu de la baie peut être modifié)
public static final Thing[] VALUES = { ... };
//Solution 1. Renvoie une liste publique immuable
private static final Thing[] PRIVATE_VALUES = { ... };
public static final List<Thing> VALUES =
Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));
//Solution 2. Renvoie une copie du tableau dans la méthode publique
private static final Thing[] PRIVATE_VALUES = { ... };
public static final Thing[] values() {
return PRIVATE_VALUES.clone();
}
Élément 16 Dans la classe publique, utilisez la méthode d'accesseur au lieu du champ public.
- Les classes publiques ne doivent pas exposer les champs variables. Il doit avoir un champ privé et une méthode d'accès public (getter), et un mutateur (setter) pour les classes de variables.
- Pour les classes imbriquées privées ou privées de package, exposer leurs champs de données directement est essentiellement très bien.
Point 17 Minimiser la variabilité
- L'objet immuable est simple. Essentiellement thread-safe.
- Pour les classes immuables, il n'est pas nécessaire de fournir une méthode de clonage ou un constructeur de copie, et il ne doit pas être fourni.
- Pour rendre une classe immuable, suivez les cinq principes suivants.
- Ne fournit pas de méthode pour modifier l'état d'un objet.
- N'étendez pas les classes.
- Rendre tous les plis définitifs.
- Rendre tous les plis privés.
--Garantie d'un accès exclusif aux composants variables.
- L'inconvénient pratique des objets immuables est qu'ils nécessitent des objets séparés pour différentes valeurs individuelles.
- Les classes doivent être immuables à moins qu'il n'y ait une bonne raison de les rendre variables.
- Si vous ne pouvez pas rendre une classe immuable, vous devez limiter au maximum sa variabilité.
Rubrique 18 Sélectionnez la composition de l'héritage
- L'héritage, lorsqu'il est utilisé de manière incorrecte, crée un logiciel fragile. L'héritage rompt l'encapsulation. Le bon fonctionnement des sous-classes dépend de l'implémentation des superclasses.
- Au lieu d'étendre une classe existante, donnez à la nouvelle classe un champ privé qui fait référence à une instance de la classe existante. Cette conception s'appelle la composition.
- Chaque méthode d'instance de la nouvelle classe appelle la méthode correspondant à l'instance de classe existante qu'elle contient et renvoie le résultat. C'est ce qu'on appelle un transfert, et la nouvelle classe de méthodes s'appelle une méthode de transfert.
- La combinaison de la composition et du transfert est parfois appelée à peu près délégation. Techniquement, ce n'est pas une délégation à moins que l'objet wrapper ne passe lui-même à l'objet wrapped.
Point 19 Conception et document pour l'héritage, sinon interdire l'héritage
- La conception d'une classe pour l'héritage impose des restrictions considérables à cette classe. Toute auto-utilisation de la classe doit être documentée, et une fois documentée, elle doit être suivie tant que la classe existe.
--Utilisez la balise Javadoc de
@ implSpec
pour documenter l'héritage.
- La meilleure solution est d'interdire les sous-classes de classes qui ne sont ni conçues ni documentées pour un sous-classement sûr. Il existe deux façons d'interdire les sous-classes.
- Déclarez la fin de la classe.
- Rendez le constructeur de classe privé ou le package privé et ajoutez une méthode de fabrique statique publique comme alternative au constructeur.
Élément 20 Sélectionnez une interface sur une classe abstraite
- S'il existe une implémentation évidente d'une méthode avec une interface, envisagez de fournir une aide à l'implémentation dans le format de méthode par défaut. La fourniture de méthodes par défaut pour les méthodes Object telles que equals et hashCode n'est pas autorisée.
- L'interface n'est pas autorisée à contenir des champs d'instance ou des membres statiques non publics (autres que les méthodes statiques privées).
- En fournissant une classe d'implémentation squelette abstraite qui accompagne une interface, vous pouvez combiner les atouts de l'interface et de la classe abstraite. L'implémentation squelette est basée sur les méthodes de base de l'interface et implémente les méthodes non basiques restantes de l'interface. La plupart de l'implémentation de l'interface se fait en étendant l'implémentation du squelette. (* Méthode de modèle * modèle)
- Par convention, la classe d'implémentation squelette est nommée Abstract * Interface *.
--Par exemple, le framework de collection fournit des implémentations squelettes qui accompagnent chaque interface de collection principale, telles que AbstractCollection, AbstractSet, AbstractList et AbstractMap.
- Le grand avantage de l'implémentation squelette est qu'elle fournit une assistance d'implémentation, qui est une classe abstraite, sans imposer de restrictions sérieuses sur le rôle de la classe abstraite en tant que définition de type.
- Une classe qui implémente une interface peut contenir une instance d'une classe interne privée qui étend l'implémentation du squelette et transfère les appels d'interface à cette instance. Cette technique est appelée héritage pseudo-multiple.
Point 21 Concevoir l'interface du futur
- Avant Java8, lorsque vous ajoutez une nouvelle méthode à une interface, l'implémentation existante n'a pas encore cette méthode et vous obtenez une erreur de compilation. Java 8 a ajouté la syntaxe de méthode par défaut, mais l'ajout de méthodes aux interfaces existantes est risqué.
- La méthode par défaut peut être en mesure de compiler l'implémentation de l'interface sans erreurs ni avertissements, mais elle peut échouer à l'exécution.
- Même si les méthodes par défaut font partie de la plate-forme Java, une conception d'interface soignée reste importante. L'ajout d'une méthode comporte beaucoup de risques.
- Il est important de tester une nouvelle interface avant de la publier. Au minimum, trois implémentations différentes doivent être implémentées et testées. Il est difficile de corriger les défauts d'interface après la publication.
Rubrique 22 Utiliser l'interface uniquement pour définir le type
--L'interface, lors de l'implémentation d'une classe, agit comme un type qui peut être utilisé pour référencer cette instance.
- Vous ne devez pas utiliser l'interface constante, qui n'est qu'une interface pour définir des constantes.
- Les constantes doivent être fournies dans le type enum ou dans des classes d'utilité non individualisables.
Élément 23 Sélectionnez une hiérarchie de classes plutôt qu'une classe balisée
- Une classe qui a deux caractéristiques ou plus et qui bascule entre elles avec enum est appelée une classe étiquetée et présente de nombreux inconvénients. Difficile à lire, mémoire accrue, redondante, apologétique et inefficace.
--Sous-type pour définir un seul type de données pouvant représenter des objets avec plusieurs caractéristiques.
--Définissez une classe abstraite qui contient des méthodes abstraites pour des opérations individuelles. S'il existe un comportement ou des données communs, placez-les dans une classe abstraite.
--Définissez une sous-classe de réalisation de la classe racine pour chaque caractéristique.
Élément 24 Sélectionnez une classe de membre statique sur une classe de membre non statique
――Quatre types de classes imbriquées
--Classe membre statique (classe interne)
- Classe de membre non statique
--Classe anonyme
--Classe locale
- La seule différence syntaxique entre les classes membres statiques et non statiques est que les classes membres statiques ont un modificateur statique dans leur déclaration. Ces deux types de classes imbriquées sont différents.
- Chaque instance d'une classe membre non statique est implicitement associée à l'instance englobante de la classe qui la contient. Dans une méthode d'instance d'une classe membre non statique, la méthode peut être appelée sur l'instance englobante, ou une référence à l'instance englobante peut être obtenue à l'aide de la syntaxe qualifiée this.
- (Prévu pour être ajouté)
classe de membre statique
class Outer {
private int outerField;
private static int a;
//classe de membre statique
static class Inner {
void innerMethod() {
//Uniquement disponible pour les membres de classe externes statiques
a = 10;
}
}
//Méthodes à l'intérieur de la classe externe
void outerMethod() {
Inner ic = new Inner();
}
}
class Main {
public static void main(String[] args) {
// Outer.Utilisé en intérieur
Outer.Inner ic = new Outer.Inner();
ic.innerMethod();
}
}
Classe de membre non statique
class Outer {
private static int outerField;
private int b;
//Classe de membre non statique
class Inner {
void innerMethod() {
outerField = 10;
b = 5;
}
}
//Méthodes à l'intérieur de la classe externe
void outerMethod() {
Inner ic = new Inner();
}
}
class Main {
public static void main(String[] args) {
Outer o = new Outer();
// o.Utilisé dans le neuf
Outer.Inner in = o.new Inner();
}
}
Élément 25 Limiter les fichiers source à une seule classe de premier niveau
- Ne mettez pas plusieurs classes de niveau supérieur dans un seul fichier source. La raison en est que le compilateur peut ne pas reconnaître correctement la classe.