首页 > 编程语言 >深入理解Java注解Annotation:从基础到实战

深入理解Java注解Annotation:从基础到实战

时间:2024-12-05 13:32:00浏览次数:4  
标签:Java 自定义 Annotation public Book 注解 class

深入理解Java注解Annotation:从基础到实战

引言

Java注解(Annotation)是JDK 1.5引入的一个强大特性,它允许开发者在代码中添加元数据(metadata),这些元数据可以在编译时、类加载时或运行时被读取和处理。注解不仅简化了代码的配置和维护,还为框架和工具提供了丰富的扩展点。本文将详细介绍Java注解的基本概念、自定义注解的创建、注解的使用以及注解的解析,并通过一个综合案例来展示注解的实际应用。

1. 什么是注解?

注解(Annotation)是一种代码级别的说明,它可以在包、类、字段、方法、局部变量、方法参数等元素的前面声明,用来对这些元素进行说明。注解本质上是一个接口,所有注解都会继承java.lang.annotation.Annotation接口。

注解的作用主要包括:

  1. 编译检查:例如@Override注解用于检查方法是否重写了父类的方法。
  2. 代码分析:通过注解对代码进行分析,例如框架的配置。
  3. 生成帮助文档:例如@author@version注解用于生成文档时标记作者和版本信息。

2. 自定义注解

2.1 注解的定义格式

自定义注解使用@interface关键字来定义,格式如下:

public @interface 注解名 {
    // 属性定义
    数据类型 属性名();
    数据类型 属性名() default 默认值;
}

例如,定义一个简单的注解Book

public @interface Book {
    String name();
    double price() default 100.0;
    String[] author();
}
2.2 注解的属性

注解的属性可以是以下类型:

  • 八种基本数据类型(int, short, long, double, byte, char, boolean, float)
  • String, Class, 注解类型, 枚举类
  • 以上类型的一维数组形式

3. 注解的使用

3.1 注解的使用格式

注解的使用格式如下:

@注解名(属性=值, 属性=值)

例如,使用上面定义的Book注解:

@Book(name = "Java编程思想", author = {"Bruce Eckel"})
public class BookStore {
    @Book(name = "Effective Java", price = 50.0, author = {"Joshua Bloch"})
    public void buy() {
        System.out.println("购书.....");
    }
}
3.2 特殊属性value

如果注解中只有一个属性,并且属性名为value,则在使用时可以省略value属性名:

@interface A {
    String value();
}

@A("值") // 当自定义注解中仅有一个value属性时,可以省略value属性名
public void test() {
}

4. 元注解

元注解是用来约束自定义注解的使用范围和生命周期的注解。常用的元注解有@Target@Retention

4.1 @Target

@Target用于指定注解的使用位置,可选的参数值在ElementType枚举类中定义:

  • TYPE:用在类、接口上
  • FIELD:用在成员变量上
  • METHOD:用在方法上
  • PARAMETER:用在参数上
  • CONSTRUCTOR:用在构造方法上
  • LOCAL_VARIABLE:用在局部变量上

例如:

@Target({ElementType.METHOD, ElementType.TYPE})
public @interface MyAnnotation {
}
4.2 @Retention

@Retention用于指定注解的生命周期,可选的参数值在RetentionPolicy枚举类中定义:

  • SOURCE:注解只存在于源代码中,编译后的字节码文件中不存在
  • CLASS:注解存在于源代码和字节码文件中,运行时内存中不存在(默认值)
  • RUNTIME:注解存在于源代码、字节码文件和运行时内存中,可以通过反射获取

例如:

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}

5. 注解解析

注解解析是通过反射技术来获取注解中的数据。AnnotatedElement接口定义了解析注解的方法,ClassMethodField等类都实现了该接口。

5.1 获取注解数据的原理
boolean isAnnotationPresent(Class<Annotation> annotationClass);
T getAnnotation(Class<T> annotationClass);

例如,解析Book注解:

public class TestBookStore {
    public static void main(String[] args) throws NoSuchMethodException {
        Class<BookStore> bookStoreClass = BookStore.class;
        Method method = bookStoreClass.getMethod("buy");

        if (method.isAnnotationPresent(Book.class)) {
            Book bookAnno = method.getAnnotation(Book.class);
            System.out.println("书名:" + bookAnno.name());
            System.out.println("价格:" + bookAnno.price());
            System.out.println("作者:" + Arrays.toString(bookAnno.author()));
        }
    }
}

6. 综合案例:模拟Junit测试

6.1 需求

模拟Junit测试的@Test注解,实现一个自定义注解@MyTest,并在目标类中使用该注解标记测试方法,最后通过反射调用所有带有@MyTest注解的方法。

6.2 实现
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

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

public class TestAnnotationParse {
    @MyTest
    public void method1() {
        System.out.println("我是方法1");
    }

    @MyTest
    public void method3() {
        System.out.println("我是方法3");
    }

    public void method2() {
        System.out.println("我是方法2");
    }
}

public class Test {
    public static void main(String[] args) throws Exception {
        Class<TestAnnotationParse> testClass = TestAnnotationParse.class;
        Method[] methods = testClass.getMethods();

        for (Method method : methods) {
            if (method.isAnnotationPresent(MyTest.class)) {
                method.invoke(testClass.newInstance());
            }
        }
    }
}

7. 总结

Java注解是一个强大的工具,它允许开发者在代码中添加元数据,并通过反射技术在运行时获取这些元数据。通过自定义注解,开发者可以实现许多高级功能,如编译检查、代码分析和生成文档。本文详细介绍了注解的基本概念、自定义注解的创建、注解的使用以及注解的解析,并通过一个综合案例展示了注解的实际应用。希望本文能帮助读者更好地理解和使用Java注解。

参考文献

标签:Java,自定义,Annotation,public,Book,注解,class
From: https://www.cnblogs.com/itcq1024/p/18588346

相关文章

  • Java中金额处理选择详解:BigDecimal vs Long vs Double
    Java中金额处理选择详解:BigDecimalvsLongvsDouble金额处理是开发中非常重要的一部分,特别是在金融、电商等涉及交易的系统中。以下是对三种方式(BigDecimal、Long、Double)的详细分析,以及为什么推荐BigDecimal的原因。1.Double为什么不适合处理金额?1.1浮点数的精......
  • 如何利用Java爬虫淘宝/天猫获取SKU详细信息数据
    在电商领域,获取商品SKU信息对于商家来说至关重要。通过Java爬虫技术,我们可以轻松获取淘宝和天猫平台上的SKU详细信息数据。本文将详细介绍如何利用Java爬虫技术实现这一目标,并提供代码示例。1.注册开放平台账号首先,您需要在淘宝开放平台注册一个开发者账号,并创建应用以获取......
  • 利用Java反射做通用框架
    以下内容均由AI生成Cat类点击查看代码packagecom.itcq.reflect.test;publicclassCat{publicvoideat(){System.out.println("猫爱吃鱼~~~");}publicvoidsleep(){System.out.println("猫睡觉打呼噜~~~");}}Dog类点击查......
  • 探索实用的Java工具类
    1.排序有时需要对集合进行排序。此时可以使用Collections的sort方法。List<Integer>list=newArrayList<>();list.add(2);list.add(1);list.add(3);Collections.sort(list);//ASCSystem.out.println("ASC-排序后:"+list......
  • 【一文读懂】SPI机制之JAVA的SPI实现详解
    ......
  • 【最新原创毕设】基于SpringBoot的网上报修平台+94800(免费领源码)可做计算机毕业设计JA
    摘要随着信息技术的快速发展和普及,高校宿舍管理面临着诸多挑战与机遇。传统的宿舍管理模式,如手工记录报修信息、纸质文档管理等,已无法满足现代高校对效率和便捷性的需求。因此,开发一套高效、智能的网上报修平台显得尤为重要。基于springBoot的网上报修平台的设计和实现正......
  • 【开源】A064—基于JAVA的民族婚纱预定系统的设计与实现
    ......
  • (面试常考)Java基础 - 接口与抽象类的区别
    接口接口(Interface)的传统定义是只能包含抽象方法(即没有方法体的方法)以及常量。但是从Java8开始,接口可以包含非抽象方法了。这些非抽象方法包括:默认方法(DefaultMethods):使用default关键字声明的方法。它们允许在接口中提供一个方法的默认实现,这样实现了该接口的类可......
  • Java 界最好用的开源行为验证码工具!
    大家好,我是Java陈序员。今天,给大家介绍一个开源的基于Java实现的行为验证码工具!关注微信公众号:【Java陈序员】,获取开源项目分享、AI副业分享、超200本经典计算机电子书籍等。项目介绍TIANAI-CAPTCHA——天爱验证码,基于Java实现的开源行为验证码,涵盖滑块验证码、旋转......
  • 常用JavaScript 单行代码
    1.不使用临时变量来交换变量的值例如我们想要将a于b的值交换leta=1,b=2;//交换值[a,b]=[b,a];//结果:a=2,b=12.对象解构,让数据访问更便捷const{name,age}={name:'张三',age:23};//结果:name='张三',age=233.浅克隆对象......