注解的学习笔记

本文详细介绍了Java中的注解,包括其作用、元注解如Retention和Target的用法,以及如何创建和使用自定义注解。重点讲解了元数据的提供、配置控制功能和注解在编译时和运行时的应用。还展示了如何通过注解处理器处理带有注解的方法。
摘要由CSDN通过智能技术生成

注解:

注解是元数据的一种形式,它提供了关于程序代码的额外信息。注解通常以特殊的注释语法编写,它们可以被附加到类、方法、字段等程序元素上,用于提供关于这些元素的额外信息或指令。

注解的作用:提供元数据信息:注解可以用于提供关于程序元素(如类、方法、变量)的元数据信息,这些信息可以在编译时、运行时或工具处理时使用。配置和控制:注解可以用于配置和控制程序的行为。通过在类或方法上添加特定的注解,可以告诉编译器或运行时环境执行特定的操作。代码生成:某些注解可以用于生成额外的代码或配置文件。


元注解:

元注解是一种注解的注解,它用于描述其他注解。

@Retention: 只能用于修饰一个 Annotation 定义, 用于指定该 Annotation 可以保留多长时间,@Rentention 包含一个 RetentionPolicy 类型的成员变量, 使用 @Rentention 时必须为该 value 成员变量指定值(值有三种)。

  (1)RetentionPolicy.SOURCE: 编译器使用后,直接丢弃这种策略的注释。

  (2)RetentionPolicy.CLASS: 编译器将把注解记录在 class 文件中 . 当运行 Java 程序时 , JVM 不会保留注解。这是默认值。

  (3)RetentionPolicy.RUNTIME: 编译器将把注解记录在 class 文件中 . 当运行 Java 程序时 , JVM 会保留注解。程序可以通过反射获取该注解。

@Target:用于修饰 Annotation 定义,指定被修饰的 Annotation 能用于修饰哪些程序元素。

用于描述注解的使用范围,也就是注解可以用在什么地方,取值有:

CONSTRUCTOR:用于描述构造器。

FIELD:用于描述字段。

LOCAL_VARIABLE:用于描述局部变量。

METHOD:用于描述方法。

PACKAGE:用于描述包。

PARAMETER:用于描述参数。

TYPE:用于描述类,包括class,interface,enum。

@Inherited:使被它修饰的注解具有继承性(如果某个类使用了被@Inherited修饰的注解,则其子类将自动具有该注解)。。

@Documented

将此注解包含在 javadoc 中 ,它代表着此注解会被javadoc工具提取成文档。它是一个标记注解,没有成员。

定义注解

图片来源:注解和反射-KuangStudy-文章

//自定义注解
public class Demo03_CustomAnnotation {
    //注解可以显示赋值,如果没有默认值,就必须给注解赋值
    @MyAnnotation2(name = "张三")
    public void test() {
    }
}
@Target(value = {ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2 {
    //注解的参数:参数类型+参数名()
    //String name();
    String name() default "";
    int age() default 0;
    int id() default -1;//-1代表不存在
    String[] schools() default {"牛津大学","哈佛大学"};

定义新的注解类型使用@interface关键字(在原有的interface关键字前增加@符号)

//定义一个简单的注解类型

public @interface 注解名

{   成员变量;

}

注解可以带成员变量,或者没有成员变量。

下面定义了一个无成员变量的名为Test的简单注解:

public @interface Test

{   

}

成员变量在注解定义中以无形参的方法形式来声明,其方法名和返回值定义了该成员变量的名字和类型。

如下代码定义带两个成员变量的名为MyTag的注解

public @interface MyTag

{

String name();   //注解中的成员变量以方法的形式来定义

int age();

}

定义了注解后,可用注解来修饰程序中的类、方法、变量、接口等定义。

使用注解的语法是:@注解名,

通常会把注解放在所有修饰符之前,单独成行;

例如,使用上面定义的无成员变量的简单注解 @Test修饰类定义

@Test

public class MyClass

{

...

}

如下程序使用简单注解@Test来修饰方法。

public class MyClass

{        @Test

public void info()

}

如果注解是带成员变量的注解,那么,

使用该注解时就应该为它的成员变量指定值,

因而注解的长度可能较长,所以通常把注解另放一行,

如下面程序所示,使用上面定义的带成员变量的@MyTag注解,需要为成员变量赋值

public class Test

{

@MyTag(name ="xx",age = 6)

public void info()

{...}

...

}

也可以在定义注解的成员变量时为其指定初始值(默认值),

指定成员变量的初始值可使用default关键字。

如下代码定义了@MyTag注解,该注解里包含了两个成员变量:name和age,

这两个成员变量使用default指定了初始值。

public @interface MyTag

{

String name() default "yeeku";

int age() default 32;

}

如果为注解的成员变量指定了默认值,

使用该注解时则可以不为这些成员变量指定值,而是直接使用默认值。

public class Test

{

@MyTag    //因为它的成员变量有默认值,所以可以不为它的成员变量指定值

public void info()

{ ...  }

}

当然也可以在使用MyTag注解时为成员变量指定值,

如果为MyTag的成员变量指定了值,则默认值不会起作用。

根据注解是否可以包含成员变量,可以把注解分为如下两类:

标记注解:没有定义成员变量的注解类型被称为标记。

这种注解仅利用自身的存在与否来提供信息,如前面介绍的@Override、@Test等注解。

本次学习任务自己设计一个注解接口,并写出接口处理程序,并进行测试

package Annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(value = RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
 @interface annotation {
        String value() default "Hello World";
    }

package Annotation;

import java.lang.reflect.Method;
public class annotationProcessor {
        public static void processAnnotations(Object object) {
            Class<?> testClass = object.getClass();
              // 遍历testClass对应的类里的所有方法
            for (Method method : testClass.getDeclaredMethods()) {
                //如果该方法使用了@annotation修饰
                if (method.isAnnotationPresent(annotation.class)) {
                    //获取该方法上的@annotation注解
                    annotation annotation = method.getAnnotation(annotation.class);
                    //获取注解里的value值
                    String value = annotation.value();
                    System.out.println("Method " + method.getName() + " has @annotation with value: " + value);
                }
            }
        }
}

package Annotation;

public class Test {
    @annotation
    public void method_A(){
    }
    @annotation("Hello Sky")
    public void method_B(){
    }
    @annotation("Hello Earth")
    public void method_C(){

    }
}

package Annotation;

public class Main {
    public static void main(String[] args) {
        Test test = new Test();
        annotationProcessor.processAnnotations(test);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值