JDK内置预定义的注解:
* JDK中预定义的注解 * @Override :检测该方法是否为父类中方法的重写 * @Deprecated: 该注解标注的内容已过时 * @SupperessWarnings: 压制警告
1 package cn.ftf.annotation; 2 /* 3 * JDK中预定义的注解 4 * @Override :检测该方法是否为父类中方法的重写 5 * @Deprecated: 该注解标注的内容已过时 6 * @SupperessWarnings: 压制警告 7 */ 8 @SuppressWarnings(value = { "all" }) //压制警告,需要传值,一般传all 9 public class Annotation01 { 10 public static void main(String[] args) { 11 12 } 13 @Override //重写toString方法,检查是否为父类中方法的重写 14 public String toString() { 15 // TODO Auto-generated method stub 16 return super.toString(); 17 } 18 @Deprecated //标识说明该方法已过时 19 public void shou1() { 20 //有缺陷 21 } 22 public void shou2() { 23 //替代shou1()方法 24 } 25 public void demo() { 26 shou1(); 27 } 28 29 } 30 31 class Student{ 32 33 }自定义注解:
* 自定义注解 * 格式 * 元注解 * public @interface 注解名 * * 本质: * 注解本质上是一个接口,该接口默认继承Annotation接口 * public interface MyAnno extends java.lang.annotation.Annotation{} * 属性: * 接口中定义的抽象方法 * 要求: * 属性的返回值有要求:基本数据类型,String,枚举,注解,以上类型的数组.定义了属性后,在使用时需要给他们赋值,也可以在注释中在属性后面用default给属性设值,如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接写值即可 * 注解是否被子类继元注解:用于描述注解的注解 * @Target:描述注解可以作用的位置 * @Retention:描述注解被保留的阶段,一般都是保留到runtime阶段 * @Documented: 描述注解是否被抽取到API文档中 * @Inherited:描述注解是否可以被其子类继承
元注解:
1 package cn.ftf.annotation; 2 3 import java.lang.annotation.Documented; 4 import java.lang.annotation.ElementType; 5 import java.lang.annotation.Inherited; 6 import java.lang.annotation.Retention; 7 import java.lang.annotation.RetentionPolicy; 8 import java.lang.annotation.Target; 9 10 /* 11 * 元注解:用于描述注解的注解 12 * @Target:描述注解可以作用的位置 13 * @Retention:描述注解被保留的阶段,一般都是保留到runtime阶段 14 * @Documented: 描述注解是否被抽取到API文档中 15 * @Inherited:描述是否可以继承到所继承的子类中 16 */ 17 18 @Target(value= {ElementType.TYPE}) //表示该注解只能作用在类上,可叠加.TYPE类上,.METHOD方法上,.FLELD成员变量上 19 @Retention(RetentionPolicy.RUNTIME) //当前被描述的注解会被保留到class文件中,并被虚拟机(jvm)读取到 20 @Documented //当前注解可以被抽取到API文档中 21 @Inherited //当前注解可以被继承到所继承的子类中 22 public @interface MyAnno03 { 23 24 }
首先定义一个注解:Myanno.java
1 package cn.ftf.annotation; 2 3 public @interface MyAnno { 4 String name() default "张三"; 5 int age(); 6 Person per(); //枚举 7 MyAnno2 anno2(); 8 String[] str(); 9 }一个枚举:Person.java:
1 package cn.ftf.annotation; 2 3 public enum Person { 4 p1,p2; 5 }
注解的声明和属性赋值:
1 package cn.ftf.annotation; 2 /* 3 * 自定义注解 4 * 格式 5 * 元注解 6 * public @interface 注解名 7 * 8 * 本质: 9 * 注解本质上是一个接口,该接口默认继承Annotation接口 10 * public interface MyAnno extends java.lang.annotation.Annotation{} 11 * 属性: 12 * 接口中定义的抽象方法 13 * 要求: 14 * 属性的返回值有要求:基本数据类型,String,枚举,注解,以上类型的数组.定义了属性后,在使用时需要给他们赋值,也可以在注释中在属性后面用default给属性设值,如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接写值即可 15 * 注解是否被子类继元注解:用于描述注解的注解 16 * @Target:描述注解可以作用的位置 17 * @Retention:描述注解被保留的阶段 18 * @Documented: 描述注解是否被抽取到API文档中 19 * @Inherited:描述注解是否可以被其子类继承 20 */ 21 22 @MyAnno(age = 20, per = Person.p1, anno2 = @MyAnno2, str = { "123","567" }) //注解声明和各种属性(方法)的赋值 23 public class AnnotationDemo02 { 24 25 }
解析注解:
定义一个注解:Prp.java
1 package cn.ftf.annotation; 2 3 import java.lang.annotation.Documented; 4 import java.lang.annotation.ElementType; 5 import java.lang.annotation.Retention; 6 import java.lang.annotation.RetentionPolicy; 7 import java.lang.annotation.Target; 8 9 /* 10 *描述需要执行的类名和方法名 11 */ 12 @Target(ElementType.TYPE) //可以作用于类上 13 @Retention(RetentionPolicy.RUNTIME) //会被保留到class文件中 14 public @interface Pro { 15 String className(); 16 String methodName(); 17 18 }对注解解析,拿到注解的属性:
1 package cn.ftf.annotation; 2 3 import java.lang.annotation.Annotation; 4 5 @Pro(className = "cn.ftf.annotation.Demo1", methodName = "show") 6 public class ReflectTest { 7 public static void main(String[] args) { 8 //解析注解 9 //获取该类的字节码文件对象 10 Class<ReflectTest> c=ReflectTest.class; 11 //获取字节码文件的注解对象 12 Pro p=c.getAnnotation(Pro.class); //其实就是在内存中生成生成了一个该注解接口的子类实现对象 13 String className=p.className(); 14 String methodName=p.methodName(); 15 System.out.println(className+" "+methodName); //拿到注解内容 16 } 17 }
下面应用注解和反射做一个简单的测试框架:
测试一个类(Calculaor类)中的方法是否有错误
1 package cn.ftf.annotationpro; 2 /* 3 * 定义了一个计算机的类 4 */ 5 public class Calculator { 6 @Check 7 public void add() { 8 System.out.println("1+0="+(1+0)); 9 } 10 @Check 11 public void del() { 12 System.out.println("1-0="+(1-0)); 13 } 14 @Check 15 public void mul() { 16 System.out.println("1*0="+(1*0)); 17 } 18 @Check 19 public void div() { //显然div方法中由错误(by zero) 20 System.out.println("1/0="+1/0); 21 } 22 public void show() { 23 System.out.println("永无bug..."); 24 } 25 }
定义一个接口:Check.java
1 package cn.ftf.annotationpro; 2 3 import java.lang.annotation.ElementType; 4 import java.lang.annotation.Retention; 5 import java.lang.annotation.RetentionPolicy; 6 import java.lang.annotation.Target; 7 8 @Target(ElementType.METHOD) 9 @Retention(RetentionPolicy.RUNTIME) 10 public @interface Check { 11 }定义测试类TestCheck.java:
1 package cn.ftf.annotationpro; 2 3 import java.io.BufferedWriter; 4 import java.io.FileWriter; 5 import java.io.IOException; 6 import java.lang.reflect.InvocationTargetException; 7 import java.lang.reflect.Method; 8 9 /* 10 * 简单的测试类,当主方法执行,会检测该类下所有的需要检测的方法,并记录到文件中 11 */ 12 public class TestCheck { 13 public static void main(String[] args) throws IOException { 14 //获取要检测的类的计算器对象 15 Calculator cal= new Calculator(); 16 //获取字节码文件对象 17 Class c=cal.getClass(); 18 19 //获取所有的方法 20 Method[] me=c.getMethods(); 21 int number =0; //记录出现异常的次数 22 BufferedWriter bw=new BufferedWriter(new FileWriter("D:\\myjavacode\\ftf001\\src\\cn\\ftf\\annotationpro\\bugNote.txt")); 23 //方法上是否由check注解 24 for(Method m:me) { 25 if(m.isAnnotationPresent(Check.class)) { 26 try { 27 m.invoke(cal); 28 } catch (Exception e) { 29 number++; 30 //记录到文件中 31 bw.write(m.getName()+"方法出异常了!"); 32 bw.newLine(); 33 bw.write("异常名称:"+e.getCause().getClass().getSimpleName()); 34 bw.newLine(); 35 bw.write("异常原因:"); 36 bw.write(e.getCause().getMessage()); 37 bw.newLine(); 38 39 } 40 } 41 } 42 bw.write("本次一共出现"+number+"次异常!"); 43 bw.close(); 44 } 45 }结果:
转载于:https://www.cnblogs.com/fangtingfei/p/11285464.html
相关资源:linux2.6.1内核源码注释