本文共 8989 字,大约阅读时间需要 29 分钟。
一、什么是注释 说起注释,得先提一提什么是元数据(metadata)。所谓元数据就是数据的数据。也就是说,元数据是描述数据的。就象数据表中的字段一样,每个字段描述了这个字段下的数据的含义。而J2SE5.0中提供的注释就是java源代码的元数据,也就是说注释是描述java源代码的。在J2SE5.0中可以自定义注释。使用时在@后面跟注释的名字。 二、J2SE5.0中预定义的注释 在J2SE5.0的java.lang包中预定义了三个注释。它们是Override、Deprecated和SuppressWarnings。下面分别解释它们的含义。 Override 这个注释的作用是标识某一个方法是否覆盖了它的父类的方法。那么为什么要标识呢?让我们来看看如果不用Override标识会发生什么事情。class ParentClass1 { public void myMethod1() {...} } class Class1 extends ParentClass1 { public void myMethod2() {...} }
ParentClass1 c1 = new Class1(); c1.myMethod1();
class Class1 extends ParentClass1 { @Override // 编译器产生一个错误 public void myMethod2() {...} }
class Class1 extends ParentClass1 { @Override public void myMethod1() {...} }
Deprecated
这个注释是一个标记注释。所谓标记注释,就是在源程序中加入这个标记后,并不影响程序的编译,但有时编译器会显示一些警告信息。
那么Deprecated注释是什么意思呢?如果你经常使用eclipse等IDE编写java程序时,可能会经常在属性或方法提示中看到这个词。如果某个类成员的提示中出现了个词,就表示这个并不建议使用这个类成员。因为这个类成员在未来的JDK版本中可能被删除。之所以在现在还保留,是因为给那些已经使用了这些类成员的程序一个缓冲期。如果现在就去了,那么这些程序就无法在新的编译器中编译了。 说到这,可能你已经猜出来了。Deprecated注释一定和这些类成员有关。说得对!使用Deprecated标注一个类成员后,这个类成员在显示上就会有一些变化。在eclipse中非常明显。让我们看看图1有哪些变化。 图1 加上@Deprecated后的类成员在eclipse中的变化 从上图可以看出,有三个地方发生的变化。红色框里面的是变化的部分。 1. 方法定义处 2. 方法引用处 3. 显示的成员列表中 发生这些变化并不会影响编译,只是提醒一下程序员,这个方法以后是要被删除的,最好别用。 Deprecated注释还有一个作用。就是如果一个类从另外一个类继承,并且override被继承类的Deprecated方法,在编译时将会出现一个警告。如test.java的内容如下:class Class1 { @Deprecated public void myMethod(){} } class Class2 extends Class1 { public void myMethod(){} }
public void myMethod() { List wordList = new ArrayList(); wordList.add("foo"); }
三、如何自定义注释
注释的强大之处是它不仅可以使java程序变成自描述的,而且允许程序员自定义注释。注释的定义和接口差不多,只是在interface前面多了一个“@”。public @interface MyAnnotation { }
public @interface MyAnnotation { String value(); }
@MyAnnotation("abc") public void myMethod() { }
public @interface MyAnnotation { public String myMethod(){} default “xyz”; }
@MyAnnotation // 使用默认值xyz public void myMethod() { }
@MyAnnotation(myMethod = ”abc”) public void myMethod() { }
public @interface MyAnnotation { public enum MyEnum{A, B, C} public MyEnum.value1() {} public String value2() {} } @MyAnnotation(value1 = MyAnnotation.MyEnum.A, value2 = “xyz”) public void myMethod() { }
@Target( ElementType.METHOD ) @interface MyAnnotation {} @MyAnnotation // 错误的使用 public class Class1 { @MyAnnotation // 正确的使用 public void myMethod1() {} }
@Target( {ElementType.METHOD, ElementType.CONSTRUCTOR} ) @interface MyAnnotation {}
@Retention(RetentionPolicy.SOURCE) @interface MyAnnotation1 { } @Retention(RetentionPolicy.CLASS) @interface MyAnnotation2 {} @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation3 {}
@interface MyAnnotation { } @MyAnnotation class Class1 { public void myMethod() { } }
class Class1extends java.lang.Object 而如果这样定义MyAnnotation将会出现另一个结果。 @Documented @interface MyAnnotation {} 生成的文档: @MyAnnotation // 这行是在加上@Documented后被加上的 class Class1extends java.lang.Object
@Inherited @interface MyAnnotation { } @MyAnnotation public class ParentClass {} public class ChildClass extends ParentClass { } 在以上代码中ChildClass和ParentClass一样都已被MyAnnotation注释了。
五、如何使用反射读取注释
前面讨论了如何自定义注释。但是自定义了注释又有什么用呢?这个问题才是J2SE5.0提供注释的关键。自定义注释当然是要用的。那么如何用呢?解决这个问题就需要使用java最令人兴奋的功能之一:反射(reflect)。 在以前的JDK版本中,我们可以使用反射得到类的方法、方法的参数以及其它的类成员等信息。那么在J2SE5.0中同样也可以象方法一样得到注释的各种信息。 在使用反射之前必须使用import java.lang.reflect.* 来导入和反射相关的类。 如果要得到某一个类或接口的注释信息,可以使用如下代码: Annotation annotation = TestAnnotation.class.getAnnotation(MyAnnotation.class); 如果要得到全部的注释信息可使用如下语句: Annotation[] annotations = TestAnnotation.class.getAnnotations(); 或 Annotation[] annotations = TestAnnotation.class.getDeclaredAnnotations(); getDeclaredAnnotations与getAnnotations类似,但它们不同的是getDeclaredAnnotations得到的是当前成员所有的注释,不包括继承的。而getAnnotations得到的是包括继承的所有注释。 如果要得到其它成员的注释,可先得到这个成员,然后再得到相应的注释。如得到myMethod的注释。Method method = TestAnnotation. class .getMethod( " myMethod " , null ); Annotation annotation = method.getAnnotation(MyAnnotation. class ); 注:要想使用反射得到注释信息,这个注释必须使用 @Retention(RetentionPolicy.RUNTIME)进行注释。
总结
注释是J2SE5.0提供的一项非常有趣的功能。它不但有趣,而且还非常有用。EJB3规范就是借助于注释实现的。这样将使EJB3在实现起来更简单,更人性化。还有Hibernate3除了使用传统的方法生成hibernate映射外,也可以使用注释来生成hibernate映射。总之,如果能将注释灵活应用到程序中,将会使你的程序更加简洁和强大。转自【来自网络,原始出处已不可考】
转载地址:http://cwnpi.baihongyu.com/