java annotation(注解)--入门
2010-09-27 15:02
351 查看
学习java的人都知道java中有javadoc这样的java注解,这类注解是用来生成帮助文档用的。
在EJB、Spring、Hibernate、Struts现都可用注解方式配置应用,但是我们对java annotation又有多少了解呢
其实annotation说是元数据(元数据大家应该不陌生--元数据
最本质、最抽象的定义为:
data about data (关于数据的数据--
关于数据的数据或者叫做用来描述数据的数据
)
元数据的作用
如果要对于元数据的作用进行分类,目前还没有明确的定义,不过我们可以根据它所起的作用,大致可分为三类:
l
编写文档:通过代码里标识的元数据生成文档。
l
代码分析:通过代码里标识的元数据对代码进行分析。
l
编译检查:通过代码里标识的元数据让编译器能实现基本的编译检查。
先看看怎么定义一个annotation
就是在定义接口的interface前加@
再看使用方法
添加变量
为变量赋默认值
限定注释使用范围
当我们的自定义注释不断的增多也比较复杂时,就会导致有些开发人员使用错误,主要表现在不该使用该注释的地方使用。为此,Java
提供了一个ElementType
枚举类型来控制每个注释的使用范围,比如说某些注释只能用于普通方法,而不能用于构造函数等。下面是Java
定义的ElementType
枚举:
添加使用范围
这样表明该annotation只能用于方法注解
注释保持性策略
使用策略;
注释保留策略。此枚举类型的常量描述保留注释的不同策略。它们与
元注释类型一起使用,以指定保留多长的注释。
运行时注解的读取
类类型注解
方法类型注解
以下为完整的测试用例:
只能用于方法类型
只能用于类类型
使用
测试类
测试类中用到了得到javabean信息的类Introspector的getBeanInfo(Class clazz)方法得到javabean的信息
在EJB、Spring、Hibernate、Struts现都可用注解方式配置应用,但是我们对java annotation又有多少了解呢
其实annotation说是元数据(元数据大家应该不陌生--元数据
最本质、最抽象的定义为:
data about data (关于数据的数据--
关于数据的数据或者叫做用来描述数据的数据
)
元数据的作用
如果要对于元数据的作用进行分类,目前还没有明确的定义,不过我们可以根据它所起的作用,大致可分为三类:
l
编写文档:通过代码里标识的元数据生成文档。
l
代码分析:通过代码里标识的元数据对代码进行分析。
l
编译检查:通过代码里标识的元数据让编译器能实现基本的编译检查。
先看看怎么定义一个annotation
public @interface TestMethodAnnotation { }
就是在定义接口的interface前加@
再看使用方法
@TestMethodAnnotation public String getName() { return name; }
添加变量
public @interface TestMethodAnnotation { boolean serialize() default true; }
@TestMethodAnnotation(serialize = false) public String getName() { return name; }
为变量赋默认值
public @interface TestMethodAnnotation { boolean serialize() default true; }
限定注释使用范围
当我们的自定义注释不断的增多也比较复杂时,就会导致有些开发人员使用错误,主要表现在不该使用该注释的地方使用。为此,Java
提供了一个ElementType
枚举类型来控制每个注释的使用范围,比如说某些注释只能用于普通方法,而不能用于构造函数等。下面是Java
定义的ElementType
枚举:
public enum ElementType { /** Class, interface (including annotation type), or enum declaration */ TYPE, /** Field declaration (includes enum constants) */ FIELD, /** Method declaration */ METHOD, /** Parameter declaration */ PARAMETER, /** Constructor declaration */ CONSTRUCTOR, /** Local variable declaration */ LOCAL_VARIABLE, /** Annotation type declaration */ ANNOTATION_TYPE, /** Package declaration */ PACKAGE }
添加使用范围
@Target(ElementType.METHOD)
public @interface TestMethodAnnotation { boolean serialize() default true; }
这样表明该annotation只能用于方法注解
注释保持性策略
public enum RetentionPolicy { /** * Annotations are to be discarded by the compiler. */ SOURCE, /** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */ CLASS, /** * Annotations are to be recorded in the class file by the compiler and * retained by the VM at run time, so they may be read reflectively. * * @see java.lang.reflect.AnnotatedElement */ RUNTIME }
CLASS 编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。即要通过java反射得到它是得不到的 |
RUNTIME 编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。 |
SOURCE 编译器要丢弃的注释。即要通过java反射得到它是得不到的 |
注释保留策略。此枚举类型的常量描述保留注释的不同策略。它们与
Retention
元注释类型一起使用,以指定保留多长的注释。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestMethodAnnotation { boolean serialize() default true; }
运行时注解的读取
类类型注解
TestBean testbean = new TestBean(); Class clazz = testbean.getClass(); TestClassAnnotation testClassAnnotation = (TestClassAnnotation) clazz .getAnnotation(TestClassAnnotation.class);
方法类型注解
Method readMethod = prop.getReadMethod(); System.out.print(",readMethod:" + readMethod.getName()); 。。。。。。。。。。。。。。。 TestMethodAnnotation testAnnotation = readMethod .getAnnotation(TestMethodAnnotation.class); if (testAnnotation != null) { System.out.println("serialize:" + testAnnotation.serialize()); }
以下为完整的测试用例:
只能用于方法类型
package com.parkingfo.test.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestMethodAnnotation { boolean serialize() default true; }
只能用于类类型
package com.parkingfo.test.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface TestClassAnnotation { String descript(); }
使用
package com.parkingfo.test; import com.parkingfo.test.annotation.TestClassAnnotation; import com.parkingfo.test.annotation.TestMethodAnnotation; @TestClassAnnotation(descript = "这是测试描述") public class TestBean extends Object { private String name; @TestMethodAnnotation(serialize = false) public String getName() { return name; } /** * @param name */ public void setName(String name) { this.name = name; } @Override public String toString() { return super.toString(); } }
测试类
package com.parkingfo.test; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import com.parkingfo.test.annotation.TestClassAnnotation; import com.parkingfo.test.annotation.TestMethodAnnotation; public class Test { /** * @param args */ public static void main(String[] args) { TestBean testbean = new TestBean(); Class clazz = testbean.getClass(); TestClassAnnotation testClassAnnotation = (TestClassAnnotation) clazz .getAnnotation(TestClassAnnotation.class); System.out.println(testClassAnnotation.descript()); BeanInfo beanInfo; try { beanInfo = Introspector.getBeanInfo(clazz); PropertyDescriptor[] props = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor prop : props) { String propName = prop.getName(); System.out.print("propterty:" + propName); Method readMethod = prop.getReadMethod(); System.out.print(",readMethod:" + readMethod.getName()); Method writeMethod = prop.getWriteMethod(); if (writeMethod != null) { System.out.print(",writeMethod:" + writeMethod.getName()); } System.out.println(); TestMethodAnnotation testAnnotation = readMethod .getAnnotation(TestMethodAnnotation.class); if (testAnnotation != null) { System.out.println("serialize:" + testAnnotation.serialize()); } } } catch (IntrospectionException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
测试类中用到了得到javabean信息的类Introspector的getBeanInfo(Class clazz)方法得到javabean的信息
相关文章推荐
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解java注解(Annotation)以及 自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- java提高篇(49)--注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门
- 深入理解Java:注解(Annotation)自定义注解入门