什么是注解
注解和接口,类一样,都属于数据类型
注解作用:
1.编译
2.配置
3.生成帮助文档
注解可以在变量,方法,类之上加载
注解可以有属性也可以没有属性 @Override @Test(timeout=1000)
注解有作用范围(源码,编译期间)
源码期间有效:String类之上@Author,@Since,@See,
作用:使用命令javadoc命令将当前的源码生成帮助文件,可以识别String类上的相关注解
编译期有效:@Override @Deprecated @Suppresswarning
告诉便编译器部分信息
运行期间有效:@Test
作用:当我们当前代码上以Junit方式运行时,Junit会运行方法上包含@Test注解的方法
自定义注解
格式:
public @interface 注解名称{
public 属性类型 属性名称1();
public 属性类型 属性名称2() default -1;
}
自定义注解属性支持的类型:
基本数据类型(4类8种),String,Class,Annotation(注解类型),枚举类型,以及以上类型的一维数组类型
注解作用:配置作用
配置:开发的时候部分信息不希望写死在程序中,例如数据库的用户名和密码,可以将用户名和密码存放在.txt,.properties,.xml文件中,利用程序来读取文件中的内容
什么时候用注解来做配置
如果配置信息不发生修改,例如servlet路径,建议使用注解的形式
如果配置信息需要发生频繁修改,例如数据库的用户名和密码信息
建议采用传统方法(.txt,.properties,.xml)
模拟Junit
1.自定义注解@MyTest
通过原注解@Runtention@Target声明当前注解的作用域以及目标对象,如果没有声明,在运行期间是无法获取到注解的信息
代码示例:
package com.zky.Annotation01;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//自定义注解,相当于Junit@Test
//定义注解的时候,需要通过原注解Retention说明当前自定义注解的作用域(Class,Source,Runtime)
@Retention(RetentionPolicy.RUNTIME)
//定义注解的时候,需要通过原注解Target说明当前的自定义注解的目标对象
@Target(ElementType.METHOD)
public @interface MyTest {
public long timeout() default -1;
}
2.定义UserDao
创建4个方法addUser delUser uptUser getUser,在前三个方法上加载注解
代码示例:
package com.zky.Annotation01;
public class UserDao {
static{
System.out.println("加载静态字节码段的消息");
}
@MyTest
public void addUser(){
System.out.println("增加用户");
}
@MyTest
public void delUser(){
System.out.println("删除用户");
}
@MyTest
public void uptUser(){
System.out.println("更新用户");
}
public void getUser(){
System.out.println("获取用户 ");
}
}
3.定义类MyJunit ,模拟Junit
将UserDao.class文件加载到内存
获取到字节码文件上所用的方法
遍历方法,判断每个方法上是否加载了@MyTest注解
通过反射读取字节码上的注解信息
md.getName()+"--"+md.isAnnotationPresent(MyTest.class)
如果当前方法上设置@MyTest,执行当前的方法
代码示例:
package com.zky.Annotation01;
import java.lang.reflect.Method;
public class MyJunit {
public static void main(String[] args) throws Exception {
//加载UserDao.class字节码中文件的方法,判断哪些方法上有自定义的注解 有就执行 没有 不执行
//1.将UserDao.class字节码文件加载到内存中,class对象(字节码文件中中的内存对象)
Class clazz=Class.forName("com.zky.Annotation01.UserDao");
//2.获取字节码对象上所有的方法,返回Method数组对象,数组中的每一个元素代表Method对象(相当于字节码上的每一个方法)
Method[] mds=clazz.getMethods();
//遍历字节码对象上所有的方法
for(Method md:mds){
//测试方法的名称
System.out.println(md.getName()+"--"+md.isAnnotationPresent(MyTest.class));
//判断当前方法上是否有@MyTest注解信息
if(md.isAnnotationPresent(MyTest.class)){
md.invoke(new UserDao());
}
//如果当前的方法上有@MyTest注解,执行,否则忽略
}
}
}