Java 反射 学习笔记

反射允许对成员变量、成员方法和构造方法的信息进行编程访问

反射可以获取类中所有信息

获取 -> 解剖

获取是从class文件中获取

获取class对象

  • Class.forName("全类名") 全类名:包名+类名
  • 类名.class
  • 对象.getClass()

什么时候使用哪种

  • 源代码阶段:java文件 -> class文件,只在硬盘内操作。使用第一种
  • 加载阶段:class文件进入内存。使用第二种
  • 运行阶段:创建了类的对象。使用第三种
//最为常用的方式
Class clazz = Class.forName("package1.Student");

//更多的是当做参数进行传递
Class clazz2 = Student.class;

//当已经有了这个类的对象时才可以使用
Student s = new Student();
Class clazz3 = s.getClass();

System.out.println(clazz1 == clazz2);//true
System.out.println(clazz2 == clazz3);//true

Java中万物皆对象

  • class文件可以看作Class类的对象
  • 构造方法可以看作Constructor类的对象
  • 成员变量可以看作Field的对象
  • 成员方法可以看作Method的对象

获取构造方法

  • Constructor<?>[] getConstructors():返回所有public构造方法对象的数组
  • Constructor<?>[] getDeclaredConstructors():返回所有构造方法对象的数组
  • Constructor<T> getConstructor(Class<?>... parameterTypes):返回单个public构造方法对象
  • Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes):返回单个构造方法对象

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

  • T newInstance(Object... initargs):根据指定的构造方法创建对象
  • setAccessible(boolean flag):设置为true,表示取消访问检查
Class clazz = Class.forName("package1.Student");

Constructor[] cons = clazz.getConstructors();

//获取单个构造方法的参数传入要获取的构造方法参数的字节码文件
Constructor con1 = clazz.getDeclaredConstructor(String.class);

//获取参数列表
Parameter[] parameters = con1.getParameters();
for (Parameter parameter : parameters) {
    System.out.println(parameter);
}


//创建对象
//无法直接利用非public的方法
//暴力反射:临时取消权限校验
con1.setAccessible(true);
Student s1 = (Student)con1.newInstance("Lin");

获取成员变量

//获取class字节码文件对象
Class clazz = Class.forName("package1.Student");

//获取成员变量
Filed[] fileds = clazz.getDeclaredFields();
for (Filed filed : fileds) {
    System.out.println(filed);
}

//获取单个成员变量
Field gender = clazz.getFiled("gender");
System.out.println(gender);

//获取权限修饰符
int modifiers = gender.getModifiers();
System.out.println(modifiers);

//获取成员变量的名字
String n = gender.getName();
System.out.println(n);

//获取成员变量的数据类型
Class<?> type = gender.getType();
System.out.println(type);

//获取成员变量记录的值
Student s = new Student("zhangsan", 23, "boy");
name.setAccessible(true);
String value = (String)gender.get(s);
System.out.println(value);

//修改对象里面记录的值
gender.set(s, "girl");
System.out.println(s);

获取成员方法

  • Method[] getMethods()
  • Method[] getDeclaredMethods()

类似

img_show