Effektive Java 3rd Edition Kapitel 6 Aufzählung und Anmerkungen

[Effective Java 3rd Edition](https://www.amazon.co.jp/Effective-Java-%E7%AC%AC3%E7%89%88-%E3%], ein Muss für fortgeschrittene Java-Benutzer und höher. 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) hat eine Kindle-Version, daher werde ich sie zusammenfassen.

Zurück: Effektive Java 3rd Edition Kapitel 5 Generika Weiter: Effektive Java 3rd Edition, Kapitel 7, Lambda und Stream

Punkt 34 Verwenden Sie enum anstelle von int

--enum ist eine Klasse, die eine Instanz für jede Aufzählungskonstante über das öffentliche statische Endfeld verfügbar macht. --enum hat keinen zugänglichen Konstruktor, daher ist es effektiv endgültig.

Aufzählungstyp mit Daten und Verhalten


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);
    //Kürzung

    private final double mass; //Masse
    private final double radius; //Radius
    private final double surfaceGravity; //Oberflächengravitation

    private static final double G = 6.67300E-11; //Universelle Gravitationskonstante
    //Konstruktor, der Daten mit der Enum-Konstante verknüpft
    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
    }
    //Beispiel aufrufen
    public static void main(String[] args) {
     //Wie viel wiegen 60 kg auf der Erde auf anderen Planeten?
        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));
        }
    }
}

//Ergebnis
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-Typ mit konstantem Klassenkörper und konstanten spezifischen Daten

Aufzählungstyp mit konstantenspezifischem Klassenkörper und konstantenspezifischen Daten


public enum Operation {
    PLUS("+") {
        //Überschreiben anwenden
        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;
    }
    //Konstrukteur
    Operation(String symbol) {
        this.symbol = symbol;
    }
    //Wenn Sie eine Methode abstrakt definieren, ist jede Vakuumkonstante erforderlich, um die Methode zu überschreiben
    public abstract double apply(double x, double y);

    //Beispiel aufrufen
    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));
        }
    }
}

Punkt 35 Verwenden Sie Instanzfelder anstelle von Bestellnummern

Speichern Sie den Wert in der Instanzfalte


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;

    //Wenn Sie einen numerischen Wert haben möchten, definieren Sie ihn im Konstruktor
    Ensemble(int size) {
        this.numberOfMusicians = size;
    }

    public int getNumberOfMusicians() {
        return numberOfMusicians;
    }

    //Beispiel aufrufen
    public static void main(String[] args) {
        for (Ensemble e : Ensemble.values()) {
            System.out.printf("%s %s %n",e.name(), e.numberOfMusicians);
        }
    }
}
//Ausführungsergebnis
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 

Punkt 36 Verwenden Sie EnumSet anstelle des Bitfelds

EnumSet-Beispiel


public class Text {
  public enum Style { BOLD, ITALIC, UNDERLINE STRIKETHROUGH }
  //Empfangen Sie EnumSet mit Set
  public void applyStyles(Set<Style> styles) { ... }
}
//Beispiel für die Verwendung von EnumSet
text.applyStyles(EnumSet.of(Style.BOLD, Style.ITALIC);

Punkt 37 Verwenden Sie EnumMap anstelle des Ordnungsindex

--EnumSet ist eine Hochgeschwindigkeits-Map-Implementierung, die Enum als Schlüssel verwendet.

Beispiel für die Verwendung von 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;
    }

    //Beispiel aufrufen
    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));
        //Erstellen Sie eine Instanz von EnumMap
        Map<LifeCycle, Set<Plant>> plantsByLifeCycle =
                new EnumMap<>(Plant.LifeCycle.class);
        //Schlüssel: Aufzählungstyp LifeCycle, Map mit HashSet mit leerem Wert hinzufügen
        for (Plant.LifeCycle lc : Plant.LifeCycle.values()) {
            plantsByLifeCycle.put(lc, new HashSet<>());
        }
        //Fügen Sie dem HashSet der Karte einen Wert hinzu.
        for (Plant p : garden) {
            plantsByLifeCycle.get(p.lifeCycle).add(p);
        }
        System.out.println(plantsByLifeCycle);
    }
}
//Ausgabeergebnis
{ANNUAL=[annual], PERENNIAL=[], BIENNIAL=[biennial1, biennial2]}

Punkt 38: Imitieren Sie die erweiterbare Enumeration mit einer Schnittstelle

Implementieren Sie die Schnittstelle mit enum


//Schnittstellendefinition
public interface Operation {
    double apply(double x, double y);
}
//Implementieren Sie die Schnittstelle
enum BasicOperation implements Operation {
    PLUS("+") {
        //Implementieren anwenden
        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;

    //Konstrukteur
    BasicOperation(String symbol) {
        this.symbol = symbol;
    }

    @Override
    public String toString() {
        return symbol;
    }
}

//Erweiterter Aufzählungstyp
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;

    //Konstrukteur
    ExtendedOperation(String symbol) {
        this.symbol = symbol;
    }

    @Override
    public String toString() {
        return symbol;
    }
}

//Beispiel aufrufen
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);
    }

    //Als Aufzählung und Operationstyp übergeben
    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));
        }
    }

    //Übergeben mit dem Rahmen-Platzhaltertyp
    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));
        }
    }
}
//Ausführungsergebnis
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

Punkt 39 Wählen Sie eine Anmerkung anstelle eines Namensmusters aus

--Anmerkungen sollten verwendet werden, da es ein Nachteil ist, Methodennamen usw. aufgrund von Namensmustern besondere Eigenschaften zu geben. (Beispiel: testSafetyOverride beginnt mit test, daher ist test med ein schlechtes Beispiel.)


// @Test Annotation Definition
@Retention(RetentionPolicy.RUNTIME) //Testanmerkungen sollten zur Laufzeit beibehalten werden
@Target(ElementType.METHOD) //Nur für Methodendeklarationen zulässig
@interface Test {
}

//Getestete Klasse
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() {
    }
}

///Test Annotation Processing Class
class RunTests {
    public static void main(String[] args) throws Exception {
        int tests = 0;
        int passed = 0;
        Class<?> testClass = Class.forName("sec39.Sample");
        //Durchlaufen Sie alle Methoden im Test
        for (Method m : testClass.getDeclaredMethods()) {
            // @Ist es mit einer Testanmerkung?
            if (m.isAnnotationPresent(Test.class)) {
                tests++;
                try {
                    //Getesteter Methodenaufruf
                    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);
    }
}

//Ausführungsergebnis
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

Punkt 40 Verwenden Sie immer die Überschriftenanmerkung

Punkt 41 Verwenden Sie die Markierungsschnittstelle, um den Typ zu definieren

Recommended Posts

Effektive Java 3rd Edition Kapitel 6 Aufzählung und Anmerkungen
Effektive Java 3rd Edition Kapitel 4 Klassen und Schnittstellen
Effektive Java 3rd Edition Kapitel 7 Lambda und Stream
Effektive Java 3rd Edition Kapitel 5 Generika
Effektive Java 3rd Edition Kapitel 8 Methoden
Effektive Java 3rd Edition Kapitel 2 Objekterstellung und Verschwindenlassen
Effektives Java 3rd Edition Kapitel 9 Programm Allgemein
Effektive Java 3rd Edition Kapitel 3 Allen Objekten gemeinsame Methoden
Was hat sich zwischen Effective Java 2nd Edition und 3rd Edition geändert?
Effektives Java Kapitel 2
Effektives Java Kapitel 6 34-35
Effektives Java Kapitel 4 15-22
Effektives Java Kapitel 3
effektive Java 3. Zusammenfassung
Effektive Java 3rd Edition Abschnitt 85 Auswählen einer Alternative zur Java-Serialisierung
[Read Effective Java] Kapitel 2 Punkt 7 "Vermeiden Sie Finalizer"
Diskriminierung von Enum in Java 7 und höher
Parallele und parallele Verarbeitung in verschiedenen Sprachen (Java Edition)
Effektive Zusammenfassung der Umfrage zu Java 2nd Edition
[Read Effective Java] Kapitel 3 Punkt 10 "Immer toString überschreiben"
Ich habe versucht, Effective Java 3rd Edition "fast alle Kapitel" in "leicht lesbarem Japanisch" zu erklären.
Java und JavaScript
XXE und Java
Konvertieren Sie Java Enum Enumeration und JSON von und nach Jackson
[Read Effective Java] Kapitel 3 Punkt 12 "Berücksichtigung der Implementierung von Comparable"
Zusammenfassung des ToString-Verhaltens mit Java- und Groovy-Annotationen
Der Vergleich von enum ist == und gleich ist gut [Java]
[Read Effective Java] Kapitel 2 Punkt 6 "Veraltete Objektreferenzen entfernen"
Aktualisierungen von Effective Java Third Edition 2nd Edition Persönliche Notizen
Ich werde einen Auszug dessen schreiben, was ich beim Lesen von Effective Java 3rd Edition interessant fand