Java注解总结
来源:互联网 发布:php网店 编辑:程序博客网 时间:2024/05/18 17:59
Java注解,从字面上看是注释、解释,但功能远不只这么简单。注解(Annotation)为我们在代码中添加信息提供一种形式化的方法,使我们可以在稍后某个时刻方便使用这些数据(通过解析注解来使用这些数据),常见作用有:
1.生成文档。这是最常见的,也是java 最早提供的注解。常用的有@see @param @return 等
2.跟踪代码依赖性,实现替代配置文件功能。比较常见的是spring 2.5 开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量。
3.在编译时进行格式检查。如@override 放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出。
包 java.lang.annotation 中包含所有定义自定义注解所需用到的原注解和接口。
如接口 java.lang.annotation.Annotation 是所有注解继承的接口,并且是自动继承,不需要定义时指定,类似于所有类都自动继承Object。
该包同时定义了四个元注解,@Target、@Retention、@Inherited、@Documented。下面将在实例中逐个讲解他们的作用及使用方法。
@Target : 表示该注解用于什么地方,可能的值在枚举类型 ElemenetType中,包括:
ElemenetType.CONSTRUCTOR 构造器声明
ElemenetType.FIELD 域声明(包括 enum 实例)
ElemenetType.LOCAL_VARIABLE 局部变量声明
ElemenetType.METHOD 方法声明
ElemenetType.PACKAGE 包声明
ElemenetType.PARAMETER 参数声明
ElemenetType.TYPE 类,接口(包括注解类型)或enum声明
@Retention:表示在什么级别保存该注解信息,可选的参数值在枚举类型 RetentionPolicy 中,包括:
RetentionPolicy.SOURCE 作用是不将注解保存在class文件中,也就是说象“//”一样在编译时被过滤掉了。
RetentionPolicy.CLASS 作用是只将注解保存在class文件中,而使用反射读取注解时忽略这些注解。
RetentionPolicy.RUNTIME 作用是既将注解保存在class文件中,也可以通过反射读取注解,这也是最常用的值。
@Inherited:继承是java主要的特性之一。在类中的protected和public成员都将会被子类继承,但是父类的注解会不会被子类继承呢?很遗憾的告诉大家,在默认的情况下,父类的注解并不会被子类继承。如果要让这个注解可以被继承,就必须在定义注解时在源码上加上@Inherited注解。
@Documented:在默认的情况下在使用javadoc自动生成文档时,注解将被忽略掉。如果想在文档中也包含注解,必须使用Documented为文档注解。
如何读取注解--类上的注解
// 取得类上的指定的注解Annotation annotation = 类.class.getAnnotation(MyAnnotation.class); // 取得类上的所有注解,包括继承的注解Annotation[] annotations = 类.class.getAnnotations(); // 取当前类上的所有的注解,不包括继承的Annotation[] annotations = 类.class.getDeclaredAnnotations();
如何读取注解--方法上的注解
// 取得方法上的指定的注解Method m = ...Annotation annotation = m.getAnnotation(MyAnnotation.class);// 取得方法上的所有注解,包括继承的注解Annotation[] annotations = m.getAnnotations(); // 取得方法上的所有注解,不包括继承的注解Annotation[] annotations = m.getDeclaredAnnotations();
如何读取注解--构造方法上的注解
// 取得构造方法上的指定的注解Constructor c =...Annotation annotation = c.getAnnotation(MyAnnotation.class);// 取得构造方法上的所有注解,包括继承的注解Annotation[] annotations = c.getAnnotations();// 取得构造方法上的所有注解,不包括继承的注解Annotation[] annotations = c.getDeclaredAnnotations();
如何读取注解--字段上的注解
// 取得属性字段上的指定的注解Field f =...Annotation annotation = f.getAnnotation(MyAnnotation.class);// 取得属性字段上的所有注解,包括继承的注解Annotation[] annotations = f.getAnnotations();// 取得属性字段上的所有注解,不包括继承的注解Annotation[] annotations = f.getDeclaredAnnotations();
我们先建立第一个注解,TestA.java
备注:@interface用来声明一个注解,其中的每一个方法实际上是声明了注解的一个配置参数,方法的名称就是参数的名称,返回值类型就是参数的类型,可以通过default来声明参数的默认。至于注解用在什么地方、在什么级别保存该注解信息是由元注解来控制。
package testannotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * @author quyang.ybb * */@Target({ ElementType.PACKAGE, ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD })@Retention(RetentionPolicy.RUNTIME)public @interface TestA { String name(); int id() default 0; Class<Long> func();}
package testannotation;import java.util.HashMap;import java.util.Map;/** * @author quyang.ybb * */@TestA(name = "type", func = Long.class)public class UserAnnotation { @TestA(name = "param", id = 1, func = Long.class) private Integer age; @TestA(name = "constructor", id = 2, func = Long.class) public UserAnnotation() {this.age = 22; } @TestA(name = "public method", id = 3, func = Long.class) public void a() {Map<String, String> m = new HashMap<String, String>(0); } @TestA(name = "protected method", id = 4, func = Long.class) protected void b() {Map<String, String> m = new HashMap<String, String>(0); } @TestA(name = "private method", id = 5, func = Long.class) private void c() {Map<String, String> m = new HashMap<String, String>(0); }}
package testannotation;import java.lang.annotation.Annotation;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;/** * @author quyang.ybb * */public class ParseAnnotation { public static void parseTypeAnnotation() throws ClassNotFoundException {Class clazz = Class.forName("testannotation.UserAnnotation");Annotation[] annotations = clazz.getAnnotations();for (Annotation annotation : annotations) { TestA testA = (TestA) annotation; System.out.println("type name = " + clazz.getName() + " | id = " + testA.id() + " | name = " + testA.name() + " | func = " + testA.func());} } public static void parseMethodAnnotation() throws Exception {// getMethods()与getDeclaredMethods()try { // just try to validate getMethod(), because a() has not parameters Method mt = UserAnnotation.class.getMethod("a"); System.out.println(mt.getName());} catch (Exception e) { e.printStackTrace();}Method[] methods = UserAnnotation.class.getDeclaredMethods();for (Method method : methods) { boolean hasAnnotation = method.isAnnotationPresent(TestA.class); if (hasAnnotation) {TestA testA = method.getAnnotation(TestA.class);System.out.println("method name = " + method.getName() + " | id = " + testA.id() + " | name = "+ testA.name() + " | func = " + testA.func()); }} } @SuppressWarnings({ "rawtypes", "unchecked" }) public static void parseConstructorAnnotation() throws ClassNotFoundException {Constructor[] construtors = UserAnnotation.class.getConstructors();for (Constructor constructor : construtors) { boolean hasAnnotation = constructor.isAnnotationPresent(TestA.class); if (hasAnnotation) {TestA testA = (TestA) constructor.getAnnotation(TestA.class);System.out.println("constructor name = " + constructor.getName() + " | id = " + testA.id()+ " | name = " + testA.name() + " | func = " + testA.func()); }} } public static void parseFieldAnnotation() throws ClassNotFoundException {// getFields()与getDeclaredFields()Field[] fields = UserAnnotation.class.getDeclaredFields();for (Field field : fields) { boolean hasAnnotation = field.isAnnotationPresent(TestA.class); if (hasAnnotation) {TestA testA = field.getAnnotation(TestA.class);System.out.println("Field name = " + field.getName() + " | id = " + testA.id() + " | name = "+ testA.name() + " | func = " + testA.func()); }} } public static void main(String[] args) throws Exception {parseTypeAnnotation();parseMethodAnnotation();parseConstructorAnnotation();parseFieldAnnotation(); }}
打印结果:
type name = testannotation.UserAnnotation | id = 0 | name = type | func = class java.lang.Long
a
method name = c | id = 5 | name = private method | func = class java.lang.Long
method name = a | id = 3 | name = public method | func = class java.lang.Long
method name = b | id = 4 | name = protected method | func = class java.lang.Long
constructor name = testannotation.UserAnnotation | id = 2 | name = constructor | func = class java.lang.Long
Field name = age | id = 1 | name = param | func = class java.lang.Long
备注:
1. 要用好注解,必须熟悉java 的反射机制,从上面的例子可以看出,注解的解析完全依赖于反射。
2. 不要滥用注解,平常我们编程过程很少接触和使用注解,只有做设计,且不想让设计有过多的配置时。
- java注解-->总结
- java总结(18)注解
- JAVA注解总结
- JAVA注解总结
- Java 注解总结
- Java注解总结
- java注解总结
- 学习java 注解总结.
- Java注解总结
- Java的注解总结
- 【java总结】注解Annotation
- java注解总结
- java注解总结
- java中的注解总结
- java,spring 注解总结
- Java注解知识点总结
- Java 注解总结
- Java 注解总结
- Codeforces #303 (div2)
- 关于二维数组分解为一维数组进行操作
- java多线程(二):线程的实现
- Valid Parentheses
- sqoop简介及安装
- Java注解总结
- Spark入门——2:spark运行模式及原理
- 黑马程序员——单例设计模式
- 2Add Two Numbers
- 01背包入门
- OC应用:射击游戏
- sqlserver08数据库表导入Oracle方法
- Android:使用百度地图SDK定位当前具体位置(类似QQ发表说说的选择地点功能)
- 注解解决Hibernate中should be mapped with insert="false" updatable=false