注解

一、注解概述

注解就是程序中的一种特殊标记。这些标记可以在编译、类加载、运行时被读取。程序员可以通过注解在程序中添加一些额外的补充信息。Annotation 注解就是像修饰符一样,可用于修饰类、成员变量、方法等成员,注解的信息存储在 ” name = value ” 对中。

注意:注解不影响程序的执行,无论增加、删除注解,代码都会执行。

二、基本 Annotation

java.lang 包中定义了一些基本的注解:

@Override 注解告诉编译器检查方法覆盖(重写)是否符合规则。

@Deprecate 注解表示已过时,当其他程序使用已过时的类或方法时,编译器会给出警告。

@FunctionalInterface 注解表示是函数式接口。如果接口中只有一个抽象方法可以定义为函数式接口函数式接口是为 Lambda 表达式准备的,即可以使用 Lambda 创建函数式接口实例。

三、元注解

java.lang.annotation 包中定义一组元注解。元注解就是用来修饰注解的注解

@Retention 用于指定被修饰的 Annotation 可以保留多长时间,它包含一个RetentionPolicy 类型的 value 成员变量,可以取三个值:

  • RetentionPolicy.SOURCE    表示注解只能保留在源代码中
  • RetentionPolicy.CLASS     表示注解记录在字节码文件中
  • RetentionPolicy.RUNTIME  表示程序运行时也可以获得注解信息

@Target 指定被修饰的 Annotation 注解可以用于修饰 哪些程序单元。  

  • ElementType.ANNOTATION_TYPE  注释类型声明
  • ElementType.CONSTRUCTOR    构造方法声明
  • ElementType.FIELD          字段声明(包括枚举常量)
  • ElementType.LOCAL_VARIABLE     局部变量声明
  • ElementType.METHOD           方法声明
  • ElementType.PACKAGE         包声明
  • ElementType.PARAMETER          参数声明
  • ElementType.TYPE            类、接口(包括注释类型)或枚举声明 

@Documented 表示被修饰的 Annotation 可以被 javadoc 提取成文档

四、自定义 Annotation

语法:

[修饰符] @interface 注解名 {

  数据类型 属性名() default 默认值;

}

五、案例:模拟框架

package cn.powernode.javase.annotation.spring_ioc;
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Properties;
/*
模拟框架:
1.框架什么读取配置文件
  将注解标注的类创建对象并放入容器中
  应该在框架启动时,第一时间就要读取配置文件,创建实例对象,放入到容器中,供程序员取用对象
2.静态代码块(在类加载时执行,而且只会执行一次,用它进行类中内容的初始化操作)
  static{
      代码片段
  }
*/
public class SpringIOCTest {
    static HashMap<String,Object> map = new HashMap<>(); // 容器,存储类对象
    public static void main(String[] args) {
        // 根据指定名称获取对应的对象
        Object stu = map.get("stu");
        Object tea = map.get("tea");
        Object work = map.get("work");
// 若成功创建实例对象,会调用 toString()方法 System.out.println(stu); //结果: null System.out.println(tea); //结果: Teacher{} System.out.println(work); //结果: Worker{} }
// 静态代码块 static{ try{ // 1.读取配置文件 Properties properties = new Properties(); FileInputStream fis = new FileInputStream("day15\\applicationContext.properties"); properties.load(fis); // 2.获取配置文件中的包路径 String packagePath = properties.getProperty("packagePath"); // cn.powernode.javase.annotation.bean // 3.将包路径转换为磁盘路径 String s = packagePath.replace(".", "\\"); File file = new File("day15\\src", s); // day15\src\cn\powernode\javase\annotation\bean // 4.获取该磁盘文件夹下的文件名称 String[] list = file.list(); ArrayList<String> fileNames = new ArrayList(); // 遍历数组,拿到每一个文件名称 xx.java for (String fileName : list) { // 对于每一个文件名称 xx.java ,不要后缀 String[] split = fileName.split("\\."); // 保存每一个 去除了后缀的文件名称 fileNames.add(split[0]); } // 5.拼接 包路径+文件名称,形成所有类的全路径 ArrayList<String> referencePaths = new ArrayList<String>(); for (String fileName : fileNames) { String referencePath = packagePath + "." + fileName; // 包路径+文件名称 // 使用集合保存所有类的全路径 referencePaths.add(referencePath); } // 6.遍历集合 拿到每一个类的全路径 for (String referencePath : referencePaths) { // 7.通过Class.forName()创建该类的Class类对象,类对象中包含有注解信息 Class<?> c = Class.forName(referencePath); // 8.判断该类对象中,是否有指定的注解,eg:@Create() boolean flag = c.isAnnotationPresent(Create.class); // 9.有,则创建该类的对象放入容器中 if(flag){ // 10.获取构造方法对象 Constructor<?> constructor = c.getDeclaredConstructor(); // 11.创建实例对象 new xxx() Object o = constructor.newInstance(); // 12.获取类上的注解信息 Create annotation = c.getAnnotation(Create.class); // 13.获取注解的属性内容 String key = annotation.value(); // 14.放入容器中 map.put(key,o); // eg: stu : new Student() } } }catch (Exception e){ e.printStackTrace(); } } }

 

posted @ 2022-07-16 20:06  鹿先森JIAN  阅读(50)  评论(0编辑  收藏  举报