反射的概念和作用:

  • JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
  • 反射的概念:万事万物皆对象,类也是对象.
  • 引用:通过反射创建类对象和使用类对象.
  • 问题:
    • 传统方式创建对象:new 类名();,前提是必须预先知道要使用的类.但是,如果无法确定要执行的对象怎么办?
    • 如果要修改使用的类,必须修改源码.
  • 解决:使用反射.

反射获取类对象

  • Class.forName();———根据全限定路径获取(必须会)
    • Class cla01 = Class.forName(“Bean.Person”);
  • 对象名.getClass();——-根据对象获取
    • Class cla02 = Person.class;
  • 类名.class—————根据类名获取
    • Class cla03 = new Person().getClass();
  • 获取类对象的相关方法函数
    • 获取类对象的包名:cla01.getPackage()
    • 获取类对象的修饰符:cla01.getModifiers()
    • 获取类的名称(全限定):cla01.getName()
    • 获取类的名称(类名):cla01.getSimpleName()
    • 获取类的父级类对象:cla01.getSuperclass()
  • 注意:一个类只有一个类对象

反射操作类属性

  • 1.获取类对象
  • Class cla = Class.forName(“Bean.Student”);
  • 2.获取反射类属性
  • getFields() 获取该类及其父类的公共字段 返回Field[]
    1
    2
    3
    4
    5
    6
    Field[] fds = cla.getFields();//获取该类及其父类的公共字段
    for (Field f : fds) {
    System.out.println("获取属性名---------------"+f.getName());
    System.out.println("获取修饰符---------------"+f.getModifiers());
    System.out.println("获取类型---------------"+f.getType());//返回的是类型的Class对象
    }
  • getDeclaredFields() 获取所有声明的字段(不包括父类) 返回Field[]
    1
    2
    3
    4
    5
    6
    Field[] fds2 = cla.getDeclaredFields();
    for (Field f : fds2) {
    System.out.println("获取属性名---------------"+f.getName());
    System.out.println("获取修饰符---------------"+f.getModifiers());
    System.out.println("获取类型---------------"+f.getType());//返回的是类型的Class对象
    }
  • getField(String name) 获取指定的公共字段包括父类 返回Field
    1
    2
    Field f = cla.getField("pname");//指定获取公共字段及其父类公共字段
    System.out.println(f.getName());
  • getDeclaredField(String name) 获取指定的声明字段(不包括父类) 返回Field
    1
    2
    Field f2 = cla.getDeclaredField("money");//指定获取该类的的所有字段
    System.out.println(f2.getName());
  • 获取父类的所有声明字段
  • 获取子类对象,通过子类的cla0.getSuperclass()反射获取到父类对象,再通过getDeclaredFields()或者getDeclaredField(String name)获取父类全部声明对象或者指定声明对象
    1
    2
    Field f3 = cla.getSuperclass().getDeclaredField("page");
    System.out.println(f3.getName());
  • 3.操作字段值
  • 静态属性值
    • Field fs = cla.getDeclaredField(“money”);
    • fs.set(null, 2000);-静态为null
    • System.out.println(fs.get(null));
  • 非静态属性值
    • Field fd = cla.getDeclaredField(“sname”);
    • Object obj = cla.newInstance();-cla.newInstance()为获取类对象的实例化
    • fd.set(obj, “李四”);
    • System.out.println(fd.get(obj));
  • 暴力反射操作私有化属性(了解)
    • Object obj2 = cla.newInstance();–获取实例化对象
    • Field fd2 = cla.getDeclaredField(“ssex”);–暴力反射,操作私有属性,不安全
    • fd2.setAccessible(true);
    • fd2.set(obj2, “女”);
    • System.out.println(fd2.get(obj2));

反射操作类方法

  • 1.获取类对象
  • Class cla = Class.forName(“Bean.Student”);
  • 2.获取类方法对象
  • getMethods() 获取所有的公共方法包括父类
    1
    2
    3
    4
    Method[] ms = cla.getMethods();
    for (Method m : ms) {
    System.out.println("获取方法名--->"+m.getName());
    }
  • getDeclaredMethods() 获取所有声明方法不包括父类
    1
    2
    3
    4
    Method[] ms2 = cla.getDeclaredMethods();
    for (Method m : ms2) {
    System.out.println("获取方法名--->"+m.getName());
    }
  • getMethod(String name,Class…cla) 获取指定的公共方法包括父类
  • String name 表示方法名 Class…cla 表示方法接收的参数类型的类对象
    1
    2
    Method m=cla.getMethod("pHi", int.class,String.class);
    System.out.println(m.getName());
  • getDeclaredMethod(String name,Class…cla) 获取指定声明方法不包括父类
  • String name 表示方法名 Class…cla 表示方法接收的参数类型的类对象
    1
    2
    Method m2 = cla.getDeclaredMethod("sHello", null);
    System.out.println(m2.getName());
  • 3.执行方法
  • 静态方法
    • Method m3 = cla.getDeclaredMethod(“sHi”, String.class);–方法名,参数类对象
    • m3.invoke(null, “今天学了反射”);-静态为null,传入参数的值
  • 非静态方法
    • Method m4 = cla.getDeclaredMethod(“sHi”, null);-方法名,参数类对象
    • Object obj = cla.newInstance();-类对象实例化
    • System.out.println(m4.invoke(obj, null));-类对象实例化,传入参数的值