在Java1.5版本中,引入了两个类型:枚举类型enum type
和注解类型annotation type
。
Num1:用enum代替int常量 枚举类型enum type
是指由一组固定的常量组成合法值的类型。比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 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; private final double radius; private final double surfaceGravity; 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 surfaceWeight (double mass) { return mass * surfaceGravity; } } public class WeightTable { public static void main (String[] args) { double earthWeight = Double.parseDouble(args[0 ]); double mass = earthWeight / Planet.EARTH.surfaceGravity(); for (Planet p : Planet.values()) System.out.printf("Weight on %s is %f%n" , p, p.surfaceWeight(mass)); } }
Num2:用EnumSet代替位域 示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class Text { public enum Style { BOLD, ITALIC, UNDERLINE, STRIKETHROUGH } public void applyStyles (Set<Style> styles) { } public static void main (String[] args) { Text text = new Text (); text.applyStyles(EnumSet.of(Style.BOLD, Style.ITALIC)); } }
总而言之,正是因为枚举类型要用在集合Set
中,所以没有理由用位域来表示它。
Num3:注解优先于命名模式 命名模式有两个缺点:
文字拼写错误会导致失败,且没有任何提示。
无法确保它们只用于相应的程序元素上。
它们没有提供将参数值与程序元素关联起来的好方法。
针对以上几个问题,注解很好地解决了所有这些问题。
1 2 3 4 5 6 7 8 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Test {}
Test注解类型的声明就是它自身通过Retention
和Target
注解进行了注解。注解类型声明中的这张注解被称作”元注解“meta-annotaition
。
那么声明的Test注解,则称作为”标记注解”marker annotation
。因为它没有参数,只是“标注”被注解的元素。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public 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 void m5 () { } public static void m6 () { } @Test public static void m7 () { throw new RuntimeException ("Crash" ); } public static void m8 () { } }
另外一种注解方式:
1 2 3 4 5 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface ExceptionTest { Class<? extends Exception >[] value(); }
使用方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class Sample2 { @ExceptionTest(ArithmeticException.class) public static void m1 () { int i = 0 ; i = i / i; } @ExceptionTest(ArithmeticException.class) public static void m2 () { int [] a = new int [0 ]; int i = a[1 ]; } @ExceptionTest(ArithmeticException.class) public static void m3 () { } @ExceptionTest({ IndexOutOfBoundsException.class, NullPointerException.class }) public static void doublyBad () { List<String> list = new ArrayList <String>(); list.addAll(5 , null ); } }