Java反射

Java反射

反射概述

反射是指对于任何一个Class类,在"运行的时候"都可以直接得到这个类全部成分。

  • 在运行时,可以直接得到这个类的构造器对象:Constructor
  • 在运行时,可以直接得到这个类的成员变量对象:Field
  • 在运行时,可以直接得到这个类的成员方法对象:Method

这种运行时动态获取类信息以及动态调用类中成分的能力称为Java语言的反射机制。

反射的关键:

  • 反射的第一步都是先得到编译后的 Class 类对象,然后就可以得到 Class 的全部成分。
HelloWorld.java -> javac -> HelloWorld.class;
Class c = HelloWorld.class

反射获取类对象

获取 Class 类的对象的三种方式:

  • Class c1 = Class.forName(“全类名”);
  • Class c2 = 类名.class
  • Class c3 = 对象.getClass();

Java反射_第1张图片

反射获取构造器对象

反射的第一步就是先得到类对象,然后从类对象中获取类的成分对象。

Class 类中用于获取构造器的方法

方法 说明
Constructor[] getConstructors() 返回所有构造器对象的数组(只能拿public的)
Constructor[] getDeclaredConstructors() 返回所有构造器对象的数组,存在就能拿到
Constructor getConstructor(Class… parameterTypes) 返回单个构造器对象(只能拿public的)
Constructor getDeclaredConstructor(Class… parameterTypes) 返回单个构造器对象,存在就能拿到

使用反射技术获取构造器对象并使用

  • 获取构造器的作用是初始化一个对象的返回。

Constructor 类中用于创建对象的方法

符号 说明
T newInstance(Object… initargs) 根据指定的构造器创建对象
public void setAccessible(boolean flag) 设置为true,表示取消访问检查,进行暴力反射

如果是一个非public的构造器,需要打开权限(暴力反射),然后在创建对象

  • setAccessible(boolean)
  • 反射可以破坏封装性,私有的也可以执行了。

反射获取成员变量对象

  • 反射的第一步是先得到类对象,然后对类对象中获取类的成分对象
  • Class 类中用于获取成员变量的方法
方法 说明
Field[] getFields() 返回所有成员变量对象的数组(只能拿public的)
Field[] getDeclaredFields() 返回所有成员变量对象的数组,存在就能拿到
Field getField(String name) 返回单个成员变量对象(只能拿public的)
Field getDeclaredField(String name) 返回单个成员变量对象,存在就能拿到

获取成员变量的作用是在某个对象中取值、赋值

Field 类中用于取值、赋值的方法

符号 说明
void set(Object obj, Object value): 赋值
Object get(Object obj) 获取值。
  • 如果某成员变量是非 public 的,需要打开权限(暴力反射),然后再取值、赋值
    • setAccessible(boolean)

反射获取方法对象

  • 反射的第一步是先得到类对象,然后从类对象中获取类的成分对象。
  • Class 类中用于获取成员方法的方法
方法 说明
Method[] getMethods() 返回所有成员方法对象的数组(只能拿public的)
Method[] getDeclaredMethods() 返回所有成员方法对象的数组,存在就能拿到
Method getMethod(String name, Class… parameterTypes) 返回单个成员方法对象(只能拿public的)
Method getDeclaredMethod(String name, Class… parameterTypes) 返回单个成员方法对象,存在就能拿到
  • 获取成员方法的作用依然是再某个对象中执行此方法

Method 类中用于出发执行的方法

符号 说明
Object invoke(Object obj, Object… args) 运行方法
参数一:用obj对象调用该方法
参数二:调用方法的传递的参数(如果没有就不写)
返回值:方法的返回值(如果没有就不写)
  • 如果某成员变量是非 public 的,需要打开权限(暴力反射),然后再触发执行
    • setAccessible(boolean)

反射的作用

绕过编译阶段为集合添加数据

  • 反射是作用在运行时的技术,此时集合的泛型将不能产生约束了,此时是可以为集合存入其他任意类型的元素
ArrayList<Integer> list = new ArrayList<>();
list.add(100);// list.add(“黑马"); // 报错
list.add(99);
  • 泛型只是在编译阶段可以约束集合只能操作某种数据类型,在编译成Class文件进入运行阶段的时候,其真实类型都是ArrayList了,泛型相当于被擦除了。

作用

  • 可以在运行时得到一个类的全部成分然后操作。
  • 可以破坏封装性。(很突出)
  • 也可以破坏泛型的约束性。(很突出)
  • 更重要的用途是适合:做Java高级框架
  • 基本上主流框架都会基于反射设计一些通用技术功能。

你可能感兴趣的:(java,开发语言)