Java 注解(Annotation)--基础篇

目录

1.Annotation的定义

2.Annotation作用分类

3.Annotation的语法形式

4.Annotation的分类

4.1:6个基本注解

4.2:4个元注解

4.2.1:@Target

4.2.2:@Retention    

4.2.3:@Documented(了解)

4.2.4:@Inherited(了解)

 5.Annotation的属性

   5.1简单演示


1.Annotation的定义

注解(Annotation),也叫元数据,是一种代码级别的说明。

它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。

其实Annotation就是代码里的特殊标记,它们可以在编译,类加载,运行时被读取,并执行相应的处理,以便于其他工具补充信息或者进行部署。


2.Annotation作用分类

  1. 编写文档:通过注解生成API文档(@Documented)
  2. 编译检查:通过注解让编译器实现基本的编译检查(@Override)
  3. 代码分析:通过注解对代码进行分析【反射等】(重点)

3.Annotation的语法形式

public @interface 注解名称 {}

      我们可以定义一个简单的注解,如下:

package com.hanyxx.annotaion;

/**
 * @author 菠菜饭团
 * @description: 自定义注解
 */
public @interface bocai {
}

如果通过 javac命令将注解类编译,然后再通过 javap 命令进行反编译,就会发现:
public interface com.hanyxx.annotaion.bocai extends java.lang.annotation.Annotation {}

注解的本质就是接口


4.Annotation的分类

java内置了6个基本注解和4个元注解

4.1:6个基本注解

@Override :检测被该注解标注的方法是继承自父类(接口)的
@Deprecated:该注解标注的内容,表示已过时
@SuppressWarnings:压制警告
其中jdk1.7之后引入了另外两个基本注解:
@SafeVarargs : Java7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告
@FunctionalInterface : Java8 开始支持,标识一个匿名函数或函数式接口。
@Repeatable: Java8 开始支持,标识某注解可以在同一个声明上使用多次
其中@Override、@Deprecated、@SuppressWarnings、@SafeVarargs和@FunctionalInterface在java.lang包下,而@Repeatable在java.lang.annotation包下

4.2:4个元注解

  元注解(meta-annotation):定义注解的注解

       4.2.1:@Target

@Target:用于描述注解能够作用的范围,可取的值存于ElementType枚举类中。

       ElementType的取值范围:

取值注解使用范围
TYPE用于类或者接口上
FIELD可作用于成员变量上
METHOD用于方法上
ANNOTATION_TYPE(了解)用于注解类型上(被@interface修饰的类型)
CONSTRUCTOR(了解)用于构造方法上
LOCAL_VARIABLE(了解)用于局部变量上
PACKAGE(了解)可用用于记录java文件的package信息
PARAMETER(了解)用于参数上
TYPE_PARAMETER(了解)可用于标注类型参数(jdk 1.8后支持)

  TYPE_USE(了解)

可用于标注任何类型名称(jdk 1.8后支持)

      4.2.2:@Retention

@Retention:表示在什么级别保存该注解信息。可取的值存于RetentionPolicy枚举类中。

     RetentionPolicy的取值范围:

取值注解使用范围
SOURCE注解将被编译器丢弃(该类型的注解信息只会保留在源码里,源码经过编译后,注解信息会被丢弃,不会保留在编译好的class文件里)
CLASS注解在class文件中可用,但会被VM丢弃(该类型的注解信息会保留在源码和class文件里,在执行的时候,不会加载到虚拟机中),请注意,当注解未定义Retention值时,默认值是CLASS,如Java内置注解,@Override、@Deprecated、@SuppressWarnning等
RUNTIME注解信息将在运行期(JVM)也保留,因此可以通过反射机制读取注解的信息(源码、class文件和执行的时候都有注解的信息),如SpringMvc中的@Controller、@Autowired、@RequestMapping等。

     4.2.3:@Documented(了解)

@Documented:此注解会被javadoc工具提取成文档

      4.2.4:@Inherited(了解)

@Inherited:允许子类继承父类中的注解

 5.Annotation的属性

从前面我们可以得知Annotation的本质是一个接口,既然是接口,那么自然能定义抽象方法。

我们把注解中的抽象方法称为注解的属性。

注解中属性的返回值类型有5种

  1. 基本数据类型
  2. String
  3. 枚举
  4. 注解
  5. 以上类型的数组
  1.    如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不进行属性的赋值。
  2.    如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义值即可。
  3.    数组赋值时,值使用{}包裹。如果数组中只有一个值,则{}可以省略

   5.1简单演示

package com.hanyxx.annotaion;
import java.lang.annotation.*;
/**
 * @author 菠菜饭团
 * @description: 自定义注解
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface BoCai {
    String name() default "菠菜饭团";
    ElementType[] value() default ElementType.TYPE ;
    String className();
    String methodName();
}

需求:通过注解的形式创建任意对象,并且执行任意方法:

package com.hanyxx.annotaion;
import java.lang.reflect.Method;
/**
 * @author 菠菜饭团
 * @description: 通过注解的形式创建任意对象,并且执行任意方法
 */
@BoCai(className="com.hanyxx.annotaion.PlayGame",methodName = "play")
public class AnnotationTest {
    public static void main(String[] args) throws Exception {
        /**
         *  <A extends Annotation> A getAnnotation(Class<A> annotationClass) :如果存在该元素的指定类型的注解,则返回这些注解,否则返回 null。
         *  Annotation[] getAnnotations() : 返回此元素上存在的所有注解。
         */
        //1.获取类字节码对象
        Class<AnnotationTest> annotationClass = AnnotationTest.class;
        //2.获取该类的注解对象(本质是在内存中生成该注解接口的子类实现对象)
        BoCai boCai = annotationClass.getAnnotation(BoCai.class);
        //3.获取传入的类名和方法名
        String className = boCai.className();
        System.out.println("获取类名:"+className);
        System.out.println("===========================");
        String methodName = boCai.methodName();
        System.out.println("获取方法名:"+methodName);
        System.out.println("===========================");
        //4.加载类进内存,并获取方法对象
        Class<?> Cls = Class.forName(className);
        Method method = Cls.getMethod(methodName);
        //5.创建对象实例并调用方法
        Object o = Cls.newInstance();
        method.invoke(o);
    }
}

执行结果如下:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值