天天看点

Java Reflection(八):注解

内容索引

<a href="http://ifeve.com/java-reflection-8-annotation/#whatarejavaannotation">什么是注解</a>

<a href="http://ifeve.com/java-reflection-8-annotation/#classannotation">类注解</a>

<a href="http://ifeve.com/java-reflection-8-annotation/#methodannotation">方法注解</a>

<a href="http://ifeve.com/java-reflection-8-annotation/#paramannotation">参数注解</a>

<a href="http://ifeve.com/java-reflection-8-annotation/#fieldannotation">变量注解</a>

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

<a></a>

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

<code>1</code>

<code>@myannotation</code><code>(name=</code><code>"somename"</code><code>,  value = </code><code>"hello world"</code><code>)</code>

<code>2</code>

<code>public</code> <code>class</code> <code>theclass {</code>

<code>3</code>

<code>}</code>

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

<code>@retention</code><code>(retentionpolicy.runtime)</code>

<code>@target</code><code>(elementtype.type)</code>

<code>4</code>

<code>public</code> <code>@interface</code> <code>myannotation {</code>

<code>5</code>

<code>  </code><code>public</code> <code>string name();</code>

<code>6</code>

<code>  </code><code>public</code> <code>string value();</code>

<code>7</code>

在interface前面的@符号表名这是一个注解,一旦你定义了一个注解之后你就可以将其应用到你的代码中,就像之前我们的那个例子那样。

在注解定义中的两个指示@retention(retentionpolicy.runtime)和@target(elementtype.type),说明了这个注解该如何使用。

@retention(retentionpolicy.runtime)表示这个注解可以在运行期通过反射访问。如果你没有在注解定义的时候使用这个指示那么这个注解的信息不会保留到运行期,这样反射就无法获取它的信息。

@target(elementtype.type) 表示这个注解只能用在类型上面(比如类跟接口)。你同样可以把type改为field或者method,或者你可以不用这个指示,这样的话你的注解在类,方法和变量上就都可以使用了。

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

<code>01</code>

<code>class aclass = theclass.</code><code>class</code><code>;</code>

<code>02</code>

<code>annotation[] annotations = aclass.getannotations();</code>

<code>03</code>

<code>04</code>

<code>for</code><code>(annotation annotation : annotations){</code>

<code>05</code>

<code>    </code><code>if</code><code>(annotation </code><code>instanceof</code> <code>myannotation){</code>

<code>06</code>

<code>        </code><code>myannotation myannotation = (myannotation) annotation;</code>

<code>07</code>

<code>        </code><code>system.out.println(</code><code>"name: "</code> <code>+ myannotation.name());</code>

<code>08</code>

<code>        </code><code>system.out.println(</code><code>"value: "</code> <code>+ myannotation.value());</code>

<code>09</code>

<code>    </code><code>}</code>

<code>10</code>

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

<code>annotation annotation = aclass.getannotation(myannotation.</code><code>class</code><code>);</code>

<code>if</code><code>(annotation </code><code>instanceof</code> <code>myannotation){</code>

<code>    </code><code>myannotation myannotation = (myannotation) annotation;</code>

<code>    </code><code>system.out.println(</code><code>"name: "</code> <code>+ myannotation.name());</code>

<code>    </code><code>system.out.println(</code><code>"value: "</code> <code>+ myannotation.value());</code>

<code>8</code>

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

<code>  </code><code>@myannotation</code><code>(name=</code><code>"somename"</code><code>,  value = </code><code>"hello world"</code><code>)</code>

<code>  </code><code>public</code> <code>void</code> <code>dosomething(){}</code>

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

<code>method method = ... </code><code>//获取方法对象</code>

<code>annotation[] annotations = method.getdeclaredannotations();</code>

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

<code>method method = ... </code><code>// 获取方法对象</code>

<code>annotation annotation = method.getannotation(myannotation.</code><code>class</code><code>);</code>

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

<code>  </code><code>public</code> <code>static</code> <code>void</code> <code>dosomethingelse(</code>

<code>        </code><code>@myannotation</code><code>(name=</code><code>"aname"</code><code>, value=</code><code>"avalue"</code><code>) string parameter){</code>

<code>  </code><code>}</code>

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

<code>annotation[][] parameterannotations = method.getparameterannotations();</code>

<code>class[] parametertypes = method.getparametertypes();</code>

<code>int</code> <code>i=</code><code>0</code><code>;</code>

<code>for</code><code>(annotation[] annotations : parameterannotations){</code>

<code>  </code><code>class parametertype = parametertypes[i++];</code>

<code>  </code><code>for</code><code>(annotation annotation : annotations){</code>

<code>11</code>

<code>12</code>

<code>        </code><code>system.out.println(</code><code>"param: "</code> <code>+ parametertype.getname());</code>

<code>13</code>

<code>        </code><code>system.out.println(</code><code>"name : "</code> <code>+ myannotation.name());</code>

<code>14</code>

<code>15</code>

<code>16</code>

<code>17</code>

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

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

<code>  </code><code>public</code> <code>string myfield = </code><code>null</code><code>;</code>

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

<code>field field = ... </code><code>//获取方法对象&lt;/pre&gt;</code>

<code>&lt;pre&gt;annotation[] annotations = field.getdeclaredannotations();</code>

<code> </code><code>if</code><code>(annotation </code><code>instanceof</code> <code>myannotation){</code>

<code> </code><code>myannotation myannotation = (myannotation) annotation;</code>

<code> </code><code>system.out.println(</code><code>"name: "</code> <code>+ myannotation.name());</code>

<code> </code><code>system.out.println(</code><code>"value: "</code> <code>+ myannotation.value());</code>

<code> </code><code>}</code>

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

<code>field field = ...</code><code>//获取方法对象&lt;/pre&gt;</code>

<code>&lt;pre&gt;</code>

<code>annotation annotation = field.getannotation(myannotation.</code><code>class</code><code>);</code>

<code>9</code>