Annotation对很多Javaer来说是一个熟悉的名词,我也是,但是今天涉及到此方面的东西,才发现自己对这个新特性知之甚少,从网上看了下资料,自己做了个例子,才逐渐明白,例子贴出来方便其他入门者参考。高手就不用看了,只适用于刚接触Annotation者,呵呵,因为我也刚接触。
测试一
1.自定义一个Annotation
@Retention(RetentionPolicy.RUNTIME)这个meta-annotation表示了此类型的 annotation将被虚拟机保留使其能够在运行时通过反射被读取。而@Target(ElementType. FIELD)表示此类型的 annotation只能用于修饰属性。
2.使用Annotation
3.测试
输出:
注意:如果在定义Annotation时没有加@Retention(RetentionPolicy.RUNTIME),则程序结果为:
测试二:
1.定义Annotation
可以看到,我加入了一个方法。注意Annotation中的方法:
Annotation类型的方法定义是独特的、受限制的,方法必须声明为无参数、无异常抛出的。这些方法定义了annotation的成员:方法名成为了成员名,而方法返回值成为了成员的类型。而方法返回值类型必须为primitive类型、Class类型、枚举类型、annotation类型或者由前面类型之一作为元素的一维数组。方法的后面可以使用default和一个默认数值来声明成员的默认值,null不能作为成员默认值,这与我们在非annotation类型中定义方法有很大不同。
2.使用
3.测试
运行输出:
也不多说了,大家自己多练练,还有方法声明上的Annotion,特别注意class、Filed、Method的所有方法,这是最java基础和核心的东西,应该熟练掌握。
====================================================
一下是Meta-Annotation类型说明:
Annotation 类型可以被它们自己所标注。Java5.0定义了4个标准的meta-annotation类型,分别是:Target、Retention、Documented、Inherited,它们被用来提供对其它annotation类型作说明。 这些类型和它们所支持的类在java.lang.annotation包中可以找到。
@Target的用法:指示注释类型所适用的程序元素的种类。如果注释类型声明中不存在 Target 元注释,则声明的类型可以用在任一程序元素上。如果存在这样的元注释,则编译器强制实施指定的使用限制。
ElementType.ANNOTATION_TYPE 应用于注释类型声明
ElementType.CONSTRUCTOR 构造方法声明
ElementType.FIELD 应用于字段声明(包括枚举常量)
ElementType.LOCAL_VARIABLE 应用于局部变量声明
ElementType.METHOD 应用于方法声明
ElementType.PACKAGE 应用于包声明
ElementType.PARAMETER 应用于参数声明
ElementType.TYPE 应用于类、接口(包括注释类型)或枚举声明
----------------------------------------------
@Retention的用法:指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS。
RetentionPolicy.CLASS 编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释
RetentionPolicy.RUNTIME 编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取
RetentionPolicy.SOURCE 编译器要丢弃的注释
-----------------------------------------------
@Documented的用法:指示某一类型的注释将通过 javadoc 和类似的默认工具进行文档化。应使用此类型来注释这些类型的声明:其注释会影响由其客户端注释的元素的使用。如果类型声明是用 Documented 来注释的,则其注释将成为注释元素的公共 API 的一部分。Documented是一个没有成员的注释。
------------------------------------------------
@Inherited的用法:指示注释类型自动被子类继承。 Inherited也是一个没有成员的注释。
注意,如果使用@Inherited注释类以外的任何事物都是无效的。还要注意,此元注释仅对从超类继承注释有效;对已实现接口的注释无效。
测试一
1.自定义一个Annotation
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface IdAnnation {
- }
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface IdAnnation {
}
@Retention(RetentionPolicy.RUNTIME)这个meta-annotation表示了此类型的 annotation将被虚拟机保留使其能够在运行时通过反射被读取。而@Target(ElementType. FIELD)表示此类型的 annotation只能用于修饰属性。
2.使用Annotation
- public class UserPojo {
- @IdAnnation
- String id;
- String name;
- }
public class UserPojo {
@IdAnnation
String id;
String name;
}
3.测试
- import java.lang.reflect.Field;
- public class Test {
- public static void main(String[] args) throws Exception{
- for(Field f:UserPojo.class.getDeclaredFields()){
- System.out.println(f.getName()+" "+f.isAnnotationPresent(IdAnnation.class) );
- }
- }
- }
import java.lang.reflect.Field;
public class Test {
public static void main(String[] args) throws Exception{
for(Field f:UserPojo.class.getDeclaredFields()){
System.out.println(f.getName()+" "+f.isAnnotationPresent(IdAnnation.class) );
}
}
}
输出:
- id true
- name false
id true
name false
注意:如果在定义Annotation时没有加@Retention(RetentionPolicy.RUNTIME),则程序结果为:
- id false
- name false
id false
name false
测试二:
1.定义Annotation
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface IdAnnation {
- String type();
- }
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface IdAnnation {
String type();
}
可以看到,我加入了一个方法。注意Annotation中的方法:
Annotation类型的方法定义是独特的、受限制的,方法必须声明为无参数、无异常抛出的。这些方法定义了annotation的成员:方法名成为了成员名,而方法返回值成为了成员的类型。而方法返回值类型必须为primitive类型、Class类型、枚举类型、annotation类型或者由前面类型之一作为元素的一维数组。方法的后面可以使用default和一个默认数值来声明成员的默认值,null不能作为成员默认值,这与我们在非annotation类型中定义方法有很大不同。
2.使用
- public class UserPojo {
- @IdAnnation(type="ttttt")
- String id;
- String name;
- }
public class UserPojo {
@IdAnnation(type="ttttt")
String id;
String name;
}
3.测试
- import java.lang.reflect.Field;
- public class Test {
- public static void main(String[] args) throws Exception{
- for(Field f:UserPojo.class.getDeclaredFields()){
- System.out.println(f.getName()+" "+f.isAnnotationPresent(IdAnnation.class) );
- if(f.isAnnotationPresent(IdAnnation.class)){
- System.out.println(((IdAnnation)f.getAnnotation(IdAnnation.class)).type());
- }
- }
- }
- }
import java.lang.reflect.Field;
public class Test {
public static void main(String[] args) throws Exception{
for(Field f:UserPojo.class.getDeclaredFields()){
System.out.println(f.getName()+" "+f.isAnnotationPresent(IdAnnation.class) );
if(f.isAnnotationPresent(IdAnnation.class)){
System.out.println(((IdAnnation)f.getAnnotation(IdAnnation.class)).type());
}
}
}
}
运行输出:
- id true
- ttttt
- name false
id true
ttttt
name false
也不多说了,大家自己多练练,还有方法声明上的Annotion,特别注意class、Filed、Method的所有方法,这是最java基础和核心的东西,应该熟练掌握。
====================================================
一下是Meta-Annotation类型说明:
Annotation 类型可以被它们自己所标注。Java5.0定义了4个标准的meta-annotation类型,分别是:Target、Retention、Documented、Inherited,它们被用来提供对其它annotation类型作说明。 这些类型和它们所支持的类在java.lang.annotation包中可以找到。
@Target的用法:指示注释类型所适用的程序元素的种类。如果注释类型声明中不存在 Target 元注释,则声明的类型可以用在任一程序元素上。如果存在这样的元注释,则编译器强制实施指定的使用限制。
ElementType.ANNOTATION_TYPE 应用于注释类型声明
ElementType.CONSTRUCTOR 构造方法声明
ElementType.FIELD 应用于字段声明(包括枚举常量)
ElementType.LOCAL_VARIABLE 应用于局部变量声明
ElementType.METHOD 应用于方法声明
ElementType.PACKAGE 应用于包声明
ElementType.PARAMETER 应用于参数声明
ElementType.TYPE 应用于类、接口(包括注释类型)或枚举声明
----------------------------------------------
@Retention的用法:指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS。
RetentionPolicy.CLASS 编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释
RetentionPolicy.RUNTIME 编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取
RetentionPolicy.SOURCE 编译器要丢弃的注释
-----------------------------------------------
@Documented的用法:指示某一类型的注释将通过 javadoc 和类似的默认工具进行文档化。应使用此类型来注释这些类型的声明:其注释会影响由其客户端注释的元素的使用。如果类型声明是用 Documented 来注释的,则其注释将成为注释元素的公共 API 的一部分。Documented是一个没有成员的注释。
------------------------------------------------
@Inherited的用法:指示注释类型自动被子类继承。 Inherited也是一个没有成员的注释。
注意,如果使用@Inherited注释类以外的任何事物都是无效的。还要注意,此元注释仅对从超类继承注释有效;对已实现接口的注释无效。