Java反射入门

Java 反射

程序在运行期间,可以动态的获取一个类的信息
(属性、方法、构造方法、方法的形参、父类、父接口、类上的泛型、包、注解)。

类对象

类加载的产物是类对象,而一个类有且只会被加载一次。

类对象的获取方式

  • 类.class
Class<LightComponent> lightComponentClass = LightComponent.class;
  • 对象.getClass()
Class<? extends LightComponent> aClass1 = component.getClass();
  • Class.forName(“包.类”)
 Class<?> aClass = Class.forName("day26.Component");
类对象常见的类基本操作方法
  • getClassLoader() : 获取加载该类的 加载器
  • getName() : 获取类的名字(包名 + 类名)
  • getSimpleName(): 只获取类名(不包含包名)

双亲委托机制

加载一个类主要是通过 类加载器 ClassLoader 实现的, Java中提供了三个 ClassLoader。

  • BootStrapClassLoader: 只负责加载 JDK 官方提供的核心类

  • ExtClassLoader: 负责加载 JDK 官方提供的 扩展库

  • AppClassLoader: 负责加载 自定义的类 和 第三方 jar

1. 保证一个类只会被加载一次、2.防止核心类被篡改

Constructor

获取 类中的 构造方法 Constructor

  • getDeclaredConstructors() : 获取 类中所有的 构造方法,返回一个 Constructor[]
  • getConstructors() : 获取 类中 所有 公开 的构造方法 (被 public 修饰的)
  • getDeclaredConstructor(Class…) : 获取指定的构造方法
  • getConstructor(Class…) : 获取指定的 公开的 构造方法

Constructor 常见的方法

  • newInstance(obj…) : 使用Constructor 构造方法 创建对象
  • setAccessible(boolean) : 是否允许破坏封装,绕过访问权限,默认是false
  • getName() : 获取构造方法的方法名
  • getModifiers() : 获取修饰符 (权限修饰符、静态修饰符 , final, abstract, native, …)
    • Modifier 是标识 修饰符 ,内置了 大量的 is方法 判断是否是某种修饰符 ,内置 大量的 常量,标记 修饰符
  • getParameterTypes() : 获取 构造方法的参数列表,返回 Class[]
  • getParameterCount() : 获取 参数列表的个数

Field 属性

  • getDeclaredFields() : 获取当前类 声明的所有属性
  • getFields() : 获取 该类 所有的 公开属性 (包含继承的属性)
  • getDeclaredField(String fieldName) : 根据名字 获取指定的属性
  • getField(String fieldName) : 根据名字,获取 指定的 公开属性 (包含继承的属性)

Field 属性中常见的方法

  • set(obj, val) : 给 obj 对象的 属性 设置 val 值

  • setXxxx(obj, val) : 给 obj 对象的属性(类型是基本数据类型) 设置 对应的 值

  • get(obj) : 获取 obj 对象的 属性值 ,返回 Object

  • getXxxx(obj) : 获取 obj对象的属性值(类型是基本数据类型)

  • trySetAccessible() : 尝试访问,如果不能访问 返回 false

  • setAccessible(boolean) : 是否破坏封装

  • getModifiers() : 获取属性修饰符

  • getName() : 获取属性名

  • getType() : 获取 属性类型

练习:

有一个 Map 集合, 数据格式如下

{
   id: 10, 
   username: "张三"
}

==> 通过 反射技术 将 Map集合中的数据,添加到 User (id, username) 对象中 

Method 方法

  • getDeclaredMethods() : 获取当前类中定义的所有方法
  • getMethods() : 获取 类中所有公开方法(包含继承的方法)
  • getDeclaredMethod(name, Class<?>…) : 获取当前类中声明的指定方法
  • getMethod(name, Class<?>…) : 获取 指定的公开方法 (包含继承的方法)

Method 中常见的方法

  • getName() : 获取方法名

  • getModifiers() : 获取修饰符

  • getReturnType() : 获取返回值的类型

  • getParameterTypes() : 获取方法参数列表类型

  • getParameterCount() : 获取参数个数

  • getExceptionTypes() : 获取方法 声明的时候 throws 的异常

  • invoke(obj, params…) : 调用方法

获取 父类、父接口

  • getSuperclass() : 获取一个类的 直接父类, 返回 Class
  • getGenericSuperclass() : 获取一个类的直接父类(包含泛型信息), 返回 Type

**如果父类没有使用泛型,那么2个方法返回的结果是一样的 **

  • getInterfaces() : 获取一个类实现的所有接口, 返回 Class[]
  • getGenericInterfaces() : 获取一个类实现的所有接口(包含泛型信息)、返回Type[]
练习:
   定义一个方法、用来获取 一个类 中 所有的 属性 (包含所有父类的属性)
   public static List<Field> getAllFields(Class<?> clz) ;
   定义一个方法、用来获取一个类的所有父类(不包含接口)
   public static List<Class<?>> getAllSuperClasses(Class<?> clz) ; 
   定义一个方法、用来获取一个类的所有接口(包含父接口)
   public static List<Class<?>> getAllSuperInterfaces(Class<?> clz);
   定义一个方法、用来获取一个类的所有方法(包含父类定义的)
   public static List<Method> getAllMethods(Class<?> clz) ;   

注解

注解是对代码进行注释的一种手段,它可以参与编译和运行~

元注解

元注解 用来注解在其他注解上的注解

  • @Target : 用来定义注解可以书写的位置, 例如 类上、方法上、属性上、参数上、构造方法上

    • ElementType.TYPE : 标记该注解可以写在类上、接口上
    • ElementType.METHOD : 标记该注解可以写在方法上
    • ElementType.FIELD : 标记该注解可以写在属性上
    • ElementType.CONSTRUCTOR : 标记该注解可以写在构造方法上
  • @Retention : 用来定义注解在什么情况下可以使用

    • RetentionPolicy.SOURCE : 注解只能在源码中使用、代码编译后该注解会不存在
    • RetentionPolicy.CLASS : 注解可以保留在字节码中、程序在运行的时候不可用
    • RetentionPolicy.RUNTIME : 注解可以在运行阶段使用、可以配合反射实现某些特殊效果
  • @Documented : 用来标记该注解在生成文档的时候,是否在文档中生成

  • @Inherited : 用来标记该注解是否允许 子类继承

  • @Repeatable : 用来标记该注解是否支持多次注释

自定义注解

注解使用 @interface 修饰符

注解 支持的 成员类型
*   1.  8种基本数据类型
*   2.  字符串
*   3.  枚举类型
*   4.  Class
*   5.  注解
*   6.  上述所有类型的 数组 表示形式

获取注解的方式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值