Annotation详解
转自:http://www.doc88.com/p-995532241886.html
首先我们定义一个简单的注解
package com.qjy.annotation; import java.lang.annotation.Documented;
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)
@Documented
public @interface MyAnnotation1 {
String value();
}
java用 @interface Annotation{ } 定义一个注解 @Annotation,一个注解是一个类。注解相当于一种标记,在程序中加上了注解就等于为程序加上了某种标记,以后,JAVAC编译器,开发工具和其他程序可以用反射来了解你的类以及各种元素上有无任何标记,看你有什么标记,就去干相应的事。
@interface
java用@interface MyAnnotation1定义一个注解
@Target
表明注解标注位置。
ElementType枚举有:
1)TYPE 类、接口、enum声明
2)FIELD 域、属性声明
3)METHOD 方法声明
4)PARAMETER 参数声明
5)CONSTRUCTOR 构造方法声明
6)PACKAGE 包声明
7)ANNOTATION_TYPE 注释类型声明
8)LOCAL_VARIABLE 局部变量声明
@Retention
表明该注解类的生命周期。
RetentionPolicy枚举有:
1)SOURCE 在源文件中有效
2)CLASS 在class文件中有效
3)RUNNTIME 在运行时有效
只有指定注解RetentionPolicy.RUNNTIME,我们才可以在注解处理器中通过反射读取
@Documented
表明此注解是否包含在javadoc中
接下来,我们定义一个包含两个值的注解
package com.qjy.annotation; import java.lang.annotation.Documented;
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)
@Documented
public @interface MyAnnotation2 {
String description();
boolean isAnnotation();
}
下面我们看下这两个注解的用法
package com.qjy.annotation; @MyAnnotation1(value="this is annotation1")
public class AnnotationDemo {
@MyAnnotation2(description="this is Annotation2",isAnnotation=true)
public void sayhello(){
System.out.println("hello world");
}
}
当我们互换@MyAnnotation1和@MyAnnotation2时,ide会报错,这就是@Target作用啦!
下面我们通过命令行执行:javadoc -d doc *.java,生成javadoc文档。注解MyAnnotation2使用@Documented时,文档方法如下:
如果不使用@Documented时,文档如下:
这就是@Documented作用啦!
下面我们编写一个完整的自定义注解。
第一步:编写一个用于对象赋值的注解
package com.qjy.annotation; import java.lang.annotation.Documented;
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)
@Documented
public @interface ValueBind {
enum fieldType{STRING,INT};
fieldType type();
String value();
}
第二步:使用注解
package com.qjy.annotation; import com.qjy.annotation.ValueBind.fieldType; public class Student {
private String name = "";
private int age = 0;
private String studentid = ""; public String getName() {
return name;
} @ValueBind(type=fieldType.STRING,value="aa")
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
} @ValueBind(type=fieldType.INT,value="25")
public void setAge(int age) {
this.age = age;
}
public String getStudentid() {
return studentid;
} @ValueBind(type=fieldType.STRING,value="101")
public void setStudentid(String studentid) {
this.studentid = studentid;
} @Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", studentid="
+ studentid + "]";
} }
第三步:编写注解处理器
package com.qjy.annotation; import java.lang.reflect.Method; /**
* 注解处理器
*
* @author admin
*
*/
public class PersistStudent {
public static void main(String[] args) throws Exception{ Object obj = Class.forName("com.qjy.annotation.Student").newInstance();
//获取类所有方法(包含私有)
Method[] methodArray = obj.getClass().getDeclaredMethods(); for(int i = 0; i < methodArray.length; i ++) {
//如果该方法上存在ValueBind注解
if(methodArray[i].isAnnotationPresent(ValueBind.class)) {
ValueBind annotation = methodArray[i].getAnnotation(ValueBind.class);
String type = String.valueOf(annotation.type());
String value = annotation.value();
//根据类型,执行set方法
if(type.equals("INT")) {
methodArray[i].invoke(obj, new Integer[]{new Integer(value)});
} else {
methodArray[i].invoke(obj, new String[]{value});
}
}
} System.out.println(obj.toString()); }
}
运行结果为:
Student [name=aa, age=25, studentid=101]
如果将ValueBind中Retention改为:@Retention(RetentionPolicy.SOURCE)或者@Retention(RetentionPolicy.CLASS),运行结果为:
Student [name=, age=0, studentid=]
我们就无法通过反射获取注解指定的值。
最新文章
- SpringMVC学习记录2
- mysql5.x升级到mysql5.7后导入之前数据库date出错的快速解决方法【mysql低版本数据导入到高版本出错的解决方法】
- MySQL存储过程动态SQL语句的生成
- go sync.Mutex 设计思想与演化过程 (一)
- php array转json、xml
- 神州通,我看行---K2用户交流会华南站
- How to display SSRS report based on customer/Vendor specific language [AX2012]
- COMException 依赖服务或组无法启动(0x8007042C)处理办法
- 在C#中调用Win32函数EnumWindows枚举所有窗口。
- k8s google sample - guestbook
- react基础学习
- 想从事IT行业的你,一定看看这篇文章
- MVVM命令绑定原理
- 织梦DEDE网站后台如何上传附件
- [HNOI2001]软件开发
- 插入mysql失败,因为java数据类型是个实体类,加上.id就好了
- windows10 VM12 安装Mac OS X 10.11
- MyBatis时间比较
- C# 类库调试 启动外部程序无法调试
- websocket项目电子签字使用场景
热门文章
- leetcode-12双周赛-1246-删除回文子数组
- thinkcmf链接多个数据库
- psecurity配置
- ac自动机fail树上按询问建立上跳指针——cf963D
- jQuery选择器 (详解)
- appium自动化获取app的appPackage与appActivity方法总结
- Java-Class-@I:org.springframework.web.bind.annotation.PostMapping
- 【Stanford Machine Learning Open Course】学习笔记目录
- jQuery实用美化input 上传组建
- springMvc请求路径解析