JavaWeb的配置信息,以前是使用配置xml文件来做,所以会有很多的配置,这样会很不方便。所以在Servlet3.0后提供了注解的方式来达到配置的目的。
注解的使用我们看到很多,形如 @WebServlet(...) 这种。一个注解的定义如下
package test.annotation; // 这里定义一个 Action 注解 public @interface Action { }
元注解就是注解的注解,在注解的定义中,我们还可以对定义的注解进行注解。
package test.anntation; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Action { }
这里的 @Target , @Retention 就是元注解。
@Retention 注解
它是被定义在一个注解类的前面,用来说明该注解的生命周期。 它有以下参数:
RetentionPolicy.SOURCE :指定注解只保留在一个源文件当中。
RetentionPolicy.CLASS :指定注解只保留在一个 class 文件中。
RetentionPolicy.RUNTIME :指定注解可以保留在程序运行期间。
@Target 注解
它是被定义在一个注解类的前面,用来说明该注解可以被声明在哪些元素前面。 它有以下参数:
ElementType.TYPE :说明该注解只能被声明在一个类前。
ElementType.FIELD :说明该注解只能被声明在一个类的字段前。
ElementType.METHOD :说明该注解只能被声明在一个类的方法前。
ElementType.PARAMETER :说明该注解只能被声明在一个方法参数前。
ElementType.CONSTRUCTOR :说明该注解只能声明在一个类的构造方法前 。
ElementType.LOCAL_VARIABLE :说明该注解只能声明在一个局部变量前。
ElementType.ANNOTATION_TYPE :说明该注解只能声明在一个注解类型前 。
ElementType.PACKAGE :说明该注解只能声明在一个包名前。
如果不加该注解表示可以声明在任何位置
http://my.oschina.net/aiguozhe/blog/59661
http://blog.csdn.net/jiangwei0910410003/article/details/18501195
package test.override; class A { public void print() { System.out.println("A"); } } class B extends A { public void print() { System.out.println("B"); } } public class OverrideTest { public static void main(String[] args) { A a = (A) new B(); a.print(); } } // output B
如果在类 B的 print 方法上加上 @Override,表示这个 print 方法是重写父类 A 的 print 方法,如果不加这个的话,如果 B 的意思是重写 A 的方法 print,但是在B的实现中写成了 Print,这时如果没有 @Override 注解,那么程序是不会报错的,如果你粗心的话,这样就发现不了,但是加上了 @Override, 如果检查到 B 中的方法不是重写父类的方法,那么编译通过不了。估计这就是 @Override 的作用了。
// Action.java package test.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) // 这个意思是这个注解只能在类的开始,在类的内部使用会出错 @Retention(RetentionPolicy.RUNTIME) public @interface Action { } // AnnotationTest.java package test.annotation; @Action class ActionAnnotation { } public class AnnotationTest { public static void main(String[] args) { System.out.println(ActionAnnotation.class.isAnnotationPresent(Action.class)); // 判断ActionAnnotation这个类是否使用到了 Action 注解 System.out.println(ActionAnnotation.class.isAnnotation()); System.out.println(Action.class.isAnnotation()); } } /* // output true false true */
代码片段2
// Action.java package test.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) // 定义Action注解只能在类的开始 @Retention(RetentionPolicy.RUNTIME) // 载入到JVM中的代码片段,包括注解信息 public @interface Action { } // RequestBean.java package test.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) // 定义RequestBean注解在方法上 @Retention(RetentionPolicy.RUNTIME) public @interface RequestBean { /* 注解中再定义注解 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Get { String value(); } @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Post{ String value(); } } // AnnotationTest.java package test.annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @Action class ActionAnnotation { @RequestBean.Get("/hello") public void doGetTest(String info) { System.out.println("Get: " + info); } @RequestBean.Post("/hello") public void doPostTest(String info) { System.out.println("Post: " + info); } } public class AnnotationTest { public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException, ClassNotFoundException { // 获得ActionAnnotation类的对象实例 Object obj = Class.forName("test.annotation.ActionAnnotation").newInstance(); // 获得ActionAnnotation类中的方法 Method[] methods = ActionAnnotation.class.getDeclaredMethods(); // 遍历获得的方法 for(Method method : methods) { // 如果这个方法上的注解为 RequestBean.Get if(method.isAnnotationPresent(RequestBean.Get.class)) { String info = method.getAnnotation(RequestBean.Get.class).value(); // 调用该注解标识的方法 method.invoke(obj, info); } else if(method.isAnnotationPresent(RequestBean.Post.class)) { String info = method.getAnnotation(RequestBean.Post.class).value(); method.invoke(obj, info); } } } } // output Post: /hello Get: /hello