Java 基础-反射与注解

来源:互联网 发布:易娱网络怎么样 编辑:程序博客网 时间:2024/05/17 22:17

一、Class

1. Class 类型的获取

  • Clazz.class;
  • clazz.getClass();
  • Class.forName(String className);

2. 根据 Class 类型创建类实例

Class clazzType = Clazz.class;try{    // Clazz 必需含有无参构造方法    Clazz clazzBean = (Clazz)clazzType.newInstance();}catch(Exception e){    e.printStackTrace();}

3. Class 加载

加载方式 实现 描述 静态加载 new Clazz() 在编译过程就加载 动态加载 (Class.forName(String className)).newInstance() 运行时才加载

二、反射

1. 反射的基本应用

class Clazz{    public void print(String str){        System.out.print("str");    }}
// 1. 获取类信息Clazz clazz = new Clazz();Class c = clazz.getClass();try{    // 2. 获取类方法    Method m = c.getMethod("print", String.class);    // 3. 实现方法的反射操作    m.invoke(clazz, "设定输出内容");}catch(Exception e){    e.printStackTrace();}   

2. 反射在泛型中的应用

反射操作位于编译之后,即编译后为泛型对象将失去泛型特征

ArrayList<String> list = new ArrayList<String>();Class c = list.getClass();try{    // 通过反射绕过编译时对插入值类型的判断    Method m = c.getMethod("add", Object.class);    m.invoke(list, 1);}catch(Exception e){    e.printStackTrace();}

三、注解

1. 概念理解

  • 成员类型必需是原始类型 及 String,Class, Annotation, Enumeration
  • 如果注解成员只有一个,则成员命名必需为 value(),在使用时可忽略成员名与赋值号(=)
  • 注解类可无成员对象,称之为标识注解


// 元注解@Target({ElementType.METHOD,ElementType.TYPE}) // 作用域@Retention(RetentionPolicy.RUNTIME) // 声明生命周期@Inherited // 允许子类继承,且仅继承类注解@Documented // 生成 javadoc 时包含注解信息// 使用@interface 定义注解public @interface Description{    // 无参无异常的成员声明    String sex();    String author();    // 成员的默认值声明    int age() default 18;}


作用域 描述 @Target(ElementType.TYPE) 接口、类、枚举、注解 @Target(ElementType.FIELD) 字段、枚举的常量 @Target(ElementType.METHOD) 方法 @Target(ElementType.PARAMETER) 方法参数 @Target(ElementType.CONSTRUCTOR) 构造函数 @Target(ElementType.LOCAL_VARIABLE) 局部变量 @Target(ElementType.ANNOTATION_TYPE) 注解 @Target(ElementType.PACKAGE) 包


生命周期/注解分类 描述 @Retention(RetentionPolicy.SOURCE) 源码注解(仅源码中存在,编译后不存在) @Retention(RetentionPolicy.CLASS) 编译时注解(源码与编译后均存在) @Retention(RetentionPolicy.RUNTIME) 运行时注解(运行时存在,影响逻辑处理)

2. 自定义

语法: @<注解名>(<成员名1>=<成员值>,<成员名2>=<成员值2>,…)

@Description(sex="I am boy", author="gzejia",age="25")public class Clazz{    @Description(sex="I am boy", author="gzejia",age="25")    public String manSex(){        return "boy";    }}

3. 注解解析

通过反射获取类、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑

try{    // 1.使用类加载器加载类    Class c = Class.forName("...Clazz");    // 2.判断是否存在注解信息    boolean isExist = c.isAnnotationPresent(Description.class);    // 3.获取类注解信息    if(isExist){        Description d = (Description)c.getAnnotation(Description.class);        System.out.println(d.sex());    }    // 4.获取方法注解信息    Method[] ms = c.getMethods();    for(Method m : ms){        boolean isMExist = m.isAnnotationPresent(Description.class);        if(isExist){            Description d = (Description)m.getAnnotation(Description.class);            System.out.println(d.author());        }    }    // 获取注解信息方式二(以获取方法注解信息为例)    for(Method m : ms){        Annotation[] as = m.getAnnotations();        for(Annotation a : as){            if(a instanceof Description){                Description d = (Description)a;                System.out.println(String.valueOf(d.age()));            }        }    }}catch(Exception e){    e.printStackTrace();}

[感谢慕课平台]

原创粉丝点击