Annotation之三:自定义注解示例,利用反射进行解析
@Retention定义了该Annotation被保留的时间长短有3中RetentionPolicy.SOURCE源文件有效,RetentionPolicy.CLASS:在class文件中有效,RetentionPolicy.RUNTIME:在运行时有效。
要想注解解析工具或编译器对其进行解析,就需要指定注解在编译期或运行期有效。
在运行期要使用注解,是通过Java反射机制从一个类中解析注解,请记住,注解保持性策略应该是RUNTIME,否则它的信息在运行期无效,我们也不能从中获取任何数据。
(某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)
注解处理器类库(java.lang.reflect.AnnotatedElement)
Java使用java.lang.annotation.Annotation接口来代表程序元素前面的注解,该接口是所有Annotation类型的父接口。除此之外,Java在java.lang.reflect 包下新增了AnnotatedElement接口,该接口代表程序中可以接受注解的程序元素,该接口主要有如下几个实现类:
Class:类定义
Constructor:构造器定义
Field:累的成员变量定义
Method:类的方法定义
Package:类的包定义
java.lang.reflect 包下主要包含一些实现反射功能的工具类,实际上,java.lang.reflect 包所有提供的反射API扩充了读取运行时Annotation信息的能力。当一个Annotation类型被定义为运行时的Annotation后,该注解才能是运行时可见,当class文件被装载时被保存在class文件中的Annotation才会被虚拟机读取。
AnnotatedElement 接口是所有程序元素(Class、Method和Constructor)的父接口,所以程序通过反射获取了某个类的AnnotatedElement对象之后,程序就可以调用该对象的如下四个个方法来访问Annotation信息:
方法1:<T extends Annotation> T getAnnotation(Class<T> annotationClass): 返回改程序元素上存在的、指定类型的注解,如果该类型注解不存在,则返回null。
方法2:Annotation[] getAnnotations():返回该程序元素上存在的所有注解。
方法3:boolean isAnnotationPresent(Class<?extends Annotation> annotationClass):判断该程序元素上是否包含指定类型的注解,存在则返回true,否则返回false.
方法4:Annotation[] getDeclaredAnnotations():返回直接存在于此元素上的所有注释。与此接口中的其他方法不同,该方法将忽略继承的注释。(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。
程序通过反射获取了某个类的AnnotatedElement对象之后,使用上面的4个方法访问Annotation信息
- Field[] fields = clazz.getDeclaredFields();
- for(Field field :fields){
- if(field.isAnnotationPresent(FruitName.class)){
- //...
Field类
- public final
- class Field extends AccessibleObject implements Member {
AccessibleObject
- public class AccessibleObject implements AnnotatedElement {
- //...
示例:一个简单的自定义注解及注解处理器对该注解的解析:
1、水果的名称、颜色、供应商注解
- package com.dxz.annotation.demo4;
- import java.lang.annotation.Documented;
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
- /**
- * 水果名称注解
- */
- @Target(ElementType.FIELD)
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface FruitName {
- String value() default "";
- }
- package com.dxz.annotation.demo4;
- import java.lang.annotation.Documented;
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
- /**
- * 水果颜色注解
- */
- @Target(ElementType.FIELD)
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface FruitColor {
- /**
- * 颜色枚举
- * @author peida
- *
- */
- public enum Color{ BULE,RED,GREEN};
- /**
- * 颜色属性
- * @return
- */
- Color fruitColor() default Color.GREEN;
- }
- package com.dxz.annotation.demo4;
- import java.lang.annotation.Documented;
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
- /**
- * 水果供应者注解
- */
- @Target(ElementType.FIELD)
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface FruitProvider {
- /**
- * 供应商编号
- *
- * @return
- */
- public int id() default -1;
- /**
- * 供应商名称
- *
- * @return
- */
- public String name() default "";
- /**
- * 供应商地址
- *
- * @return
- */
- public String address() default "";
- }
2、使用注解(标注注解)
- package com.dxz.annotation.demo4;
- import com.dxz.annotation.demo4.FruitColor.Color;
- public class Apple {
- @FruitName("Apple")
- private String appleName;
- @FruitColor(fruitColor = Color.RED)
- private String appleColor;
- @FruitProvider(id = 1, name = "陕西红富士集团", address = "陕西省西安市延安路89号红富士大厦")
- private String appleProvider;
- public void setAppleColor(String appleColor) {
- this.appleColor = appleColor;
- }
- public String getAppleColor() {
- return appleColor;
- }
- public void setAppleName(String appleName) {
- this.appleName = appleName;
- }
- public String getAppleName() {
- return appleName;
- }
- public void setAppleProvider(String appleProvider) {
- this.appleProvider = appleProvider;
- }
- public String getAppleProvider() {
- return appleProvider;
- }
- public void displayName() {
- System.out.println("水果的名字是:苹果");
- }
- }
3、解析器解析
- package com.dxz.annotation.demo4;
- import java.lang.reflect.Field;
- public class FruitInfoUtil {
- public static void getFruitInfo(Class<?> clazz){
- String strFruitName=" 水果名称:";
- String strFruitColor=" 水果颜色:";
- String strFruitProvicer="供应商信息:";
- Field[] fields = clazz.getDeclaredFields();
- for(Field field :fields){
- if(field.isAnnotationPresent(FruitName.class)){
- FruitName fruitName = (FruitName) field.getAnnotation(FruitName.class);
- strFruitName=strFruitName+fruitName.value();
- System.out.println(strFruitName);
- }
- else if(field.isAnnotationPresent(FruitColor.class)){
- FruitColor fruitColor= (FruitColor) field.getAnnotation(FruitColor.class);
- strFruitColor=strFruitColor+fruitColor.fruitColor().toString();
- System.out.println(strFruitColor);
- }
- else if(field.isAnnotationPresent(FruitProvider.class)){
- FruitProvider fruitProvider= (FruitProvider) field.getAnnotation(FruitProvider.class);
- strFruitProvicer=" 供应商编号:"+fruitProvider.id()+" 供应商名称:"+fruitProvider.name()+" 供应商地址:"+fruitProvider.address();
- System.out.println(strFruitProvicer);
- }
- }
- }
- }
测试类:
- package com.dxz.annotation.demo4;
- public class Test {
- public static void main(String[] args) {
- FruitInfoUtil.getFruitInfo(Apple.class);
- }
- }
结果:
- 水果名称:Apple
- 水果颜色:RED
- 供应商编号:1 供应商名称:陕西红富士集团 供应商地址:陕西省西安市延安路89号红富士大厦
Java注解的基础知识点(见下面导图)基本都过了一遍,下一篇我们通过设计一个基于注解的简单的ORM框架,来综合应用和进一步加深对注解的各个知识点的理解和运用。
Annotation之三:自定义注解示例,利用反射进行解析的更多相关文章
- Java注解Annotation与自定义注解详解
Java注解简介 开发中经常使用到注解,在项目中也偶尔会见到过自定义注解,今天就来探讨一下这个注解是什么鬼,以及注解的应用场景和如何自定义注解. 下面列举开发中常见的注解 @Override:用于标识 ...
- [2]注解(Annotation)-- 深入理解Java:注解(Annotation)自定义注解入门
转载 http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 深入理解Java:注解(Annotation)自定义注解入门 要深入学习 ...
- Java注解教程:自定义注解示例,利用反射进行解析
Java注解能够提供代码的相关信息,同时对于所注解的代码结构又没有直接影响.在这篇教程中,我们将学习Java注解,如何编写自定义注解,注解的使用,以及如何使用反射解析注解. 注解是Java 1.5引入 ...
- 深入JAVA注解(Annotation):自定义注解 (转)
原文出自:http://blog.csdn.net/yjclsx/article/details/52101922 一.基础知识:元注解 要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义 ...
- 深入理解Java:注解(Annotation)自定义注解入门
转载:http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 元注解: 元注解的作用就是负责注解其他注解.Java5.0定义了4个标准 ...
- 【转】深入理解Java:注解(Annotation)自定义注解入门
http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 元注解: 元注解的作用就是负责注解其他注解.Java5.0定义了4个标准的me ...
- Java注解(Annotation)自定义注解入门
要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法. 元注解: 元注解的作用就是负责注解其他注解.Java5. ...
- Java:注解(Annotation)自定义注解入门
转载地址:http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的 ...
- 注解(Annotation)自定义注解入门
摘自:http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 元注解: 元注解的作用就是负责注解其他注解.Java5.0定义了4个标准 ...
随机推荐
- Amazon SES介绍 - SES发送邮件的过程
Amazon SES, 全称Amazon Simple Email Service,即Amazon简单邮件服务,它是Amazon提供的一款供开发人员或公司企业用来处理邮件相关业务的服务,也就是说, ...
- linux安装-----源码安装步骤--zlib软件安装
该zlib 可以对许多其他软件的编译代码起着优化 压缩作用. 解压压缩包: .tar.gz------------->tar zxvf 压缩包.tar.gz .tar.bz2---------- ...
- python学习笔记(SMTP邮件发送)
想着给框架添加邮件发送功能.所以整理下python下邮件发送功能 首先python是支持邮件的发送.内置smtp库.支持发送纯文本.HTML及添加附件的邮件 之后是邮箱.像163.qq.新浪等邮箱默认 ...
- python爬虫scrapy框架——爬取伯乐在线网站文章
一.前言 1. scrapy依赖包: 二.创建工程 1. 创建scrapy工程: scrapy staratproject ArticleSpider 2. 开始(创建)新的爬虫: cd Artic ...
- [csharp] bool IsNumeric(Type type)
/* "C:\Program Files (x86)\MSBuild\14.0\Bin\csc.exe" /out:IsNumericType.exe IsNumericType. ...
- MailJobUtils 发送邮件
import java.util.List; import java.util.Properties; import javax.annotation.Resource; import javax.m ...
- Pro C/C++环境搭建
一. 安装oracle软件或者oracle客户端. 二. 载入orasql10.lib (1)在连接器->常规->附件库目录中,加入orasql10.lib库所在目录. (2)在连接器-& ...
- Android 用户界面---定制组件(Custom Components)
基于布局类View和ViewGroup的基本功能,Android为创建自己的UI界面提供了先进和强大的定制化模式.首先,平台包含了各种预置的View和ViewGroup子类---Widget和layo ...
- 【机器学习基石笔记】七、vc Dimension
vc demension定义: breakPoint - 1 N > vc dimension, 任意的N个,就不能任意划分 N <= vc dimension,存在N个,可以任意划分 只 ...
- 解决AndroidStudio导入项目在 Building gradle project info 一直卡住
Android Studio导入项目的时候,一直卡在Building gradle project info这一步,主要原因还是因为被墙的结果.gradle官网虽然可以访问,但是速度连蜗牛都赶不上.. ...