public static final int APPLE_FUJI = 0;
比較脆弱,若是與枚舉常量關聯的int發生了變化,客戶端需從新編譯。另外沒有便利的方法將常量名稱打印出來。java
public enum Apple { FUJI,PIPPIN,GRANNY_SMITH }
實例app
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), JUPITER(1.899e+27, 7.149e7), SATURN (5.685e+26, 6.027e7), URANUS (8.683e+25, 2.556e7), NEPTUNE(1.024e+26, 2.477e7); private final double mass; // In kilograms private final double radius; // In meters private final double surfaceGravity; // In m / s^2 // Universal gravitational constant in m^3 / kg s^2 private static final double G = 6.67300E-11; // Constructor 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 surfaceWeight(double mass) { return mass * surfaceGravity; // F = ma } }
public enum Operation { PLUS("+") { double apply(double x, double y) { return x + y; } }, MINUS("-") { double apply(double x, double y) { return x - y; } }, TIMES("*") { double apply(double x, double y) { return x * y; } }, DIVIDE("/") { double apply(double x, double y) { return x / y; } }; private final String symbol; Operation(String symbol) { this.symbol = symbol; } @Override public String toString() { return symbol; } abstract double apply(double x, double y); // Implementing a fromString method on an enum type - Page 154 private static final Map<String, Operation> stringToEnum = new HashMap<String, Operation>(); static { // Initialize map from constant name to enum constant for (Operation op : values()) stringToEnum.put(op.toString(), op); } // Returns Operation for string, or null if string is invalid public static Operation fromString(String symbol) { return stringToEnum.get(symbol); } // Test program to perform all operations on given operands public static void main(String[] args) { double x = Double.parseDouble(args[0]); double y = Double.parseDouble(args[1]); for (Operation op : Operation.values()) System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y)); } }
// The strategy enum pattern enum PayrollDay { MONDAY(PayType.WEEKDAY), TUESDAY(PayType.WEEKDAY), WEDNESDAY(PayType.WEEKDAY), THURSDAY(PayType.WEEKDAY), FRIDAY(PayType.WEEKDAY), SATURDAY(PayType.WEEKEND), SUNDAY(PayType.WEEKEND); private final PayType payType; PayrollDay(PayType payType) { this.payType = payType; } double pay(double hoursWorked, double payRate) { return payType.pay(hoursWorked, payRate); } // The strategy enum type private enum PayType { WEEKDAY { double overtimePay(double hours, double payRate) { return hours <= HOURS_PER_SHIFT ? 0 : (hours - HOURS_PER_SHIFT) * payRate / 2; } }, WEEKEND { double overtimePay(double hours, double payRate) { return hours * payRate / 2; } }; private static final int HOURS_PER_SHIFT = 8; abstract double overtimePay(double hrs, double payRate); double pay(double hoursWorked, double payRate) { double basePay = hoursWorked * payRate; return basePay + overtimePay(hoursWorked, payRate); } } }
oridinal()
// Enum with integer data stored in an instance field public enum Ensemble { SOLO(1), DUET(2), TRIO(3), QUARTET(4), QUINTET(5), SEXTET(6), SEPTET(7), OCTET(8), DOUBLE_QUARTET(8), NONET(9), DECTET(10), TRIPLE_QUARTET(12); private final int numberOfMusicians; Ensemble(int size) { this.numberOfMusicians = size; } public int numberOfMusicians() { return numberOfMusicians; } }
採用單獨的屬性存儲,這樣維護起來方便,不然枚舉順序一改,整個都得改。ide
public class Text{ public static final int STYLE_1 = 1 << 0; //1 public static final int STYLE_2 = 1 << 1; //2 public static final int STYLE_3 = 1 << 2; //4 public static final int STYLE_4 = 1 << 3; //8 public void applyStyles(int styles){ ... } } text.applyStyles(STYLE_1 | STYLE_2); //好處就是高效,可是比較晦澀。
public class Text { public enum Style { BOLD, ITALIC, UNDERLINE, STRIKETHROUGH } // Any Set could be passed in, but EnumSet is clearly best public void applyStyles(Set<Style> styles) { // Body goes here } // Sample use public static void main(String[] args) { Text text = new Text(); text.applyStyles(EnumSet.of(Style.BOLD, Style.ITALIC)); } }
public enum Phase { SOLID, LIQUID, GAS; public enum Transition { MELT, FREEZE, BOIL, CONDENSE, SUBLIME, DEPOSIT; private final Phase src; private final Phase dst; Transition(Phase src, Phase dst) { this.src = src; this.dst = dst; } //don't do this private static final Transition[][] TRANSITIONS = { {null,MELT,SUBLIME}, {FREEZE,null,BOIL}, {DEPOSIT,CONDENSE,null} } //return public static Transition from(Phase src,Phase dst){ return TRANSITIONS[src.oridinal()][dst.oridinal()]; } } }
// Simplistic class representing a culinary herb - Page 161 public class Herb { public enum Type { ANNUAL, PERENNIAL, BIENNIAL } private final String name; private final Type type; Herb(String name, Type type) { this.name = name; this.type = type; } @Override public String toString() { return name; } public static void main(String[] args) { Herb[] garden = { new Herb("Basil", Type.ANNUAL), new Herb("Carroway", Type.BIENNIAL), new Herb("Dill", Type.ANNUAL), new Herb("Lavendar", Type.PERENNIAL), new Herb("Parsley", Type.BIENNIAL), new Herb("Rosemary", Type.PERENNIAL) }; // Using an EnumMap to associate data with an enum - Page 162 Map<Herb.Type, Set<Herb>> herbsByType = new EnumMap<Herb.Type, Set<Herb>>(Herb.Type.class); for (Herb.Type t : Herb.Type.values()) herbsByType.put(t, new HashSet<Herb>()); for (Herb h : garden) herbsByType.get(h.type).add(h); System.out.println(herbsByType); } }
public interface Operation { double apply(double x, double y); } //擴展1 public enum BasicOperation implements Operation { PLUS("+") { 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; BasicOperation(String symbol) { this.symbol = symbol; } @Override public String toString() { return symbol; } } //擴展2 public 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; ExtendedOperation(String symbol) { this.symbol = symbol; } @Override public String toString() { return symbol; } // Test class to exercise all operations in "extension enum" - Page 167 public static void main(String[] args) { double x = Double.parseDouble(args[0]); double y = Double.parseDouble(args[1]); test(ExtendedOperation.class, x, y); System.out.println(); // Print a blank line between tests test2(Arrays.asList(ExtendedOperation.values()), x, y); } // 使用綁定類型 test parameter is a bounded type token (Item 29) private static <T extends Enum<T> & Operation> void test( Class<T> opSet, double x, double y) { for (Operation op : opSet.getEnumConstants()) System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y)); } // 使用有限通配符類型 test parameter is a bounded wildcard type (Item 28) private static void test2(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)); } }
A、文字拼寫容易出錯this
B、沒法確保它們只用於相應的程序元素上spa
C、沒有提供將參數值與程序元素關聯起來的好方法code
// Program containing marker annotations - Page 170 public class Sample { @Test public static void m1() { } // Test should pass public static void m2() { } @Test public static void m3() { // Test Should fail throw new RuntimeException("Boom"); } public static void m4() { } @Test public void m5() { } // INVALID USE: nonstatic method public static void m6() { } @Test public static void m7() { // Test should fail throw new RuntimeException("Crash"); } public static void m8() { } } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Test { }
異常註解實例orm
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface ExceptionTest { Class<? extends Exception>[] value(); } public class Sample2 { @ExceptionTest(ArithmeticException.class) public static void m1() { // Test should pass int i = 0; i = i / i; } @ExceptionTest(ArithmeticException.class) public static void m2() { // Should fail (wrong exception) int[] a = new int[0]; int i = a[1]; } @ExceptionTest(ArithmeticException.class) public static void m3() { } // Should fail (no exception) // Code containing an annotation with an array parameter - Page 174 @ExceptionTest({ IndexOutOfBoundsException.class, NullPointerException.class }) public static void doublyBad() { List<String> list = new ArrayList<String>(); // The spec permits this method to throw either // IndexOutOfBoundsException or NullPointerException list.addAll(5, null); } }
public boolean equals(Bigram o){ return b.first == o.first && b.second == second; }
@Override public boolean equals(Object o){ if(!(o instance of Bigram)){ return false; } Bigram b = (Bigram)o; return b.first == first && b.second == second; }
即沒有包含方法聲明的接口,只是用來標明一個類實現了具備某種屬性的接口,好比Serializable接口,經過實現這個接口,類標明它的實例能夠被寫到ObjectOutputStream,即序列化索引
Set接口就是有限制的標記接口,只適用於Collection的子類型,不會添加除了Collection定義以外的方法。
token