枚举和注解
笔记:
enum and annotation:
1、用枚举代替int常量
枚举类型是指由一组固定常量组成合法值的类型。没有枚举之前,表示枚举类型的常用模式是声明一组具名的int常量,每一个类型成员一个常量。String枚举模式。java的枚举本质是int值
枚举中可以有抽象方法,实例当中实现
枚举中可以有枚举子类
2、用实例域代替序数
所有的枚举都有一个ordinal方法,它返回每个枚举常量在类型中的数字位置。永远不要根据枚举的序数导出与它相关联的值,而是要把它保存在一个实例域中。
3、用EnumSet代替位域
4、用EnumMap代替序数索引
5、用接口模拟可伸缩性枚举
6、注解优先于命名模式
jdk1.5之前,一般使用命名模式表示有些程序元素需要通过某种工具或者框架进行特殊处理,例如JUnit测试框架原本要求它的用户一定要用test作为测试方法名称的开头。
命名模式的缺点:
1、文字拼写错误会导致失败而且没有任何提示
2、无法确保它们只用于相应的程序元素上
3、没有提供将参数值和程序元素关联起来的好方法
注解:@interface
注解对类的语义没有直接的影响,只负责提供信息供相关的程序使用
7、坚持使用Override注解
可以做错误检查
8、用标记接口定义类型
标记接口是没有包含方法声明的接口,而只是指明一个类实现了具有某种属性的接口,如Serializable接口。
标记接口有两点胜过标记注解:
1、标记接口定义的类型是由被标记类的实例实现的;标记注解则没有定义这样的类型
2、标记接口可以被更精确地进行锁定
标记注解的优势在于它们使注解机制的一部分;它可以通过默认的方式添加一个或者多个注解类型元素,给已被使用的注解类型添加更多信息
什么时候使用标记注解,什么时候使用标记接口呢?如果标记是应用到任何程序元素而不是类或者接口,就必须使用注解。如果是标记只应有给类和接口,就要问自己是需要编写一个还是有多个接受有标记的方法呢?如果是一个就优先使用标记接口而非注解。
有关代码:
package chapter5; import java.util.EnumMap; import java.util.HashSet; import java.util.Map; import java.util.Set; /** * @author zhen * @Date 2018/10/7 16:37 */ 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 = null; // Set<Herb>[] herbsByType = (Set<Herb>[])new Set[Type.values().length]; // for(int i = 0; i < herbsByType.length; i++){ // herbsByType[i] = new HashSet<>(); // } // // for (Herb h : garden) { // herbsByType[h.type.ordinal()].add(h); // } // // for(int i = 0; i < herbsByType.length; i++){ // System.out.printf("%s: %s%n", Herb.Type.values()[i], herbsByType[i]); // } Map<Herb.Type, Set<Herb>> herbsByType = new EnumMap<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); } }
package chapter5; /** * @author zhen * @Date 2018/10/7 15:42 */ 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); public static void main(String[] args) { double x = Double.parseDouble("2"); double y = Double.parseDouble("4"); for(Operation op : Operation.values()){ System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y)); } } }
package chapter5; /** * @author zhen * @Date 2018/10/7 15:52 */ public enum PayrollDay { // MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY; // private static final int HOURS_PER_SHIFT = 8; // // double pay(double hoursWorked, double payRate) { // double basePay = hoursWorked * payRate; // double overtimePay; //Calculate overtime pay // switch(this) { // case SATURDAY: // case SUNDAY: // overtimePay = hoursWorked * payRate / 2; // break; // default: //Weekdays // overtimePay = hoursWorked <= HOURS_PER_SHIFT ? 0 : (hoursWorked - HOURS_PER_SHIFT) * payRate / 2 ; // break; // } // return basePay + overtimePay; // } 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); } 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 hours, double payRate); double pay(double hoursWorked, double payRate) { double basePay = hoursWorked * payRate; return basePay + overtimePay(hoursWorked, payRate); } } }
package chapter5; /** * @author zhen * @Date 2018/10/7 15:27 */ public enum Planet { ; 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; 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 } }
package chapter5; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author zhen * @Date 2018/10/7 16:58 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Test { }

浙公网安备 33010602011771号