[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: Génériques du chapitre 5 de Java 3ème édition efficaces Suivant: Effective Java 3rd Edition Chapter 7 Lambda and Stream
--enum est une classe qui expose une instance pour chaque constante d'énumération via le champ final statique public. --enum n'a pas de constructeur accessible, il est donc effectivement définitif. --Le type enum est une version généralisée de singleton, qui est essentiellement une énumération à un seul élément.
Type d'énumération avec données et comportement
public enum Planet {
MERCURY(3.302e+23, 2.439e6),
VENUS(4.869e+24, 6.052e6),
EARTH(5.975e+24, 6.378e6),
MARS(6.419e+23, 3.393e6);
//réduction
private final double mass; //Masse
private final double radius; //rayon
private final double surfaceGravity; //Gravité de surface
private static final double G = 6.67300E-11; //Constante gravitationnelle universelle
//Constructeur qui associe des données à la constante enum
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
surfaceGravity = G * mass / (radius * radius);
}
public double mass() {
return mass;
}
public double radius() {
return radius;
}
public double surfaceGravity() {
return surfaceGravity;
}
//
public double getSurfaceWeight(double mass) {
return mass * surfaceGravity; // F = ma
}
//Exemple d'appel
public static void main(String[] args) {
//Combien pèsent 60 kg sur terre sur les autres planètes?
double earthWeight = Double.parseDouble("60.0");
double mass = earthWeight / Planet.EARTH.surfaceGravity();
for (Planet p: Planet.values()) {
System.out.printf("Weight on %s is %f%n", p, p.getSurfaceWeight(mass));
}
}
}
//résultat
Weight on MERCURY is 22.674402
Weight on VENUS is 54.303060
Weight on EARTH is 60.000000
Weight on MARS is 22.776240
--Enum type avec corps de classe spécifique à la constante et données spécifiques à la constante
Type enum avec corps de classe spécifique à la constante et données spécifiques à la constante
public enum Operation {
PLUS("+") {
//Remplacer appliquer
public double apply(double x, double y) {
return x + y;
}
},
MINUS("-") {
public double apply(double x, double y) {
return x - y;
}
},
TIMES("*") {
public double apply(double x, double y) {
return x * y;
}
},
DIVIDE("/") {
public double apply(double x, double y) {
return x / y;
}
};
private final String symbol;
@Override
public String toString() {
return symbol;
}
//constructeur
Operation(String symbol) {
this.symbol = symbol;
}
//Si vous définissez une méthode de manière abstraite, chaque constante euum est requise pour remplacer la méthode
public abstract double apply(double x, double y);
//Exemple d'appel
public static void main(String[] args) {
double x = 2.0;
double y = 4.0;
for (Operation op : Operation.values()) {
System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y));
}
}
}
Enregistrez la valeur dans le repli de l'instance
public enum Ensemble {
SOLO(1), DUET(2), TRIO(3), QUARTET(4), QUINTET(5),
SEXTET(6), SEPTET(7), OCTET(8), DOUBLE_QUARTET(8),
NONET(0), DECTET(10), TRIPLE_QUARTET(12);
private final int numberOfMusicians;
//Si vous souhaitez avoir une valeur numérique, définissez-la dans le constructeur
Ensemble(int size) {
this.numberOfMusicians = size;
}
public int getNumberOfMusicians() {
return numberOfMusicians;
}
//Exemple d'appel
public static void main(String[] args) {
for (Ensemble e : Ensemble.values()) {
System.out.printf("%s %s %n",e.name(), e.numberOfMusicians);
}
}
}
//Résultat d'exécution
SOLO 1
DUET 2
TRIO 3
QUARTET 4
QUINTET 5
SEXTET 6
SEPTET 7
OCTET 8
DOUBLE_QUARTET 8
NONET 0
DECTET 10
TRIPLE_QUARTET 12
--Bitfield est un moyen d'exprimer abc comme 1 + 2 + 4 = 7 quand a = 1, b = 2, c = 4, d = 8. --EnumSet est un ensemble qui peut avoir plusieurs types d'énumération.
Exemple EnumSet
public class Text {
public enum Style { BOLD, ITALIC, UNDERLINE STRIKETHROUGH }
//Recevoir EnumSet avec Set
public void applyStyles(Set<Style> styles) { ... }
}
//Exemple d'utilisation d'EnumSet
text.applyStyles(EnumSet.of(Style.BOLD, Style.ITALIC);
--EnumSet est une implémentation de carte à grande vitesse conçue pour utiliser enum comme clé.
Exemple d'utilisation d'EnumSet
public class Plant {
enum LifeCycle {ANNUAL, PERENNIAL, BIENNIAL;}
final String name;
final LifeCycle lifeCycle;
Plant(String name, LifeCycle lifeCycle) {
this.name = name;
this.lifeCycle = lifeCycle;
}
@Override
public String toString() {
return name;
}
//Exemple d'appel
public static void main(String[] args) {
var garden = List.of(new Plant("annual", LifeCycle.ANNUAL),
new Plant("biennial1", LifeCycle.BIENNIAL),
new Plant("biennial2", LifeCycle.BIENNIAL));
//Créer une instance d'EnumMap
Map<LifeCycle, Set<Plant>> plantsByLifeCycle =
new EnumMap<>(Plant.LifeCycle.class);
//Clé: Enum type LifeCycle, ajoutez Map avec HashSet avec une valeur vide
for (Plant.LifeCycle lc : Plant.LifeCycle.values()) {
plantsByLifeCycle.put(lc, new HashSet<>());
}
//Ajoutez une valeur au HashSet de la carte.
for (Plant p : garden) {
plantsByLifeCycle.get(p.lifeCycle).add(p);
}
System.out.println(plantsByLifeCycle);
}
}
//Résultat de sortie
{ANNUAL=[annual], PERENNIAL=[], BIENNIAL=[biennial1, biennial2]}
--Le type enum ne peut pas être étendu, mais il est possible d'implémenter l'interface avec le type enum.
Implémenter l'interface avec enum
//Définition d'interface
public interface Operation {
double apply(double x, double y);
}
//Implémenter l'interface
enum BasicOperation implements Operation {
PLUS("+") {
//Mettre en œuvre appliquer
public double apply(double x, double y) {
return x + y;
}
},
MINUS("-") {
public double apply(double x, double y) {
return x - y;
}
},
TIMES("*") {
public double apply(double x, double y) {
return x * y;
}
},
DIVIDE("/") {
public double apply(double x, double y) {
return x / y;
}
};
private final String symbol;
//constructeur
BasicOperation(String symbol) {
this.symbol = symbol;
}
@Override
public String toString() {
return symbol;
}
}
//Type d'énumération étendu
enum ExtendedOperation implements Operation {
EXP("^") {
public double apply(double x, double y) {
return Math.pow(x, y);
}
},
REMAINDER("%") {
public double apply(double x, double y) {
return x % y;
}
};
private final String symbol;
//constructeur
ExtendedOperation(String symbol) {
this.symbol = symbol;
}
@Override
public String toString() {
return symbol;
}
}
//Exemple d'appel
class Main {
public static void main(String[] args) {
double x = 2.0;
double y = 4.0;
text1(BasicOperation.class, x, y);
text1(ExtendedOperation.class, x, y);
text2(Arrays.asList(BasicOperation.values()), x, y);
text2(Arrays.asList(ExtendedOperation.values()), x, y);
}
//Passer comme énumération et sous-type d'opération
private static <T extends Enum<T> & Operation> void text1(Class<T> opEnumType, double x, double y) {
for (Operation op : opEnumType.getEnumConstants()) {
System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y));
}
}
//Comment passer en utilisant le type générique de bordure
private static void text2(Collection<? extends Operation> opSet, double x, double y) {
for (Operation op : opSet) {
System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y));
}
}
}
//Résultat d'exécution
2.000000 + 4.000000 = 6.000000
2.000000 - 4.000000 = -2.000000
2.000000 * 4.000000 = 8.000000
2.000000 / 4.000000 = 0.500000
2.000000 ^ 4.000000 = 16.000000
2.000000 % 4.000000 = 2.000000
2.000000 + 4.000000 = 6.000000
2.000000 - 4.000000 = -2.000000
2.000000 * 4.000000 = 8.000000
2.000000 / 4.000000 = 0.500000
2.000000 ^ 4.000000 = 16.000000
2.000000 % 4.000000 = 2.000000
// @Tester la définition de l'annotation
@Retention(RetentionPolicy.RUNTIME) //L'annotation de test doit être conservée lors de l'exécution
@Target(ElementType.METHOD) //Uniquement autorisé pour les déclarations de méthode
@interface Test {
}
//Classe testée
class Sample {
@Test
public static void m1() {
}
public static void m2() {
}
@Test
public static void m3() {
throw new RuntimeException("Boom");
}
public static void m4() {
}
@Test
public static void m5() {
}
public static void m6() {
}
@Test
public static void m7() {
throw new RuntimeException("Crash");
}
public static void m8() {
}
}
///Classe de traitement des annotations de test
class RunTests {
public static void main(String[] args) throws Exception {
int tests = 0;
int passed = 0;
Class<?> testClass = Class.forName("sec39.Sample");
//Parcourez toutes les méthodes du test
for (Method m : testClass.getDeclaredMethods()) {
// @Est-ce avec une annotation Test?
if (m.isAnnotationPresent(Test.class)) {
tests++;
try {
//Appel de méthode testée
m.invoke(null);
passed++;
} catch (InvocationTargetException wrappedExc) {
Throwable exc = wrappedExc.getCause();
System.out.println(m + " failed: " + exc);
} catch (Exception e) {
System.out.println("Invalid @Test: " + m);
}
}
}
System.out.printf("Passed: %d, Failed: %d%n", passed, tests - passed);
}
}
//Résultat d'exécution
public static void sec39.Sample.m7() failed: java.lang.RuntimeException: Crash
public static void sec39.Sample.m3() failed: java.lang.RuntimeException: Boom
Passed: 2, Failed: 2
@ Override
détectera qu'elle n'a pas été remplacée.@ Override
, l'EDI vous avertira afin que vous puissiez éviter les remplacements involontaires.Recommended Posts