JDK注解&注解案例

什么是注解?

  • 注解和接口,类属于同一个级别
  • 注解可以在变量、方法、类上加载
  • 注解可以有属性也可以没有属性
  • 注解是有作用范围(源码、编译期间,运行期间)
      • 源码期间:例如String类上@Author  @since  , 使用javac命令将当前源码生成帮助文件,可以识别String类上的注解
      • 编译期间:@Override 、@SuppressWarnings 、 @Deprecated,告诉编译器部分信息
      • 运行期间:@Test    Junit会运行包含@Test注解的方法

@Test(timeout=1000)  //单元测试,超过1ms则报异常

@Override  //重写父类的方法

@SuppressWarnings({ "rawtypes", "unused" }) //抑制编译器警告,如果有变量未使用,未遵循泛型格式错误不报警告

@Deprecated  //声明一下方法过时,不建议使用

@Retention(RetentionPolicy.RUNTIME)  //定义注解的时候,需要通过元注解说明当前自定义注解的作用,此注解在运行期间有效

@Target(ElementType.METHOD)  //定义注解的时候,需要通过@Target说明目标对象

注解的作用:

  • 编译检查
  • 配置
  • 生成帮助文档

什么时候用注解来做配置?

   如果配置信息不会发生的修改,例如servlet路径,建议使用注解的形式

   如果配置信息需要发生频繁的修改,例如数据库的用户名和密码信息,

      建议采用传统方法 (.txt , .properties , .xml)

 

自定义注解

格式:

  • public @interface 注解名称{

    //在注解中定义一个属性
    public 属性类型 属性名称() default 默认值;

  • public long timeout() default -1;

    }

支持的类型:

注解支持的类型有:基本数据类型(4类8种),String,Class,Annotation,Enumeration,以及以上类型的一维数组类型

注解作用:配置

配置:开发的时候部分信息不希望写死在程序中,例如数据库的用户名和密码,可以将其存放在.txtr,properties,xml文件中

    注解在后期的作用主要做配置

框架开发中,一般提供两种方式:xml和注解

案例:模拟Junit

1 自定义注解@MyTest

  通过元注解声明作用域和目标对象,否则运行期间无法通过反射获取到注解信息

2 定义UserDao,里面有四个方法,加上注解

3 编写测试类进行测试

将UserDao.class文件通过反射加载到内存

获取到字节码文件上的所有方法

判断方法上是否有注解,如果有,则执行该方法。

MyTest

package com.test02;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


//定义注解的时候,需要通过元注解说明当前自定义注解的作用
//注解在运行期间有效
@Retention(RetentionPolicy.RUNTIME)
//定义注解的时候,需要通过@Target说明目标对象
@Target(ElementType.METHOD)
public @interface MyTest {
   //在MyTest注解中定义成员属性,属性为-1
   public long timeout() default -1;
}

UserDao

package com.test02;


public class UserDao {
    static{
        System.out.println("加载UserDao静态代码块");
    }
    
    @MyTest
    public void addUser(){
        System.out.println("增加用户");
    }
    @MyTest
    public void delUser(){
        System.out.println("删除用户");
    }
    @MyTest
    public void uptUser(){
        System.out.println("更新用户");        
    }
    @MyTest
    public void getUser(){
        System.out.println("得到用户");
    }
}

测试类

package com.test02;

import java.lang.reflect.Method;

public class MyJunit {
    public static void main(String[] args) throws Exception {
        // 加载UserDao.class字节码文件中的方法,判断哪些方法上有自定义的注解@MyTest并执行
        // 1 将UserDao.class字节码文件加载到内存,class对象(字节码文件在内存中的对象)
        Class clazz = Class.forName("com.test02.UserDao");
        // 2 获取字节码对象上所有的方法,数组中的每一个元素都代表method对象(相当于字节码中的每一个方法)
        Method[] methods = clazz.getMethods();
        // 遍历每个方法
        for (Method method : methods) {
            // System.out.println(method.getName());
            // 判断方法上是否有@MyTest注解
            // System.out.println(method.isAnnotationPresent(MyTest.class));
            if (method.isAnnotationPresent(MyTest.class)) {
                // 如果有@MyTest注解,执行,否则忽略
                method.invoke(new UserDao());
            }
        }

    }
}
原文地址:https://www.cnblogs.com/ltfxy/p/10259609.html