java语言注解基础概念详解

1、RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;

2、RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;

3、RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;

这3个生命周期分别对应于:Java源文件(.java文件)--->.class文件--->内存中的字节码。

那怎么来选择合适的注解生命周期呢?

首先要明确生命周期长度SOURCE<CLASS<RUNTIME,所以前者能作用的地方后者一定也能作用。一般如果需要在运行时去动态获取注解信息,那只能用RUNTIME注解;如果要在编译时进行一些预处理操作,比如生成一些辅助代码(如ButterKnife),就用CLASS注解;如果只是做一些检查性的操作,比如@Override和@SuppressWarnings,则可选用SOURCE注解。

下面来介绍下运行时注解的简单运用。

获取注解

你需要通过反射来获取运行时注解,可以从Package、Class、Field、Method...上面获取,基本方法都一样,几个常见的方法如下:

/**
 * 获取指定类型的注解
 */
public <A extends Annotation> A getAnnotation(Class<A> annotationType);
/**
 * 获取所有注解,如果有的话
 */
public Annotation[] getAnnotations();
/**
 * 获取所有注解,忽略继承的注解
 */
public Annotation[] getDeclaredAnnotations();
/**
 * 指定注解是否存在该元素上,如果有则返回true,否则false
 */
public Boolean isAnnotationPresent(Class<? extends Annotation> annotationType);
/**
 * 获取Method中参数的所有注解
 */
public Annotation[][] getParameterAnnotations();

要使用这些函数必须先通过反射获取到对应的元素:Class、Field、Method等。

自定义注解

来看下自定义注解的简单使用方式,这里先定义3个运行时注解:

// 适用类、接口(包括注解类型)或枚举
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ClassInfo {
  String value();
}
// 适用field属性,也包括enum常量
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FieldInfo {
  int[] value();
}
// 适用方法
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MethodInfo {
  String name() default "long";
  String data();
  int age() default 27;
} 

这3个注解分别适用于不同的元素,并都带有不同的属性,在使用注解是需要设置这些属性值。

再定义一个测试类来使用这些注解:

/**
 * 测试运行时注解
 */
@ClassInfo("Test Class")
public class TestRuntimeAnnotation {
	@FieldInfo(value = {1, 2})
	  public String fieldInfo = "FiledInfo";
	@FieldInfo(value = {10086})
	  public int i = 100;
	@MethodInfo(name = "BlueBird", data = "Big")
	  public static String getMethodInfo() {
		return TestRuntimeAnnotation.class.getSimpleName();
	}
}

使用还是很简单的,最后来看怎么在代码中获取注解信息:

/**
 * 测试运行时注解
 */
private void _testRuntimeAnnotation() {
	StringBuffer sb = new StringBuffer();
	Class<?> cls = TestRuntimeAnnotation.class;
	Constructor<?>[] constructors = cls.getConstructors();
	// 获取指定类型的注解
	sb.append("Class注解:").append("\n");
	ClassInfo classInfo = cls.getAnnotation(ClassInfo.class);
	if (classInfo != null) {
		sb.append(Modifier.toString(cls.getModifiers())).append(" ")
		        .append(cls.getSimpleName()).append("\n");
		sb.append("注解值: ").append(classInfo.value()).append("\n\n");
	}
	sb.append("Field注解:").append("\n");
	Field[] fields = cls.getDeclaredFields();
	for (Field field : fields) {
		FieldInfo fieldInfo = field.getAnnotation(FieldInfo.class);
		if (fieldInfo != null) {
			sb.append(Modifier.toString(field.getModifiers())).append(" ")
			          .append(field.getType().getSimpleName()).append(" ")
			          .append(field.getName()).append("\n");
			sb.append("注解值: ").append(Arrays.toString(fieldInfo.value())).append("\n\n");
		}
	}
	sb.append("Method注解:").append("\n");
	Method[] methods = cls.getDeclaredMethods();
	for (Method method : methods) {
		MethodInfo methodInfo = method.getAnnotation(MethodInfo.class);
		if (methodInfo != null) {
			sb.append(Modifier.toString(method.getModifiers())).append(" ")
			          .append(method.getReturnType().getSimpleName()).append(" ")
			          .append(method.getName()).append("\n");
			sb.append("注解值: ").append("\n");
			sb.append("name: ").append(methodInfo.name()).append("\n");
			sb.append("data: ").append(methodInfo.data()).append("\n");
			sb.append("age: ").append(methodInfo.age()).append("\n");
		}
	}
	System.out.print(sb.toString());
}

所做的操作都是通过反射获取对应元素,再获取元素上面的注解,最后得到注解的属性值。

看一下输出情况,这里我直接显示在手机上:

总结

以上就是本文关于java语言注解基础概念详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

(0)

相关推荐

  • Java注解机制之Spring自动装配实现原理详解

    Java中使用注解的情况主要在SpringMVC(Spring Boot等),注解实际上相当于一种标记语言,它允许你在运行时动态地对拥有该标记的成员进行操作.注意:spring框架默认不支持自动装配的,要想使用自动装配需要修改spring配置文件中<bean>标签的autowire属性. 自动装配属性有6个值可选,分别代表不同的含义: byName ->从Spring环境中获取目标对象时,目标对象中的属性会根据名称在整个Spring环境中查找<bean>标签的id属性值.如果

  • 深入理解 Java注解及实例

     Java注解 什么是注解? Java中的注解就是Java源代码的元数据,也就是说注解是用来描述Java源代码的. 基本语法就是:@后面跟注解的名称. ①Override:标识某一个方法是否正确覆盖了它的父类的方法. ②Deprecated:表示已经不建议使用这个类成员了. 它是一个标记注解. ③SuppressWarnings:用来抑制警告信息 等等. 要更好的理解注解,我们可以自己写一个注解 @Target : 用来限制注解可以用到那几个地方.比方可以用到类上,可以用到方法胜都可以用@Tar

  • Java之Spring注解配置bean实例代码解析

    前面几篇均是使用xml配置bean,如果有上百个bean,这是不可想象的.故而,请使用注解配置bean !!! [1]注解类别 @Component : 基本注解, 标识了一个受 Spring(点击这里可以下载<Spring应用开发完全手册>) 管理的组件 @Repository : 标识持久层组件 @Service : 标识服务层(业务层)组件 @Controller : 标识表现层组件 Spring 能够从 classpath 下自动扫描, 侦测和实例化具有特定注解的组件. 对于扫描到的组

  • 浅谈Java注解和动态代理

    本文主要介绍Java中与注解和动态代理有关的部分知识,接下来我们看看具体内容. Annotation(注解) 其实就是代码里的特殊标记, 它用于替代配置文件,也就是说,传统方式通过配置文件告诉类如何运行,有了注解技术后,开发人员可以通过注解告诉类如何运行. 1. 三个基本的Annotation: Override:限定重写父类方法, 该注解只能用于方法 Deprecated:用于表示某个程序元素(类, 方法等)已过时 SuppressWarnings:抑制编译器警告. 2.自定义Annotati

  • Java利用反射如何查找使用指定注解的类详解

    前言 最近有些空,想自己写个跟spring里的注解一样的注解来用,然后希望能找到使用了自己写了注解的类,下面来介绍一下实现方法 声明,下面代码是没看过spring源码写的,基本上都是网上找的博客,整理的 定义注解 Controller.java @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Controller { } RequestMapping.jav

  • java中注解机制及其原理的详解

    java中注解机制及其原理的详解 什么是注解 注解也叫元数据,例如我们常见的@Override和@Deprecated,注解是JDK1.5版本开始引入的一个特性,用于对代码进行说明,可以对包.类.接口.字段.方法参数.局部变量等进行注解.它主要的作用有以下四方面: 生成文档,通过代码里标识的元数据生成javadoc文档. 编译检查,通过代码里标识的元数据让编译器在编译期间进行检查验证. 编译时动态处理,编译时通过代码里标识的元数据动态处理,例如动态生成代码. 运行时动态处理,运行时通过代码里标识

  • java 自定义注解的实例详解

    java  自定义注解的实例详解 Java的Annotation是在5.0版本之后引入的,可以用于创建文档,跟踪代码中的依赖性,并且可以执行编译时期检查.注解就是给虚拟机看的,代表程序的一些特殊的功能.JDK中提供了@Override,@SuppressWarning,@Deprecated三种注解,当让还有元注解,@Target,@Retention,@Documented,@Inherited,元注解的作用负责注解其它注解. 要想了解注解,就要了解自定义注解,了解是通过反射来实现的. 首先,

  • Java注解处理器简单实例

    如果没有用来读取注解的方法和工作,那么注解也就不会比注释更有用处了.使用注解的过程中,很重要的一部分就是创建于使用注解处理器.JavaSE5扩展了反射机制的API,以帮助程序员快速的构造自定义注解处理器. 注解处理器类库(java.lang.reflect.AnnotatedElement): Java使用Annotation接口来代表程序元素前面的注解,该接口是所有Annotation类型的父接口.除此之外,Java在java.lang.reflect包下新增了AnnotatedElement

  • java语言注解基础概念详解

    1.RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃: 2.RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期: 3.RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在: 这3个生命周期分别对应于:Java源文件(.java文件)--->.class文件--->内存中的字节码.

  • 基于JS脚本语言的基础语法详解

    JS脚本语言的基础语法:输出语法  alert("警告!");  confirm("确定吗?");   prompt("请输入密码");为弱类型语言: 开始时要嵌入JS代码:<script type="text/javascript"></script>: 关于写程序是需注意的基本语法: 1.所有的字符全都是英文半角的: 2.大部分情况下每条语句结束后要加分号: 3.每一块代码结束后加换行:4.程序前呼

  • JVM内存管理之JAVA语言的内存管理详解

    引言 内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑.不过世界上不存在十全十美的好事,在带来了便利的同时,也因此引入了很多令人抓狂的内存溢出和泄露的问题. 可怕的事情还不只如此,有些使用其它语言开发的程序员,给JAVA程序员扣上了一个"不懂内存"的帽子,这着实有点让人难以接受.毕竟JAVA当中没有malloc和delete.没有析构函数.没有指针,刚开始接触JAVA的程序员们又怎么可能接触内存这一部分呢,更何况有不

  • 基于java中集合的概念(详解)

    1.集合是储存对象的,长度可变,可以封装不同的对象 2.迭代器: 其实就是取出元素的方式(只能判断,取出,移除,无法增加) 就是把取出方式定义在集合内部,这样取出方式就可以直接访问集合内部的元素,那么取出方式就被定义成了内部类. 二每一个容器的数据结构不同,所以取出的动作细节也不一样.但是都有共性内容判断和取出,那么可以将共性提取,这些内部类都符合一个规则Iterator Iterator it = list.iterator(); while(it.hasNext()){ System.out

  • R语言决策基础知识点详解

    决策结构要求程序员指定要由程序评估或测试的一个或多个条件,以及如果条件被确定为真则要执行的一个或多个语句,如果条件为假则执行其他语句. 以下是在大多数编程语言中的典型决策结构的一般形式 R提供以下类型的决策语句. 单击以下链接以检查其详细信息. Sr.No. 声明和描述 1 if语句 if语句由一个布尔表达式后跟一个或多个语句组成. 2 if ... else语句 if语句后面可以有一个可选的else语句,当布尔表达式为false时执行. 3 switch语句 switch语句允许根据值列表测试

  • Java @Pointcut注解表达式案例详解

    1 表达式类型 标准的Aspectj Aop的pointcut的表达式类型是很丰富的,但是Spring Aop只支持其中的9种,外加Spring Aop自己扩充的一种一共是10种类型的表达式,分别如下. execution:一般用于指定方法的执行,用的最多. within:指定某些类型的全部方法执行,也可用来指定一个包. this:Spring Aop是基于代理的,生成的bean也是一个代理对象,this就是这个代理对象,当这个对象可以转换为指定的类型时,对应的切入点就是它了,Spring Ao

  • Go语言字符串基础示例详解

    目录 包含 Contains(s,substr string) bool ContainsAny(s, chars string) bool 统计 Count(s, substr string) int 比较 EqualFold(s, t string) bool HasPrefix(s, prefix string) bool HasSuffix(s, suffix string) bool 分割 Fields(s string) []string 下标 Index(s, sep string

  • java  自定义注解的实例详解

    java  自定义注解的实例详解 Java的Annotation是在5.0版本之后引入的,可以用于创建文档,跟踪代码中的依赖性,并且可以执行编译时期检查.注解就是给虚拟机看的,代表程序的一些特殊的功能.JDK中提供了@Override,@SuppressWarning,@Deprecated三种注解,当让还有元注解,@Target,@Retention,@Documented,@Inherited,元注解的作用负责注解其它注解. 要想了解注解,就要了解自定义注解,了解是通过反射来实现的. 首先,

  • C语言操作符基础知识详解

    目录 一.单目操作符: 二.关系操作符 三.条件操作符 四.逗号表达式 五.逻辑操作符 总结 一.单目操作符: !:逻辑反操作符: -:负数操作符: +:整数操作符: &:取地址操作符: sizeof:操作数的类型长度操作符: sizeof(数组名)--数组名表示整个数组,sizeof(数组名)求的是整个数组的大小,单位是字节 例如: int a[10] = { 0 }; printf("%d\n",sizeof(a)); suzeof(a[0]);-->(4) 不同的表

随机推荐