java语言注解基础概念详解

 更新时间:2017年12月26日 08:39:15   作者:hypmxy  
这篇文章主要介绍了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语言注解基础概念详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

相关文章

  • Java泛型详解

    Java泛型详解

    本文给大家汇总介绍了下java中的泛型的相关资料,包括引入泛型机制的原因,泛型类,泛型方法,泛型的实现以及泛型的注意事项,非常的详细,有需要的小伙伴可以参考下
    2016-03-03
  • 百度Java面试题 前200页精选(上)

    百度Java面试题 前200页精选(上)

    这篇文章主要为大家分享了Java面试资源,百度“Java面试题”前200页都在这里了,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • Mac上配置JDK 1.8的超详细流程

    Mac上配置JDK 1.8的超详细流程

    相信每个拿到MAC的小伙伴都是很欣喜的,但是由于MAC系统与WIN系统有着极大的不同,所以使用起来会有一些小困扰,这篇文章主要给大家介绍了关于Mac上配置JDK 1.8的超详细流程,需要的朋友可以参考下
    2023-11-11
  • SpringBoot2.3定制错误页面的方法示例

    SpringBoot2.3定制错误页面的方法示例

    这篇文章主要介绍了SpringBoot2.3定制错误页面的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • MyBatisPlus的IService接口实现

    MyBatisPlus的IService接口实现

    MyBatisPlus是一个为MyBatis提供增强的工具,它通过IService接口简化了数据库的CRUD操作,IService接口封装了一系列常用的数据操作方法,本文就来介绍一下,感兴趣的可以了解一下
    2024-10-10
  • springmvc实现json交互-requestBody和responseBody

    springmvc实现json交互-requestBody和responseBody

    本文主要介绍了springmvc实现json交互-requestBody和responseBody的相关知识。具有很好的参考价值。下面跟着小编一起来看下吧
    2017-03-03
  • Java算法之时间复杂度和空间复杂度的概念和计算

    Java算法之时间复杂度和空间复杂度的概念和计算

    这篇文章主要介绍了Java算法之时间复杂度和空间复杂度的概念和计算,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-05-05
  • java判断String类型是否能转换为int的方法

    java判断String类型是否能转换为int的方法

    今天小编就为大家分享一篇java判断String类型是否能转换为int的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • Java Web项目中验证码功能的制作攻略

    Java Web项目中验证码功能的制作攻略

    使用servlet制作验证码中最关键的部分是缓存的使用,验证session中的字符串,接下来我们就来看一下Java Web项目中验证码功能的制作攻略
    2016-05-05
  • Nacos 版本不一致报错Request nacos server failed解决

    Nacos 版本不一致报错Request nacos server failed解决

    这篇文章主要为大家介绍了Nacos 版本不一致报错Request nacos server failed的解决方法,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11

最新评论