Java Annotation认知(包括框架图、详细介绍、示例说明)
2014-07-15 13:54
351 查看
[b]摘要[/b]
Java Annotation是JDK5.0引入的一种注释机制。
网上很多关于Java Annotation的文章,看得人眼花缭乱。Java Annotation本来很简单的,结果说的人没说清楚;弄的看的人更加迷糊。
我按照自己的思路,对Annotation进行了整理。理解 Annotation 的关键,是理解Annotation的语法和用法,对这些内容,我都进行了详细说明;理解Annotation的语法和用法之后,再看Annotation的框架图,可能有更深刻体会。废话就说这么多,下面开始对Annotation进行说明。若您发现文章中存在错误或不足的地方,希望您能指出!
[b]第1部分 Annotation架构[/b]
先看看Annotation的架构图:
View Code
说明:
上面是eclipse中的截图,比较类中 “getString1() 和 getString2()” 以及 “testDate() 和 testCalendar()” 。
(01) getString1() 被@Deprecated标注,意味着建议不再使用getString1();所以getString1()的定义和调用时,都会一横线。这一横线是eclipse()对@Deprecated方法的处理。
getString2() 没有被@Deprecated标注,它的显示正常。
(02) testDate() 调用了Date的相关方法,而java已经建议不再使用Date操作日期/时间。因此,在调用Date的API时,会产生警告信息,途中的warnings。
testCalendar() 调用了Calendar的API来操作日期/时间,java建议用Calendar取代Date。因此,操作Calendar不回产生warning。
2.2 @Inherited
@Inherited 的定义如下:
说明:
(01) @interface -- 它的用来修饰Inherited,意味着Inherited实现了java.lang.annotation.Annotation接口;即Inherited就是一个注解。
(02) @Documented -- 它的作用是说明该注解能出现在javadoc中。
(03)
@Retention(RetentionPolicy.RUNTIME) --
它的作用是指定Inherited的策略是RetentionPolicy.RUNTIME。这就意味着,编译器会将Inherited的信息保留
在.class文件中,并且能被虚拟机读取。
(04) @Target(ElementType.ANNOTATION_TYPE) -- 它的作用是指定Inherited的类型是ANNOTATION_TYPE。这就意味着,@Inherited只能被用来标注“Annotation类型”。
(05) @Inherited 的含义是,它所标注的Annotation将具有继承性。
假设,我们定义了某个Annotaion,它的名称是MyAnnotation,并且MyAnnotation被标注为@Inherited。现在,某
个类Base使用了MyAnnotation,则Base具有了“具有了注解MyAnnotation”;现在,Sub继承了Base,由于
MyAnnotation是@Inherited的(具有继承性),所以,Sub也“具有了注解MyAnnotation”。
@Inherited的使用示例
源码如下(InheritableSon.java):
View Code
运行结果:
InheritableFather:true
InheritableSon:false
对比上面的两个结果,我们发现:当注解Inheritable被@Inherited标注时,它具有继承性。否则,没有继承性。
2.3 @SuppressWarnings
@SuppressWarnings 的定义如下:
View Code
说明:
(01) 左边的图中,没有使用 @SuppressWarnings(value={"deprecation"}) , 而Date属于java不再建议使用的类。因此,调用Date的API时,会产生警告。
而右边的途中,使用了 @SuppressWarnings(value={"deprecation"})。因此,编译器对“调用Date的API产生的警告”保持沉默。
补充:SuppressWarnings 常用的关键字的表格
View Code
上面是该程序在eclipse中的截图。从中,我们可以发现“getString()”函数会报错。这是因为“getString() 被@Override所标注,但在OverrideTest的任何父类中都没有定义getString1()函数”。
“将getString() 上面的@Override注释掉”,即可解决该错误。
[b]2 在反射中使用Annotation[/b]
在反射的Class, Method, Field等函数中,有许多于Annotation相关的接口。
这也意味着,我们可以在反射中解析并使用Annotation。
源码如下(AnnotationTest.java):
运行结果:
somebody: lily, 18
girl, boy,
@com.skywang.annotation.MyAnnotation(value=[girl, boy])
empty
unknown,
@com.skywang.annotation.MyAnnotation(value=[unknown])
@java.lang.Deprecated()
[b]3 根据Annotation生成帮助文档[/b]
通过给Annotation注解加上@Documented标签,能使该Annotation标签出现在javadoc中。
[b]4 能够帮忙查看查看代码[/b]
通过@Override, @Deprecated等,我们能很方便的了解程序的大致结构。
另外,我们也可以通过自定义Annotation来实现一些功能。
Java Annotation是JDK5.0引入的一种注释机制。
网上很多关于Java Annotation的文章,看得人眼花缭乱。Java Annotation本来很简单的,结果说的人没说清楚;弄的看的人更加迷糊。
我按照自己的思路,对Annotation进行了整理。理解 Annotation 的关键,是理解Annotation的语法和用法,对这些内容,我都进行了详细说明;理解Annotation的语法和用法之后,再看Annotation的框架图,可能有更深刻体会。废话就说这么多,下面开始对Annotation进行说明。若您发现文章中存在错误或不足的地方,希望您能指出!
[b]第1部分 Annotation架构[/b]
先看看Annotation的架构图:
View Code
说明:
上面是eclipse中的截图,比较类中 “getString1() 和 getString2()” 以及 “testDate() 和 testCalendar()” 。
(01) getString1() 被@Deprecated标注,意味着建议不再使用getString1();所以getString1()的定义和调用时,都会一横线。这一横线是eclipse()对@Deprecated方法的处理。
getString2() 没有被@Deprecated标注,它的显示正常。
(02) testDate() 调用了Date的相关方法,而java已经建议不再使用Date操作日期/时间。因此,在调用Date的API时,会产生警告信息,途中的warnings。
testCalendar() 调用了Calendar的API来操作日期/时间,java建议用Calendar取代Date。因此,操作Calendar不回产生warning。
2.2 @Inherited
@Inherited 的定义如下:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Inherited { }
说明:
(01) @interface -- 它的用来修饰Inherited,意味着Inherited实现了java.lang.annotation.Annotation接口;即Inherited就是一个注解。
(02) @Documented -- 它的作用是说明该注解能出现在javadoc中。
(03)
@Retention(RetentionPolicy.RUNTIME) --
它的作用是指定Inherited的策略是RetentionPolicy.RUNTIME。这就意味着,编译器会将Inherited的信息保留
在.class文件中,并且能被虚拟机读取。
(04) @Target(ElementType.ANNOTATION_TYPE) -- 它的作用是指定Inherited的类型是ANNOTATION_TYPE。这就意味着,@Inherited只能被用来标注“Annotation类型”。
(05) @Inherited 的含义是,它所标注的Annotation将具有继承性。
假设,我们定义了某个Annotaion,它的名称是MyAnnotation,并且MyAnnotation被标注为@Inherited。现在,某
个类Base使用了MyAnnotation,则Base具有了“具有了注解MyAnnotation”;现在,Sub继承了Base,由于
MyAnnotation是@Inherited的(具有继承性),所以,Sub也“具有了注解MyAnnotation”。
@Inherited的使用示例
源码如下(InheritableSon.java):
View Code
运行结果:
InheritableFather:true
InheritableSon:false
对比上面的两个结果,我们发现:当注解Inheritable被@Inherited标注时,它具有继承性。否则,没有继承性。
2.3 @SuppressWarnings
@SuppressWarnings 的定义如下:
View Code
说明:
(01) 左边的图中,没有使用 @SuppressWarnings(value={"deprecation"}) , 而Date属于java不再建议使用的类。因此,调用Date的API时,会产生警告。
而右边的途中,使用了 @SuppressWarnings(value={"deprecation"})。因此,编译器对“调用Date的API产生的警告”保持沉默。
补充:SuppressWarnings 常用的关键字的表格
View Code
上面是该程序在eclipse中的截图。从中,我们可以发现“getString()”函数会报错。这是因为“getString() 被@Override所标注,但在OverrideTest的任何父类中都没有定义getString1()函数”。
“将getString() 上面的@Override注释掉”,即可解决该错误。
[b]2 在反射中使用Annotation[/b]
在反射的Class, Method, Field等函数中,有许多于Annotation相关的接口。
这也意味着,我们可以在反射中解析并使用Annotation。
源码如下(AnnotationTest.java):
package com.skywang.annotation; import java.lang.annotation.Annotation; import java.lang.annotation.Target; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Inherited; import java.lang.reflect.Method; /** * Annotation在反射函数中的使用示例 * * @author skywang * @email kuiwu-wang@163.com */ @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation { String[] value() default "unknown"; } /** * Person类。它会使用MyAnnotation注解。 */ class Person { /** * empty()方法同时被 "@Deprecated" 和 “@MyAnnotation(value={"a","b"})”所标注 * (01) @Deprecated,意味着empty()方法,不再被建议使用 * (02) @MyAnnotation, 意味着empty() 方法对应的MyAnnotation的value值是默认值"unknown" */ @MyAnnotation @Deprecated public void empty(){ System.out.println("\nempty"); } /** * sombody() 被 @MyAnnotation(value={"girl","boy"}) 所标注, * @MyAnnotation(value={"girl","boy"}), 意味着MyAnnotation的value值是{"girl","boy"} */ @MyAnnotation(value={"girl","boy"}) public void somebody(String name, int age){ System.out.println("\nsomebody: "+name+", "+age); } } public class AnnotationTest { public static void main(String[] args) throws Exception { // 新建Person Person person = new Person(); // 获取Person的Class实例 Class<Person> c = Person.class; // 获取 somebody() 方法的Method实例 Method mSomebody = c.getMethod("somebody", new Class[]{String.class, int.class}); // 执行该方法 mSomebody.invoke(person, new Object[]{"lily", 18}); iteratorAnnotations(mSomebody); // 获取 somebody() 方法的Method实例 Method mEmpty = c.getMethod("empty", new Class[]{}); // 执行该方法 mEmpty.invoke(person, new Object[]{}); iteratorAnnotations(mEmpty); } public static void iteratorAnnotations(Method method) { // 判断 somebody() 方法是否包含MyAnnotation注解 if(method.isAnnotationPresent(MyAnnotation.class)){ // 获取该方法的MyAnnotation注解实例 MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class); // 获取 myAnnotation的值,并打印出来 String[] values = myAnnotation.value(); for (String str:values) System.out.printf(str+", "); System.out.println(); } // 获取方法上的所有注解,并打印出来 Annotation[] annotations = method.getAnnotations(); for(Annotation annotation : annotations){ System.out.println(annotation); } } }
运行结果:
somebody: lily, 18
girl, boy,
@com.skywang.annotation.MyAnnotation(value=[girl, boy])
empty
unknown,
@com.skywang.annotation.MyAnnotation(value=[unknown])
@java.lang.Deprecated()
[b]3 根据Annotation生成帮助文档[/b]
通过给Annotation注解加上@Documented标签,能使该Annotation标签出现在javadoc中。
[b]4 能够帮忙查看查看代码[/b]
通过@Override, @Deprecated等,我们能很方便的了解程序的大致结构。
另外,我们也可以通过自定义Annotation来实现一些功能。
相关文章推荐
- Java Annotation认知(包括框架图、详细介绍、示例说明)
- Java Annotation认知(包括框架图、详细介绍、示例说明)
- Java Annotation认知(包括框架图、详细介绍、示例说明) (转)
- Java Annotation认知(包括框架图、详细介绍、示例说明)
- Java Annotation认知(包括框架图、详细介绍、示例说明)
- Java Annotation认知(包括框架图、详细介绍、示例说明)
- Java Annotation认知(包括框架图、详细介绍、示例说明)
- Java Annotation认知(包括框架图、详细介绍、示例说明)
- Java Annotation认知(包括框架图、详细介绍、示例说明)
- Java Annotation认知(包括框架图、详细介绍、示例说明)
- Java 集合框架--ArrayList详细介绍和使用示例
- Java自带的线程池ThreadPoolExecutor详细介绍说明和实例应用
- Java 集合系列11之 Hashtable详细介绍(源码解析)和使用示例
- Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例
- Java 集合系列 04 LinkedList详细介绍(源码解析)和使用示例
- JAVA HashMap详细介绍和示例
- Java 集合系列16之 HashSet详细介绍(源码解析)和使用示例
- Java 集合系列06之 Vector详细介绍(源码解析)和使用示例
- Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例
- Java 集合系列13之 WeakHashMap详细介绍(源码解析)和使用示例