java语言注解基础概念详解

所属分类: 软件编程 / java 阅读数: 15
收藏 0 赞 0 分享

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数据类型的规则的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

Spring整合TimerTask实现定时任务调度

这篇文章主要介绍了Spring整合TimerTask实现定时任务调度的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

详解SpringMVC使用MultipartFile实现文件的上传

本篇文章主要介绍了SpringMVC使用MultipartFile实现文件的上传,本地的文件上传到资源服务器上,比较好的办法就是通过ftp上传。这里是结合SpringMVC+ftp的形式上传的,有兴趣的可以了解一下。
收藏 0 赞 0 分享

SpringMVC上传文件的三种实现方式

本篇文章主要介绍了SpringMVC上传文件的三种实现方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

微信公众帐号开发-自定义菜单的创建及菜单事件响应的实例

本篇文章主要介绍了微信公众帐号开发-自定义菜单的创建及菜单事件响应的实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
收藏 0 赞 0 分享

浅析Java中的继承与组合

本文将介绍组合和继承的概念及区别,并从多方面分析在写代码时如何进行选择。文中通过示例代码介绍的很详细,有需要的朋友可以参考借鉴,下面来一起看看吧。
收藏 0 赞 0 分享

利用反射获取Java类中的静态变量名及变量值的简单实例

下面小编就为大家带来一篇利用反射获取Java类中的静态变量名及变量值的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

java启动线程的3种方式对比分析

这篇文章主要为大家对比分析了java启动线程的3种方式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

SpringMVC上传和解析Excel方法

这篇文章主要介绍了SpringMVC上传和解析Excel方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

JAVA中String类与StringBuffer类的区别

这篇文章主要为大家详细介绍了JAVA中String类与StringBuffer类的区别,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享
查看更多