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

 更新时间:2020年07月07日 10:52:35   作者:Haidnor  
这篇文章主要介绍了Java Annotation注解相关原理代码总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

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 种元注解。元注解用于注解其他的注解

注解中可以使用的元素

所有基本类型(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 "";
}

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 浅谈JSONObject的使用及示例代码(JSON解析)

    浅谈JSONObject的使用及示例代码(JSON解析)

    这篇文章主要介绍了浅谈JSONObject的使用及示例代码(JSON解析),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • SpringBoot-Maven打包压缩瘦身方式

    SpringBoot-Maven打包压缩瘦身方式

    这篇文章主要介绍了SpringBoot-Maven打包压缩瘦身方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • springcloud初体验(真香)

    springcloud初体验(真香)

    这篇文章主要介绍了springcloud初体验(真香),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • 通过实例解析spring bean之间的关系

    通过实例解析spring bean之间的关系

    这篇文章主要介绍了通过实例解析spring bean之间的关系,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • Maven发布项目到Nexus私有服务器

    Maven发布项目到Nexus私有服务器

    本文主要介绍了Maven发布项目到Nexus私有服务器,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • SpringSecurity实现自定义登录接口的详细过程

    SpringSecurity实现自定义登录接口的详细过程

    本文详细介绍了如何使用SpringSecurity实现自定义登录接口,文章还涉及了对用户实体类的增强以满足详细信息的需求,适合需要深入了解和实现SpringSecurity自定义登录功能的开发者,感兴趣的朋友跟随小编一起看看吧
    2024-10-10
  • 如何获取Maven项目的版本号

    如何获取Maven项目的版本号

    最近需要在项目中获取项目的版本号,最笨的方法莫过于硬编码一个版本号,当然之前我也是这么干的。不过闲下来的时候突发奇想Spring Boot项目中pom.xml定义的版本号(也就是project.version的值)能不能通过API获得呢?于是利用摸鱼的时间研究了这种无聊透顶的东西。
    2021-05-05
  • 全面了解JAVA_BaseDAO数据处理类

    全面了解JAVA_BaseDAO数据处理类

    下面小编就为大家带来一篇全面了解JAVA_BaseDAO数据处理类。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-07-07
  • 深入理解Spring MVC的数据转换

    深入理解Spring MVC的数据转换

    这篇文章主要给大家介绍了关于Spring MVC数据转换的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起看看吧。
    2017-09-09
  • 一文简单了解C# 中的DataSet类

    一文简单了解C# 中的DataSet类

    这篇文章主要介绍了一文简单了解C# 中的DataSet类,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-08-08

最新评论