[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