注解

一.注解的使用格式与作用。

格式:@注解名称(参数)。

作用:

  • 编写文档:通过代码里的注解生成文档【生成doc文档】。(通过cmd打开命令行操作符,用javadoc +类名称.java生成doc文档)
  • 代码分析:通过代码里的注解对代码进行分析【使用反射】。 
  • 编译检查:通过代码里的注解让编译器能够实现基本的编译检查【Override】,参考toString方法前的@Override

二.JDK中预定义的一些注解。

  • @Override :检测被该注解标注的方法是否是继承父类(接口)的。
  • @Deprecated:该注解标注的内容已经过时。
  • @SuppressWarnings:压制警告,一般传参为all,且放在类前面。

三.自定义注解。

  • 格式:

         元注解

        public  @interface  注解名称{            }

  • 本质:注解本质上就是一个接口,默认继承Annotation接口

      public   interface MyAnno extends  java.lang.annotation.Annotation{   }

  • 属性:接口中的抽象方法(省略public abstract),返回值类型有以下要求

      ①基本数据类型。

      ②String类型。

      ③枚举(如public  enum Person{p1,p2  })

      ④注解

      ⑤以上类型的数组。

  • 定义了属性需要给属性赋值:

      ①定义属性时用了Default赋予了默认初始值时,使用注解无需对属性赋值: String  eat( ) default "吃饭".

      ②如果只有一个属性需要赋值,恰好属性名称为value,使用注解对属性赋值值可以省略value,直接定义值即可。

      ③数组赋值时用{  }包裹,如果数组中只有一个值时可省略{ }。

      ④给枚举赋值:枚举名称.枚举内容;给注解属性赋值时:@注解名称。

  • 元注解

      ①@Target:描述注解能够起作用的位置。

         只作用于类(TYPE):@Target(ElementType.TYPE)

         只作用于方法(METHOD):@Target(ElementType.METHOD)

         只作用于成员变量(FIELD)@Target(ElementType.FIELD)

         作用于三者:@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})

      ②@Retenion:描述注解被保留的阶段。

          保留在Source阶段:@Retention(RetentionPolicy.SOURSE)

          保留在Class阶段:@Retention(RetentionPolicy.CLASS)

          一般保留在Runtime阶段:@Retention(RetentionPolicy.RUNTIME)

      ③@Documented:描述注解是否被抽取到api文档上。

      ④@Inherited:描述是否会被子类继承。

四.代码分析(解析注解)。

  自定义注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Myanno {
    String className();
    String methodName();
}

框架类:在类前面加自定义的注解

@Myanno(className="week07.Junit.Person",methodName="eat")
public class ReleftTest {
    public static void main(String[] args) throws Exception {
        Class ReleftTestClass=ReleftTest.class;
        Myanno my= ReleftTestClass.getAnnotation(Myanno.class);
        String className=my.className();
        String methodName=my.methodName();
        Class cls=Class.forName(className);
        Constructor con=cls.getConstructor();
        Object ob=con.newInstance();
        Method method=cls.getMethod(methodName);
        method.invoke(ob);
    }
}

五.测试类。

自定义注解:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)

public @interface Check {

}

需要被测试的类:在需要被测试的方法前加自定义注解

public class Caculater {
    @Check()
    public void add( ){
        System.out.println("2+3=5");
    }
    @Check()
    public void submit( ){
        int b=10/0;
        System.out.println("3-2=1");
    }
}

测试类:

public class DemoTest {
    public static void main(String[] args) throws IOException {
        Caculater c=new Caculater();
        Class cls=Caculater.class;
        BufferedWriter bw=new BufferedWriter(new FileWriter("C:\\Users\\RookieMzz\\Desktop\\99\\bug.txt"));
        int number=0;
        Method[] methods=cls.getMethods();
        for(Method method:methods){
            if(method.isAnnotationPresent(Check.class)){
                try {
                    method.invoke(c);
                } catch (Exception e) {
                    number++;
                    bw.write(method.getName()+"方法出现了异常");
                    bw.newLine();
                    bw.write("异常的名称是:"+e.getCause().getClass().getSimpleName());
                    bw.newLine();
                    bw.write("异常的原因是:"+e.getCause().getMessage());
                    bw.newLine();
                    bw.write("------------");
                    bw.newLine();
                }
            }
        }
        bw.write("一共出现了"+number+"次异常");
        bw.flush();
        bw.close();
    }
}

 

posted @ 2020-02-02 23:24  星垂平野阔  阅读(159)  评论(0)    收藏  举报