/** * 重写toString * @param id * @param name * @return */ public String toString(int id, String name) { return id+","+name; }
package com.zhengbin.annotationtest.anno; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Created by zhengbin06 on 2016/10/15. */ @Retention(RetentionPolicy.RUNTIME) //①声明注解的保留期限 @Target(ElementType.METHOD) //②声明可以使用该注解的目标类型(这里表明该注解的目标类型是方法,查看@Target的实现,可以看到它的成员为ElementType类型的数组) public @interface NeedTest { //③定义注解 boolean internal() default true; //④声明注解成员 // 注解成员的类型、成员名、与默认值 }
package com.zhengbin.annotationtest.anno; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Created by zhengbin06 on 2016/10/15. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Student { String id() default "201370034217"; String name() default "郑斌"; int age() default 21; }
@Retention(RetentionPolicy.RUNTIME) //①声明注解的保留期限 @Target(ElementType.METHOD) //②声明可以使用该注解的目标类型(这里表明该注解的目标类型是方法,查看@Target的实现,可以看到它的成员为ElementType类型的数组) public @interface NeedTest { //③定义注解 boolean internal() default true; //④声明注解成员 // 注解成员的类型、成员名、与默认值 Student student(); }
在①和②处,我们所看到的注解是Java预定义的注解,成为元注解(Meta-Annotation),它们被Java编译器使用,会对注解类的行为产生印象。@Retention(RetentionPolicy.RUNTIME)表示NeedTest这个注解可以在运行期被JVM读取,注解的保留期限类型在java.lang.annotation.Retention类中定义,介绍如下:
Target(ElementType.METHOD)表示NeedTest这个注解只能应用到目标类的方法上,注解的应用目标在java.lang.annotation.ElementType类中定义:
所有的注解类都隐式继承于java.lang.annotation.Annotation,但注解不允许显式继承于其他的接口。
下面我们在ManageService.java中使用注解:
package com.zhengbin.annotationtest.service; import com.zhengbin.annotationtest.anno.NeedTest; import com.zhengbin.annotationtest.anno.Student; /** * Created by zhengbin06 on 2016/10/15. */ public class ManageService { @NeedTest(student = @Student)// ① public void accessStudent() { System.out.println("中工来了个小学弟!"); } @NeedTest(internal = false, student = @Student(name = "郑斌" , age = 21))// ② public void graduateStudent() { System.out.println("曾经的小学弟要毕业了。。。"); } }
前面提到过,注解不会直接影响程序的运行,但是第三方程序或工具可以利用代码中的注解完成特殊的任务,间接控制程序的运行。对于RetentionPolicy.RUNTIME保留期限的注解,我们可以通过反射机制访问类中的注解。
在JDK 5.0里,Package、Class、Constructor、Method以及Field等反射对象都新增了访问注解信息的方法:
<T extends Annotation>T getAnnotation(Class<T> annotationClass)
下面,我们就通过反射来访问注解,得出ManageService类中通过@NeedTest注解所承载的测试需求,如下:
package com.zhengbin.annotationtest.test; import com.zhengbin.annotationtest.anno.NeedTest; import com.zhengbin.annotationtest.service.ManageService; import java.lang.reflect.Method; /** * Created by zhengbin06 on 2016/10/15. */ public class TestTool { public static void main(String[] args) { Class clazz = ManageService.class; Method[] methods = clazz.getMethods(); System.out.println(methods.length); for (Method method : methods) { NeedTest needTest = method.getAnnotation(NeedTest.class); if (needTest != null) { if (needTest.internal()) { // ① System.out.println("小学弟:"+needTest.student().name()); // ② }else { System.out.println("毕业僧:"+needTest.student().name()); } } } } }
运行以上的代码,输出以下的信息:
11
小学弟:郑斌
毕业僧:郑斌
方法个数为11,除了我们申明的两个,其它都是父类Object的方法。
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。