我们用过 JDK给我们提供的 @Override @Deprecated @SuppressWarning 注解 ,这些注解是JDK给我们提供的 ,我们只是在用别人写好的东西 ,那么我们是否可以自己写注解呢?当然是可以的 。
我们写的注解包括三个环节
1、 注解的声明 ,也就是注解类的定义 形式如下 @interface 来进行注解的声明
package annotate;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD) //这个标识注解应该标在那里 ElementType的几个枚举值就代表了 注解应该写在的位置
@Retention(RetentionPolicy.RUNTIME) //指定了注解保留的周期
public @interface CheckString {
}
@Retention(RetentionPolicy.RUNTIME)
指定了注解保留的周期 注解的生命周期有是三个 RetentionPolicy 枚举的三个值代表了三个声明周期 默认是CLASS
枚举常量摘要 | |
---|---|
CLASS 编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。 |
|
RUNTIME 编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。 |
|
SOURCE 编译器要丢弃的注释。 |
@Target(ElementType.TYPE)
这个标识注解应该标在那里 ElementType的几个枚举值就代表了 注解应该写在的位置
CONSTRUCTOR 构造方法声明 |
FIELD 字段声明(包括枚举常量) |
LOCAL_VARIABLE 局部变量声明 |
METHOD 方法声明 |
PACKAGE 包声明 |
PARAMETER 参数声明 |
TYPE 类、接口(包括注释类型)或枚举声明 |
Annotation类型里面的参数该怎么设定:
第一,只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型;
第二,参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String;
package annotate;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD) //这个标识注解应该标在那里 ElementType的几个枚举值就代表了 注解应该写在的位置
@Retention(RetentionPolicy.RUNTIME) //指定了注解保留的周期
public @interface CheckString {
/**
* 检验的正则表达式
*/
String regex() default ".*";
/**
* 字段是否需要填写
*/
Exists exists() default Exists.Skipped;
/**
* 字段最小长度
* @return
*/
int minlen() default 0;
/**
* 字段最大长度
* @return
*/
int maxlen() default Short.MAX_VALUE;
}
枚举类:
package annotate;
public enum Exists {
/**
* 跳过检验
*/
Skipped,
/**
* 禁止填写
*/
Prohibit,
/**
* 非空字段
*/
Required,
/**
* 可选字段
*/
Optional
}
注解使用类:
package model;
import annotate.CheckString;
import annotate.Exists;
public class Persion {
@CheckString(exists=Exists.Required)
public String test;
@CheckString(exists=Exists.Required)
private String name;
@CheckString(exists=Exists.Required)
private String password;
private String sex;
private int age;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Persion [name=" + name + ", password=" + password + ", sex=" + sex + ", age=" + age + ", test=" + test + "]";
}
public Persion(String name, String password) {
super();
this.name = name;
this.password = password;
}
}
Class类有一个 方法
|
getAnnotation(Class annotationClass) |
这个方法接受一个注解的字节码参数 ,然后返回这个类所标识的注解对象 ,因为我们标识了一个注解就相当于产生了一个注解对象 。
boolean |
isAnnotationPresent(Class extendsAnnotation> annotationClass) |
这个方法判断一个类是否被注解所标识
下面是代码示例
public class CheckParamUtil {
public static void checkParam(Object o) throws Exception{
out:{
final Class> objClass=o.getClass();
Field[] farray=objClass.getDeclaredFields();//获取所有字段 包括private 不包括父类字段
Class chkString=CheckString.class;//CheckString的class
for(int i=0;i
public class TestCheckParam {
public static void main(String[] args) {
Persion p=new Persion("zhangsan","111111");
try {
CheckParamUtil.checkParam(p);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}