java注解学习使用

目录

注解

概念:

作用分类

编写文档:

代码分析:

编译检查

JDK中预定义的一些注解

自定义注解

格式:

本质:

属性:就是接口中的抽象方法

元注解:用于描述注解的注解

在程序中使用(解析)注解

如何获取注解中定义的属性值

案例1

案例2

总结


注解

概念:

  • JDK1.5的新特性

  • 说明程序

作用分类

编写文档:

通过代码里标识的注解生成文档【生成文档doc文档】        就是我们才学java看的api文档

1.编写注解:

 /**
  * 注解java doc演示
  *
  * @author  mxp
  * @version 1.0
  * @since 1,5
  */
 public class AoonDemo1 {
 ​
     /**
      * 计算两数之和
      * @param a
      * @param b
      * @return 两数之和
      */
     public int add(int a,int b){
         return a+b;
     }
 }

2.打开终端

3.输入javadoc .\xxx.java

4.效果

代码分析:

通过代码里标识的注解对代码进行分析【使用反射】

编译检查

通过代码里标识的注解让编译器能够实现基本的编译检查【override】

JDK中预定义的一些注解

@Override : 检测被该注解标注的方法是否是继承自父类(接口)的 @Deprecated: 该注解标注的内容,表示已过时 @Suppresswarnings: 压制警告

自定义注解

格式:

元注解 ​ public @interface 注解名称{

属性列表

}

本质:

 package com.company.annotation;
 ​
 public @interface MyAnno {
 }

进行反编译

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

可以看出就是一个接口

属性:就是接口中的抽象方法

要求:

1.属性返回值的类型

基本数据类型 ​ String ​ 枚举 ​ 注解 ​ 以上的数组类型

2.定义了属性,在使用时需要给属性赋值

使用注解使,里面的方法需要赋值,除非定义的时候,使用default有默认值 ​ 方法名叫value,在使用时,如果你就用这一个,可以省略 ​ 数组赋值时,值使用门包裹。如果数组中只有一个值,则{}省略

元注解:用于描述注解的注解

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

TYPE, 能够在类上使用 FIELD, 在属性上使用 METHOD, 在方法上使用

@Retention:描述注解被保留的阶段

SOURCE, 源码阶段

CLASS, 字节码阶段

RUNTIME 运行时阶段

一般我们自定义的注解 使用运行时阶段 @Retention(RetentionPolicy.RUNTIME)

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

@Inherited :描述注解是否被子类继承

在程序中使用(解析)注解

如何获取注解中定义的属性值

1.获取注解所在的位置的对象(Class,Method,Field)

2.获取指定的注解 getAnnotation(注解类.class)

3.调用注解中抽象类的方法,获取属性值

案例1

需求:不修改任何代码,可以创建任意对象,执行任意方法

Pro.java

package com.company.anli;
 import java.lang.annotation.*;
 /**
  * @描述:获取需要执行的类名,方法名
  */
 @Target(ElementType.TYPE)
 @Retention(RetentionPolicy.RUNTIME)
 public @interface Pro {
     String className();
     String methodName();
 }
 /**
  *
  * 执行 Pro an=reflectTestClass.getAnnotation(Pro.class);
  * 相当于生产了
  * public class ProImpl implements Pro{
  *     public String className(){
  *         return "com.company.anli.Dog";
  *     }
  *     public void methodName(){
  *         return "eat"
  *     }
  * }
  */

Dog.java

 package com.company.anli;
 ​
 public class Dog {
     public void eat() {
         System.out.println("狗吃肉");
     }
 ​
    public void sleep() {
         System.out.println("狗睡觉");
     }
 }

ReflectTest.java

package com.company.anli;
 ​
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 ​
 /**
  * 1.可以看出来最主要的作用就是,替代properties文件
  */
 @Pro(className = "com.company.anli.Dog", methodName = "sleep")
 public class ReflectTest {
     /**
      * @param args
      * @描述 不修改任何代码,可以创建任意对象,执行任意方法
      */
     public static void main(String[] args) throws Exception {
         //1.解析注解
         //1.1获取该类的字节码文件对象
         Class<ReflectTest> reflectTestClass = ReflectTest.class;
         //2.获取上边的注解对象
         //其实就是在内存中生成了一个该注解接口的子类实现对象
         Pro an = reflectTestClass.getAnnotation(Pro.class);
         //3.调用注解对象中定义的抽象方法,获取返回值
         String className = an.className();
         String methodName = an.methodName();
 ​
         //    加载该类进内存
         Class cls = Class.forName(className);
         Object obj = cls.newInstance();
         Method method = cls.getMethod(methodName);
         method.invoke(obj);
     }
 }

案例2

需求:添加 @Check 就判断,这个方法是否有异常,且记录

Calculator.java

 package com.company.anli2;
 ​
 /**
  * 小明定义的计算器类
  */
 public class Calculator {
 ​
     //加法
     @Check
     public void add() {
         System.out.println("1+0=" + (1 + 0));
     }
 ​
     //减法
     @Check
     public void sub() {
         System.out.println("1-0=" + (1 - 0));
     }
 ​
     //乘法
     @Check
     public void mul() {
         System.out.println("1*0=" + (1 * 0));
     }
 ​
     //除法
     @Check
     public void div() {
         System.out.println("1/0=" + (1 / 0));
     }
 ​
     @Check
     private void shwo() {
         System.out.println("永无bug......");
     }
 }

Check.java

package com.company.anli2;
 ​
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 ​
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
 public @interface Check {
 }

TestCheck.java

 package com.company.anli2;
 ​
 import java.io.BufferedWriter;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 ​
 /**
  * 简单的测试框架
  */
 public class TestCheck {
     public static void main(String[] args) throws IOException {
         //1.创建计算器对象
         Calculator c = new Calculator();
         //2.获取字节码文件对象
         Class<? extends Calculator> ccls = c.getClass();
         //3.获取所有public修饰的方法
         Method[] methods = ccls.getMethods();
 ​
         int number = 0;//异常出现的次数
         BufferedWriter bw = new BufferedWriter(new FileWriter("bug.txt"));
 ​
         for (Method method : methods) {
             //4.判断方法上是否有Check注解
             if (method.isAnnotationPresent(Check.class)) {
                 //5.有,执行
                 try {
                     method.invoke(c);
                 } catch (Exception e) {
                     //6.捕获异常
 ​
                     //记录到文件中
                     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();
     }
 }

总结

  1. 以后大多数时候,我们会使用注解,而不是自定义注解

    注解给谁用? 编译器:识别注解,检查编译有没有问题。如 @Override 这个里面肯定也有解析程序的存在       
    给解析程序用:如果没有解析的存在那么这个注解加在上面毫无意义
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值