编写一个注解的基本原则
1.注解不能直接干扰程序代码的运行,也就是说无论增加或删除注解,程序都能正常的运行。
2.一般情况下是通过java的反射机制读取注解信息,从而通过这些信息更改目标程序的一个逻辑
编写一个简单的注解类并详细解释
package com.lilei.test.annotationtest;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/** * 一个简单的注解类 * @author lilei * Created by Administrator on 2017/10/19. */
@Retention(RetentionPolicy.RUNTIME)//a.声明注解的保留期限
@Target(ElementType.METHOD)//b.声明可以使用该注解的目标类型
public @interface NeedTest {//c.定义注解
/** * 1.成员不能有参数,不能抛异常。 * 如boolean value(String name) 或 * boolean value() throws Exception 是错误声明方式 * * 2.可以通过default方法来为这个方法指定默认值,也可以不指定默认值 * * 3.成员类型是受限制的,合法的类型除了八种基本类型和它们的包装类以为还包括 * String,Class,enmus 的注解类型 * * @return */
boolean value() default true;//d. 声明注解成员
}
注意:
1. a和b处的注解是java预定义的注解,会对注解类的行为产生影响
2. 对@Retention(RetentionPolicy.RUNTIME)详细解释
a.当@Retention的括号中是RUNTIME:运行期间可以通过反射机制来读取类中的注解信息
b.当@Retention的括号中是SOURCE:注解信息仅保留目标类的源代码,不保存对应的字节码文件
c.当@Retention的括号中是CLASS:注解信息将进入目标类的字节码文件中,但类加载器加载字节码文件时不会将注解信息加载到jvm中,也就是说运行期不能获取注解信息
3.Target属性的详细解释:
a.当ElementTypte.TYPE代表类,接口,注解类,Enum声明处,成为类型注解
b.当ElementTypte.FIELD:声明在类的成员变量或者常量上,称为域值注解
c.当ElementTypte.METHOD:方法声明处,称为方法注解
d.当ElementTypte.PARAMTER:参数声明处,称为参数注解
f.当ElementTypte.CONSTRUCTOR:构造函数声明处,相应的注解为构造函数注解
g.当ElementTypte.LOCAL_VARIABLE:局部变量声明
h.当ElementTypte.ANNOTATION_TYPE:注解类声明处
使用注解类
package com.lilei.test.annotationtest;
/** * 测试注解类 * * @author lilei * Created by Administrator on 2017/10/19. */
public class ForumService {
//注解类中的成员名字叫value所以括号中的值是value,值和注解类中的数据类型要相同,多个的话用,隔开
//如果是是数组类型的话用{}表示,如:value的类型是一个数组,则@NeedTest(value={...})
@NeedTest(value=true)
public void deleteForum(int forumId){
System.out.println("删除论坛模块:"+forumId);
}
@NeedTest(value = false)
public void deleteTopic(int postId){
System.out.println("删除论坛主题:"+postId);
}
}
在一个普通的类中使用注解
package com.lilei.test.annotationtest;
import java.lang.reflect.Method;
/** * 注解测试使用类 * @author lilei * Created by Administrator on 2017/10/19. */
public class ToolTest {
public static void main(String[] args) {
Class clazz = ForumService.class;
//获取这个类中的所有方法数组;
Method[] methods = clazz.getDeclaredMethods();
System.out.println(methods.length);
for (Method method:methods){
//获取方法上的注解对象
NeedTest needTest = method.getAnnotation(NeedTest.class);
if (needTest != null){
if (needTest.value()){
System.out.println(method.getName()+"()需要测试");
}else{
System.out.println(method.getName()+"()不需要测试");
}
}
}
}
}
注意:个人觉得其实可以和aop中的切面知识结合起来,比如使用记录日志的时候可以通过aop切面监听类上面使用日志注解的方法,然后只要那个方法被调用了就自动的进入了你自己想要处理的方法。