java 注解

本文详细介绍了Java注解(Annotation)的概念、作用、分类,包括JDK预定义的如@Override、@Deprecated等注解,以及如何自定义注解。讲解了注解在文档生成、代码分析和编译检查中的功能,并通过实例展示了如何在程序中使用和解析注解。此外,还讨论了注解在实际编程中的重要性。
摘要由CSDN通过智能技术生成

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


概念

说明程序的。 给计算机看

定义

注解(Annotation)也叫元数据,一种代码级别的说明。JDK1.5之后引入的特性,与类、接口、枚举在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。


概念描述

JDK1.5之后的新特性
说明程序的
使用注释: @注解名称


作用分类

1.编写文档: 通过代码里标识的元数据生成文档 【生成文档doc文档】
—javadoc命令 使.java生成文档
2.代码分析: 通过代码里标识的元数据对代码进行分析 【使用反射】
3.编译检查: 通过代码里标识的元数据让编译器能够实现基本的编译检查【Override】


JDK中预定义的一些注解

例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

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

自定义注解

格式:
-----元注解
public @interface 注解名称{
属性列表
}

// 本质上是一个接口 默认继承了Annotation接口
// 属性: 接口中可以定义的成员方法 就是接口中的抽象方法
/*
  要求: 1.  属性的返回值类型 有下列取值 其他都不行
              基本数据类型
              String
              枚举
              注解
              以上类型的数组
        2. 定义了属性 需要给属性赋值
              1. 如果定义属性时 使用default关键字给属性默认初始化值,则使用注解时,可                  以不进行属性的赋值。
              2. 如果只有一个属性需要赋值,并且属性的名称是value 则value可以省略, 直接定义值即可
              3. 数组赋值时,值使用{}包裹。 如果数组中只有一个值,则{}省略

  元注解 : 用于描述注解的注解
       @Target: 描述注解能够作用的位置
               Type:可以作用于类上
               METHOD: 可以作用于方法上
               FIELD: 可以作用于成员变量上
       @Retention: 描述注解被保留的阶段
               @Retention(RetentionPolicy.RUNTIME) 当前被描述的注解 会保留到class字节中,并被JVM读取到
       @Oocumented: 描述注解是否被抽取到api文档中
       @Inherited: 描述注解是否被子类继承


   在程序使用注解 : 获取注解中定义的属性值
      1. 获取注解定义的位置的对象 (class, Method, Field)
      2. 获取指定的注解
                getAnnotation(Class)
      3. 调用注解中的抽象方法获取配置的属性值
              
*/

public interface MyAnno extends java.lang.annotation.Annotation{}
// 等于
public @interface MyAnno{
   
  // public abstract String show();  // 接口中方法默认就是 public abstract
  int age();

  String name() default "张三"; // 默认值

  @interface anno2;

}

public @interface MyAnno2{

}


@Target(value={ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) // 表示MyAnno3注解智能作用于类上  方法上  属性上
@Retention(RetentionPolicy.RUNTIME)
@Oocumented
@Inherited  是否能被描述的类的子类继承
public @interface MyAnno3{

}

@MyAnno(age = 12, name = "张三", anno2 = @MyAnno2)
@MyAnno3
public class Worker{
   @MyAnno3
   public String name = "aaa";

   @MyAnno3
   public void show(){
   }
}

// 通过@Inherited 可以让teacher类使用 @MyAnno3
public class Teacher extends Worker{

}

在程序使用(解析)注解

获取注解的值

/*\
  描述需要执行的类名 和方法名
*/
@Target({ElementType.TYPE})   // 使用在类上
@Retention(RetentionPolicy.RUNTIME)  // 实在在运行阶段
public @interface Pro {

  String className();
  String methodName();
}
/*
 系统中默认创建了 Pro的实现类 ProImpl 

*/


public class Demo1{
  public void show(){
     System.out.println("demo1...show")
  }
}

public class Demo2{
  public void show(){
     System.out.println("demo2...show")
  }
}


@Pro(className = "cn.itcast.annotation.Demo1", methodName= "show")
public class ReflectTest{
  public static void main(String[] arg) throws Exception {
  /*
     前提 不能改变该类的任何代码 可以创建任意类的对象 可以执行任意方法
     
   */
    // 解析注解
    // 1. 获取该类的字节码文件对象
    Class<ReflectTest> reflectTestClass = ReflectTest.class;
    // 2. 获取上边的注解对象
    Pro an = reflectTestClass.getAnnotation(Pro.class);
    // 3. 调用注解对象中定义的抽象方法 获取返回值
    String className = an.className();


   // 反射写法
   // 1. 加载类到内存
   Class cls = Class.forName(className);
   // 2. 创建对象
   Object obj = cls.newInstance();
   // 3. 获取方法对象
   Method method = cls.getMethod(methodName);
   // 执行方法
   method.invoke(obj);
  }

}

实例

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));
   }
    
   public void show(){

   }
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Check{
    
}

public static void main(String[] args){
   // 1. 创建计算器对象
   Calulator c = new Calculator();
   // 2. 获取字节码文件对象
   Class cls = c.getClass();
   // 3. 获取所有方法
   Method[] methods = cls.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.writer( method.getName() + "xxx方法异常了");
           bw.newLine();
           bw.writer( "异常的名称:" + e.getCause().getClass().getSimpleName());
           bw.newLine();
           bw.writer( "异常的原因:" + e.getCause().getMessage());
           bw.newLine();
           bw.writer( "-----------------------");
       }
     }
     bw.write("本次出现"+ num + " 次异常");
     bw.flush();
     bw.close();
  }
}

小结

1.以后大多数时间 使用注解 而不是自定义注解
2.注解给谁用?
1. 编译器
2. 给解析程序用
3. 注解就是一个标签

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值