加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Java自定义注解Annotation的使用

发布时间:2020-12-15 07:27:06 所属栏目:Java 来源:网络整理
导读:从 jdk5 开始, Java 增加了对元数据的支持,也就是 Annotation , Annotation 其实就是对代码的一种特殊标记,这些标记可以在编译,类加载和运行时被读取,并执行相应的处理。当然刚刚说了, Annotation 只是一种标记,所以要是在代码里面不用这些标记也是

jdk5开始,Java增加了对元数据的支持,也就是AnnotationAnnotation其实就是对代码的一种特殊标记,这些标记可以在编译,类加载和运行时被读取,并执行相应的处理。当然刚刚说了,Annotation只是一种标记,所以要是在代码里面不用这些标记也是能完成相应的工作的,只是有时候用注解能简化很多代码,看起来非常的简洁。

常见的注解(Annotation

@Override——限定重写父类方法

@Deprecated——标示已过时

@SuppressWarning——抑制编译器警告

JAVA的元注解

除了上面的注解,还有元注解。元注解是指注解的注解,包括@Retention @Target @Document @Inherited四种。

[email?protected] 这个是决定你Annotation存活的时间的,它包含一个RetationPolicyvalue成员变量,用于指定它所修饰的Annotation保留时间,一般有:

1. Retationpolicy.CLASS:编译器将把注解记录在Class文件中,

不过当java程序执行的时候,JVM将抛弃它。不过当java程序执行的时候,JVM将抛弃它。

2. Retationpolicy.SOURCE : 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得。

4. Retationpolicy.RUNTIME : 在Retationpolicy.CLASS的基础上,JVM执行的时候也不会抛弃它,所以我们一般在程序中可以通过反射来获得这个注解,然后进行处理。

首先要明确生命周期长度 SOURCE < CLASS < RUNTIME ,所以MT4下载教程前者能作用的地方后者一定也能作用。一般如果需要在运行时去动态获取注解信息,那只能用 RUNTIME 注解;如果要在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife),就用 CLASS注解;如果只是做一些检查性的操作,比如 @Override @SuppressWarnings,则可选用 SOURCE 注解。

[email?protected] 这个注解一般用来指定被修饰的注解修饰哪些元素,如下:

ElementType.ANNOTATION_TYPE : //注解

ElementType.CONSTRUCTOR: //构造函数

ElementType.FIELD: //字段、枚举的常量

ElementType.LOCAL_VARIABLE: //局部变量

ElementType.METHOD: //方法

ElementType.PACKAGE: //包 ??

ElementType.PARAMETER://方法参数

ElementType.TYPE: //接口、类、枚举、注解

@Document 这个注解修饰的Annotation类可以被javadoc工具提取成文档

@Inherited 被他修饰的注解具有继承性,说明子类可以继承父类中的该注解

例子

自定义注解MyClassAnnotation

@Retention(RetentionPolicy.RUNTIME) ?

@Target(ElementType.TYPE) ?

public @interface MyClassAnnotation {

String value();

}

自定义注解MyFieldAnnotation

@Retention(RetentionPolicy.RUNTIME) ?

@Target(ElementType.FIELD) ?

public @interface MyFieldAnnotation {

public String name() default "fieldName";

}

自定义注解MyMethodAnnotation

@Retention(RetentionPolicy.RUNTIME) ?

@Target(ElementType.METHOD) ?

public @interface MyMethodAnnotation {

??????String name();

??????int age();

}

在实例中使用TestRuntimeAnnotation 来测试注解情况:

@MyClassAnnotation(value = "test Class")

public class TestRuntimeAnnotation {

????@MyFieldAnnotation

????public String fieldInfo = "FiledInfo"; ?

@MyMethodAnnotation(age = 0,name = "zhangsan")

????public static String getMethodInfo() { ?

????????return TestRuntimeAnnotation.class.getSimpleName(); ?

????} ??

????public static void main(String[]args) {

????????StringBuffer sb = new StringBuffer(); ?

????????Class<?> cls = TestRuntimeAnnotation.class; ?

????????sb.append("Class注解:").append("n"); ?

????????MyClassAnnotation myClassAnnotation = cls.getAnnotation(MyClassAnnotation.class); ?

????????if (myClassAnnotation != null) { ?

????????????sb.append(Modifier.toString(cls.getModifiers())).append(" ") ?

????????????????????.append(cls.getSimpleName()).append("n"); ?

????????????sb.append("注解值: ").append(myClassAnnotation.value()).append("nn"); ?

????????}

????????sb.append("Field注解:").append("n"); ?

????????Field[] fields = cls.getDeclaredFields(); ?

????????for (Field field : fields) { ?

???????? MyFieldAnnotation fieldInfo = field.getAnnotation(MyFieldAnnotation.class); ?

????????????if (fieldInfo != null) { ?

????????????????sb.append(Modifier.toString(field.getModifiers())).append(" ") ?

????????????????????????.append(field.getType().getSimpleName()).append(" ") ?

????????????????????????.append(field.getName()).append("n"); ?

????????????????sb.append("注解值: ").append(fieldInfo.name()).append("nn"); ?

????????????} ?

????????} ?

????? ????????sb.append("Method注解:").append("n"); ?

????????Method[] methods = cls.getDeclaredMethods(); ?

????????for (Method method : methods) { ?

???????? MyMethodAnnotation methodInfo = method.getAnnotation(MyMethodAnnotation.class); ?

????????????if (methodInfo != null) { ?

????????????????sb.append(Modifier.toString(method.getModifiers())).append(" ") ?

????????????????????????.append(method.getReturnType().getSimpleName()).append(" ") ?

????????????????????????.append(method.getName()).append("n"); ?

????????????????sb.append("注解值: ").append("n"); ?

????????????????sb.append("name: ").append(methodInfo.name()).append("n"); ?

????????????????sb.append("age: ").append(methodInfo.age()).append("n"); ?

????????????} ?

????????} ?

????????System.out.print(sb.toString()); ?

????}

}

测试结果如下:

Class注解:

public TestRuntimeAnnotation

注解值: test Class

Field注解:

public String fieldInfo

注解值: fieldName

Method注解:

public static String getMethodInfo

注解值:

name: zhangsan

age: 0

定义注解

该注解可以验证成员属性是否为空,长度,提供了几种常见的正则匹配,也可以使用自定义的正则去判断属性是否合法,同时可以为该成员提供描述信息。

定义注解

该注解可以验证成员属性是否为空,长度,提供了几种常见的正则匹配,也可以使用自定义的正则去判断属性是否合法,同时可以为该成员提供描述信息。

package org.xdemo.validation.annotation;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

import org.xdemo.validation.RegexType;

/**

?* 数据验证

?* @author Goofy

?*/

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.FIELD,ElementType.PARAMETER})

public @interface DV { ?

????//是否可以为空

????boolean nullable() default false;

????//最大长度

????int maxLength() default 0;

????//最小长度

????int minLength() default 0;

????//提供几种常用的正则验证

????RegexType regexType() default RegexType.NONE;

????//自定义正则验证

????String regexExpression() default "";

????//参数或者字段描述,这样能够显示友好的异常信息

????String description() default "";

}

注解的解析

package org.xdemo.validation.annotation.support;

import java.lang.reflect.Field;

import org.xdemo.validation.RegexType;

import org.xdemo.validation.annotation.DV;

import org.xdemo.validation.utils.RegexUtils;

import org.xdemo.validation.utils.StringUtils;

/**

?* 注解解析

?* @author Goofy

?*/

public class ValidateService {

?????

????private static DV dv;

?????

????public ValidateService() {

????????super();

????}

????//解析的入口

????public static void valid(Object object) throws Exception{

????????//获取object的类型

????????Class<? extends Object> clazz=object.getClass();

????????//获取该类型声明的成员

????????Field[] fields=clazz.getDeclaredFields();

????????//遍历属性

????????for(Field field:fields){

????????????//对于private私有化的成员变量,通过setAccessible来修改器访问权限

????????????field.setAccessible(true);

????????????validate(field,object);

????????????//重新设置会私有权限

????????????field.setAccessible(false);

????????}

????} ?

????public static void validate(Field field,Object object) throws Exception{

????????String description;

????????Object value;

????????//获取对象的成员的注解信息

????????dv=field.getAnnotation(DV.class);

????????value=field.get(object);

????????if(dv==null)return;

????????description=dv.description().equals("")?field.getName():dv.description();

????????/*************注解解析工作开始******************/

????????if(!dv.nullable()){

????????????if(value==null||StringUtils.isBlank(value.toString())){

????????????????throw new Exception(description+"不能为空");

????????????}

????????}

????????if(value.toString().length()>dv.maxLength()&&dv.maxLength()!=0){

????????????throw new Exception(description+"长度不能超过"+dv.maxLength());

????????}

?????????

????????if(value.toString().length()<dv.minLength()&&dv.minLength()!=0){

????????????throw new Exception(description+"长度不能小于"+dv.minLength());

????????}

????????if(dv.regexType()!=RegexType.NONE){

????????????switch (dv.regexType()) {

????????????????case NONE:

????????????????????break;

????????????????case SPECIALCHAR:

????????????????????if(RegexUtils.hasSpecialChar(value.toString())){

????????????????????????throw new Exception(description+"不能含有特殊字符");

????????????????????}

????????????????????break;

????????????????case CHINESE:

????????????????????if(RegexUtils.isChinese2(value.toString())){

????????????????????????throw new Exception(description+"不能含有中文字符");

????????????????????}

????????????????????break;

????????????????case EMAIL:

????????????????????if(!RegexUtils.isEmail(value.toString())){

????????????????????????throw new Exception(description+"地址格式不正确");

????????????????????}

????????????????????break;

????????????????case IP:

????????????????????if(!RegexUtils.isIp(value.toString())){

????????????????????????throw new Exception(description+"地址格式不正确");

????????????????????}

????????????????????break;

????????????????case NUMBER:

????????????????????if(!RegexUtils.isNumber(value.toString())){

????????????????????????throw new Exception(description+"不是数字");

????????????????????}

????????????????????break;

????????????????case PHONENUMBER:

????????????????????if(!RegexUtils.isPhoneNumber(value.toString())){

????????????????????????throw new Exception(description+"不是数字");

????????????????????}

????????????????????break;

????????????????default:

????????????????????break;

????????????}

????????}

????????if(!dv.regexExpression().equals("")){

????????????if(value.toString().matches(dv.regexExpression())){

????????????????throw new Exception(description+"格式不正确");

????????????}

????????}

????????/*************注解解析工作结束******************/

????}

}

用到的几个类

package org.xdemo.validation;

/**

?* 常用的数据类型枚举

?* @author Goofy

?*

?*/

public enum RegexType {

?????

????NONE,

????SPECIALCHAR,

????CHINESE,

????EMAIL,

????IP,

????NUMBER,

????PHONENUMBER; ??

}

其中正则验证类和字符串工具类请参考以下链接:

SuperUtilRegexUtils

SuperUtilStringUtils

使用方法

package org.xdemo.validation.test;

import org.xdemo.validation.RegexType;

import org.xdemo.validation.annotation.DV;

public class User {

????@DV(description="用户名",minLength=6,maxLength=32,nullable=false)

????private String userName;

?????

????private String password;

????@DV(description="邮件地址",nullable=false,regexType=RegexType.EMAIL)

????private String email;

public User(){}

????public User(String userName,String password,String email) {

????????super();

????????this.userName = userName;

????????this.password = password;

????????this.email = email;

????}

????public String getUserName() {

????????return userName;

????}

????public void setUserName(String userName) {

????????this.userName = userName;

????}

????public String getPassword() {

????????return password;

????}

????public void setPassword(String password) {

????????this.password = password;

????}

????public String getEmail() {

????????return email;

????}

????public void setEmail(String email) {

????????this.email = email;

????}

}

测试代码

import org.xdemo.validation.annotation.support.ValidateService;

/**

?* @author Goofy

?*/

public class Test {

????public static void main(String[] args){

????????User user=new User("张三","xdemo.org","[email?protected]");

????????try {

????????????ValidateService.valid(user);

????????} catch (Exception e) {

????????????e.printStackTrace();

????????}

????????user=new User("zhangsan","[email?protected]");

????????try {

????????????ValidateService.valid(user);

????????} catch (Exception e) {

????????????e.printStackTrace();

????????}

????????user=new User("zhangsan","");

????????try {

????????????ValidateService.valid(user);

????????} catch (Exception e) {

????????????e.printStackTrace();

????????}

????}

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读