Java Annotation注解相关原理代码总结

作者:Haidnor 时间:2023-11-18 02:13:57 

Java.lang 中自带的注解

  • @Override:表示当前的方法定义将覆盖基类的方法。如果你不小心拼写错误,或者方法签名被错误拼写的时候,编译器就会发出错误提示。

  • @Deprecated:如果使用该注解的元素被调用,编译器就会发出警告信息。

  • @SuppressWarnings:关闭不当的编译器警告信息。

  • @SafeVarargs:在 Java 7 中加入用于禁止对具有泛型varargs参数的方法或构造函数的调用方发出警告。

  • @FunctionalInterface:Java 8 中加入用于表示类型声明为函数式接口

如何定义注解

以下是一个为标记注解(marker annotation), 不包含任何元素


package cn.haidnor.annotation;

import java.lang.annotation.*;

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

}

注解的定义也需要一些元注解(meta-annoation),比如 @Target 和 @Retention。

@Target 定义你的注解可以应用在哪里(例如是方法还是字段)。

@Retention 定义了注解在哪里可用,在源代码中(SOURCE),class文件(CLASS)中或者是在运行时(RUNTIME)。

Demo 简单实例

定义注解

以下的代码中。Target 定义只能在方法上使用,Retention 定义保留域


package cn.haidnor.annotation;

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
 int id();
 String description() default "no description";
}

在类中使用注解


package cn.haidnor.clazz;
package cn.haidnor.clazz;
import cn.haidnor.annotation.UseCase;
import java.util.List;

public class PasswordUtils {
 @UseCase(id = 47, description ="Passwords must contain at least one numeric")
 public boolean validatePassword(String passwd) {
   return (passwd.matches("\\w*\\d\\w*"));
 }
 @UseCase(id = 48)
 public String encryptPassword(String passwd) {
   return new StringBuilder(passwd)
       .reverse().toString();
 }
 @UseCase(id = 49, description = "New passwords can't equal previously used ones")
 public boolean checkForNewPassword(
     List<String> prevPasswords, String passwd) {
   return !prevPasswords.contains(passwd);
 }
}

对以上 demo 中的代码进行测试


package cn.haidnor.test;

import cn.haidnor.annotation.UseCase;
import cn.haidnor.clazz.PasswordUtils;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.*;
import java.lang.reflect.*;

public class UseCaseTracker {

public static void main(String[] args) {
   List<Integer> useCases = IntStream.range(44, 51)
       .boxed().collect(Collectors.toList());
   trackUseCases(useCases, PasswordUtils.class);
 }

public static void trackUseCases(List<Integer> useCasesList, Class<?> clazz) {
   // getDeclaredMethods() 获取所有公开的方法
   for(Method m : clazz.getDeclaredMethods()) {
     // getAnnotation() 获取指定注解
     UseCase uc = m.getAnnotation(UseCase.class);
     if(uc != null) {
       System.out.print("Found Use Case ");
       // 提取注解元素值
       System.out.println(uc.id());
       // 提取注解元素值
       System.out.println('\t' + uc.description());
       useCasesList.remove( Integer.valueOf( uc.id() ) );
     }
   }

// 迭代集合
   useCasesList.forEach(new Consumer<Integer>() {
     @Override
     public void accept(Integer integer) {
       System.out.println("Missing use case " + integer);
     }
   });
   // 以上代码可以使用箭头行数简写
   // useCasesList.forEach(i -> System.out.println("Missing use case " + i));
 }
}

控制台输出结果


Found Use Case 47
 Passwords must contain at least one numeric
Found Use Case 48
 no description
Found Use Case 49
 New passwords can't equal previously used ones
Missing use case 44
Missing use case 45
Missing use case 46
Missing use case 50

元注解

Java 语言中目前有 5 种标准注解(前面介绍过),以及 5 种元注解。元注解用于注解其他的注解

Java Annotation注解相关原理代码总结

注解中可以使用的元素

所有基本类型(int、float、boolean等)

  • String

  • Class

  • enum

  • Annotation

  • 以上类型的数组

其他类型,编译器就会报错。注意,也不允许使用任何包装类型

  • 注解的默认值

无论是在源代码声明时还是在注解接口中定义默认值时,都不能使用 null 作为其值。


import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SimulatingNull {
 int id() default -1;
 String description() default "";
}

使用反射获取注解的方法流程图

Java Annotation注解相关原理代码总结

来源:https://www.cnblogs.com/Haidnor/p/13237985.html

标签:Java,Annotation,注解
0
投稿

猜你喜欢

  • 超详细的Spring Boot入门笔记(总结)

    2022-10-26 18:44:21
  • 一文了解Java读写锁ReentrantReadWriteLock的使用

    2023-10-12 19:28:21
  • 详解使用SSM实现简单工作流系统之实现篇

    2021-10-21 07:49:23
  • Android超详细讲解组件ScrollView的使用

    2022-08-05 09:55:18
  • 详细聊聊C#的并发机制优秀在哪

    2023-03-04 15:41:18
  • 一文搞懂c# await,async执行流

    2023-07-14 01:22:35
  • Java微信授权登陆的实现示例

    2021-12-11 22:03:04
  • java Iterator.remove()实例方法分析

    2022-05-01 15:56:01
  • Java Spring中Quartz调度器详解及实例

    2022-09-30 03:31:13
  • C# null 合并运算符??(双问号)使用示例

    2022-12-03 02:29:19
  • Mybatis-plus多租户项目实战进阶指南

    2023-10-10 18:14:43
  • Android启动页用户相关政策弹框的实现代码

    2021-06-30 15:29:30
  • Tablayout简单使用方法总结

    2022-01-08 16:27:37
  • Android笔记之:CM9源码下载与编译的应用

    2022-09-23 05:40:14
  • java利用递归算法实现对文件夹的删除功能

    2023-07-26 06:37:02
  • openFeign服务之间调用保持请求头信息处理方式

    2022-11-07 23:45:21
  • C# Web应用调试开启外部访问步骤解析

    2023-04-01 15:24:01
  • Toast类避免显示时间叠加的方法

    2021-08-20 02:01:42
  • C#表达式和运算符详细解析

    2021-09-30 23:39:09
  • Java基础之String类使用与字符串比较

    2023-11-09 23:46:51
  • asp之家 软件编程 m.aspxhome.com