Java Reflection(八):注解

内容索引
什么是注解
类注解
方法注解
参数注解
变量注解

利用Java反射机制可以在运行期获取Java类的注解信息。

什么是注解

注解是Java 5的一个新特性。注解是插入你代码中的一种注释或者说是一种元数据(meta data)。这些注解信息可以在编译期使用预编译工具进行处理(pre-compiler tools),也可以在运行期使用Java反射机制进行处理。下面是一个类注解的例子:

1 @MyAnnotation(name="someName",  value = "Hello World")
2 public class TheClass {
3 }

在TheClass类定义的上面有一个@MyAnnotation的注解。注解的定义与接口的定义相似,下面是MyAnnotation注解的定义:

1 @Retention(RetentionPolicy.RUNTIME)
2 @Target(ElementType.TYPE)
3  
4 public @interface MyAnnotation {
5   public String name();
6   public String value();
7 }

在interface前面的@符号表名这是一个注解,一旦你定义了一个注解之后你就可以将其应用到你的代码中,就像之前我们的那个例子那样。
在注解定义中的两个指示@Retention(RetentionPolicy.RUNTIME)和@Target(ElementType.TYPE),说明了这个注解该如何使用。
@Retention(RetentionPolicy.RUNTIME)表示这个注解可以在运行期通过反射访问。如果你没有在注解定义的时候使用这个指示那么这个注解的信息不会保留到运行期,这样反射就无法获取它的信息。
@Target(ElementType.TYPE) 表示这个注解只能用在类型上面(比如类跟接口)。你同样可以把Type改为Field或者Method,或者你可以不用这个指示,这样的话你的注解在类,方法和变量上就都可以使用了。
关于Java注解更详细的讲解可以访问Java Annotations tutorial

类注解

你可以在运行期访问类,方法或者变量的注解信息,下是一个访问类注解的例子:

01 Class aClass = TheClass.class;
02 Annotation[] annotations = aClass.getAnnotations();
03  
04 for(Annotation annotation : annotations){
05     if(annotation instanceof MyAnnotation){
06         MyAnnotation myAnnotation = (MyAnnotation) annotation;
07         System.out.println("name: " + myAnnotation.name());
08         System.out.println("value: " + myAnnotation.value());
09     }
10 }

你还可以像下面这样指定访问一个类的注解:

1 Class aClass = TheClass.class;
2 Annotation annotation = aClass.getAnnotation(MyAnnotation.class);
3  
4 if(annotation instanceof MyAnnotation){
5     MyAnnotation myAnnotation = (MyAnnotation) annotation;
6     System.out.println("name: " + myAnnotation.name());
7     System.out.println("value: " + myAnnotation.value());
8 }

方法注解

下面是一个方法注解的例子:

1 public class TheClass {
2   @MyAnnotation(name="someName",  value = "Hello World")
3   public void doSomething(){}
4 }

你可以像这样访问方法注解:

01 Method method = ... //获取方法对象
02 Annotation[] annotations = method.getDeclaredAnnotations();
03  
04 for(Annotation annotation : annotations){
05     if(annotation instanceof MyAnnotation){
06         MyAnnotation myAnnotation = (MyAnnotation) annotation;
07         System.out.println("name: " + myAnnotation.name());
08         System.out.println("value: " + myAnnotation.value());
09     }
10 }

你可以像这样访问指定的方法注解:

1 Method method = ... // 获取方法对象
2 Annotation annotation = method.getAnnotation(MyAnnotation.class);
3  
4 if(annotation instanceof MyAnnotation){
5     MyAnnotation myAnnotation = (MyAnnotation) annotation;
6     System.out.println("name: " + myAnnotation.name());
7     System.out.println("value: " + myAnnotation.value());
8 }

参数注解

方法参数也可以添加注解,就像下面这样:

1 public class TheClass {
2   public static void doSomethingElse(
3         @MyAnnotation(name="aName", value="aValue") String parameter){
4   }
5 }

你可以通过Method对象来访问方法参数注解:

01 Method method = ... //获取方法对象
02 Annotation[][] parameterAnnotations = method.getParameterAnnotations();
03 Class[] parameterTypes = method.getParameterTypes();
04  
05 int i=0;
06 for(Annotation[] annotations : parameterAnnotations){
07   Class parameterType = parameterTypes[i++];
08  
09   for(Annotation annotation : annotations){
10     if(annotation instanceof MyAnnotation){
11         MyAnnotation myAnnotation = (MyAnnotation) annotation;
12         System.out.println("param: " + parameterType.getName());
13         System.out.println("name : " + myAnnotation.name());
14         System.out.println("value: " + myAnnotation.value());
15     }
16   }
17 }

需要注意的是Method.getParameterAnnotations()方法返回一个注解类型的二维数组,每一个方法的参数包含一个注解数组。

变量注解

下面是一个变量注解的例子:

1 public class TheClass {
2  
3   @MyAnnotation(name="someName",  value = "Hello World")
4   public String myField = null;
5 }

你可以像这样来访问变量的注解:

01 Field field = ... //获取方法对象</pre>
02 <pre>Annotation[] annotations = field.getDeclaredAnnotations();
03  
04 for(Annotation annotation : annotations){
05  if(annotation instanceof MyAnnotation){
06  MyAnnotation myAnnotation = (MyAnnotation) annotation;
07  System.out.println("name: " + myAnnotation.name());
08  System.out.println("value: " + myAnnotation.value());
09  }
10 }

你可以像这样访问指定的变量注解:

1 Field field = ...//获取方法对象</pre>
2 <pre>
3 Annotation annotation = field.getAnnotation(MyAnnotation.class);
4  
5 if(annotation instanceof MyAnnotation){
6  MyAnnotation myAnnotation = (MyAnnotation) annotation;
7  System.out.println("name: " + myAnnotation.name());
8  System.out.println("value: " + myAnnotation.value());
9 }
时间: 2024-11-03 01:15:09

Java Reflection(八):注解的相关文章

Java Reflection API简介

Java Reflection API提供对JVM中的类,接口和对象的深入洞察.开发者通常使用API来完成以下的任务,这解释了为什么总是使用开发工具,例如debugger和Integrated Development Environments (IDEs): · 决定一个对象的类. · 获得关于一个类的modifiers, fields, methods, constructors, etc的信息. · 获得关于一个接口的常量和方法声明. · 创建一个类的instance,这个类的名字直到运行时

Java Reflection(九):泛型

内容索引运用泛型反射的经验法则泛型方法返回类型泛型方法参数类型泛型变量类型 我常常在一些文章以及论坛中读到说Java泛型信息在编译期被擦除(erased)所以你无法在运行期获得有关泛型的信息.其实这种说法并不完全正确的,在一些情况下是可以在运行期获取到泛型的信息.这些情况其实覆盖了一些我们需要泛型信息的需求.在本节中我们会演示一下这些情况. 运用泛型反射的经验法则 下面是两个典型的使用泛型的场景: 1.声明一个需要被参数化(parameterizable)的类/接口. 2.使用一个参数化类. 当

java 实体类注解配置问题

问题描述 java 实体类注解配置问题 我有一个机构实体类,里面有id,orgnName(机构名),parentId(父级机构的id)三个属性 问要如何配置id和parentId的多对一关系? 表里面的数据如下形式: ID ORGNNAME PARENTID 1 机构 1 0 2 机构 1-1 1(存的是 机构1 的id ) 3 机构 1-2 1(存的是 机构1 的id ) 求高手解答,不,求 '大神' 解答,跪求!! 解决方案 一对多注解标识在表示多的集合字段上,多对一的注解标识在一的属性上,

全面解析Java中的注解与注释_java

注解一.什么是 Annotation? (注解 or 注释)Annotation, 准确的翻译应该是 -- 注解. 和注释的作用完全不一样. Annotation 是JDK5.0及以后版本引入的一个特性. 与类.接口.枚举是在同一个层次,可以成为java 的一个类型. 语法是以@ 开头 简单来说, 注释是程序员对源代码的类,方法,属性等做的一些记忆或提示性描述(比如这个方法是做什么用的),是给人来看的. 注解则是Java 编译器可以理解的部分,是给编译器看的. 举个简单的例子来看一下注解的使用和

Java 中的注解详解及示例代码_java

在Java中,注解(Annotation)引入始于Java5,用来描述Java代码的元信息,通常情况下注解不会直接影响代码的执行,尽管有些注解可以用来做到影响代码执行. 注解可以做什么 Java中的注解通常扮演以下角色 编译器指令 构建时指令 运行时指令 其中 Java内置了三种编译器指令,本文后面部分会重点介绍 Java注解可以应用在构建时,即当你构建你的项目时.构建过程包括生成源码,编译源码,生成xml文件,打包编译的源码和文件到JAR包等.软件的构建通常使用诸如Apache Ant和Mav

把springxml配置改为在java类中注解的方式

问题描述 把springxml配置改为在java类中注解的方式 原因:使用spring-boot框架发布rest服务时出现中文乱码 解决方案 http://zhidao.baidu.com/link?url=3q7jr29bB_zAh8maEUxHuzon_6rXrXqKw_6m7VoaZ3GeH7_lsFSsdlml7BsCvEt7EZzE2QXgzF-_CXCsgtetX_ 解决方案二: 需要在web.xml中对请求的时间进行utf-8操作过滤: encodingFilterorg.spri

Java中八种基本数据类型的默认值_java

通过一段代码来测试一下 8种基本数据类型的默认值 package dierge; public class Ceshi { int a; double b; boolean c; char d; float f; byte e; long h; short j; public static void main(String args[]){ Ceshi a=new Ceshi(); System.out.println("整型的默认值是:"+a.a); System.out.print

利用Java Reflection(反射)原理,在hibernate里面实现对单表、视图的动态组合查询

动态|视图|组合查询     Reflection 是 Java 程序开发语言的特征之一,它允许运行中的程序对自身进行访问,并能直接操作程序的内部属性.     Hibernate是一个面向Java环境的对象/关系数据库映射工具,基本上,每个表或者视图在hibernate里面都可以对应一个类,在此处,我们通过充分的利用这个类,来实现动态组合查询. 首先我们一起来看看这个函数的源代码:     /**     * 组合查询     * @param object 包含查询条件的对象     * @

Java中的注解(Annotation)--注解处理器

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