注解一般情况下是跟着反射走的,要读取注解的信息,使用注解一定要用到反射(个人理解),而反射一般是在构造框架,或者修改框架的时候才会用到。
先实现一下读取类注解的信息,和实现一个特殊功能的注解:被此注解修饰的方法不能有int型的参数。
代码:
package Java201512; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * MyAnnotation : 我的注解 * @author xuejupo [email protected] * create in 2015-12-9 下午7:52:16 */ @Target(value = {ElementType.TYPE,ElementType.METHOD,ElementType.CONSTRUCTOR}) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface MyAnnotation{ String[] value() default {"test"}; String name() default "defa"; int age() default 18; int val = 6; }
package Java201512; /** * annotaTest : * @author xuejupo [email protected] * create in 2015-12-9 下午8:20:59 */ @MyAnnotation public class annotaTest { @ParamsNotInteger public void test(Integer i){ } }
package Java201512; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * ParamsNotInteger : 我的注解: 有这个注解的方法,参数不能有int类型的 * @author xuejupo [email protected] * create in 2015-12-9 下午7:52:16 */ @Target(value = {ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface ParamsNotInteger{ String[] value() default {"test"}; }
测试:
public static void main(String[] args) { // TODO Auto-generated method stub try { parseTypeAnnotation(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block System.out.println("ERROR"); } } public static void parseTypeAnnotation() throws ClassNotFoundException { Class clazz = Class.forName("Java201512.annotaTest"); //获取类的所有方法 Method[] methods = clazz.getMethods(); //获取类的所有注解 Annotation annotation1 = clazz.getAnnotation(MyAnnotation.class); if(annotation1 != null){ System.out.println(annotation1 instanceof MyAnnotation); MyAnnotation test = (MyAnnotation)annotation1; System.out.println("value= "+test.value()[0]+"; name= "+test.name()+"; age = "+test.age()+"; val:"+test.val); } //分析类的方法 for(Method method : methods){ if(method.isAnnotationPresent(ParamsNotInteger.class)){ Class<?>[] types = method.getParameterTypes(); for(Class c:types){ System.out.println(c.getName()); System.out.println(c.equals(Integer.class)); if("int".equals(c.getName()) || c.equals(Integer.class)){ throw new RuntimeException("该方法不支持int型参数"); } } } } }
结果:
true value= test; name= defa; age = 18; val:6 java.lang.Integer true Exception in thread "main" java.lang.RuntimeException: 该方法不支持int型参数 at Java201512.ReadAnnotation.parseTypeAnnotation(ReadAnnotation.java:48) at Java201512.ReadAnnotation.main(ReadAnnotation.java:22)
可以看到,ParamsNotInteger注解不需要任何参数,只是一个简单的注解即可(@Retention一定要runtime,不然反射读不到信息的),通过反射读取到该方法有此注解,那么就遍历方法的参数,如果有int型就抛错。
如果这是一个简单的框架,annotaTest类是被监控的类,那么ParamsNotInteger就实现了注解的一个简单的功能:类型检查。 检查被ParamsNotInteger注解的方法是否含int型的参数。