反射的概念和特点:

  • java的类:具备相同特征的对象的模版.
    • 类Person: 不同事物也具备相同的特征(父类) 同一事物具备相同的特征(子类) 结论: 按照事务的特征来进行抽取成具体的java类,由java类来进行具体对象的创建. java中的类的特征: 属性: 修饰符 类型 属性名 值 结论:可以创建类专门用来表示以上特征,该类的一个对象表示一个具体的属性. 方法: 修饰符 返回值类型 方法名 形参 方法体 结论:可以创建类专门用来表示以上特征,该类的一个对象表示一个具体的方法. 构造器: 修饰符 形参 方法体 结论:可以创建类专门用来表示以上特征,该类的一个对象表示一个具体的构造器方法 抽取一个类来表示类的共同特征. 一个该类的具体对象存储了一个类的所有的信息. 类对象 类的对象

反射的概念和作用:

  反射的概念:
  万事万物皆对象,类也是对象.
      引用:
  通过反射创建类对象和使用类对象.
      反射的作用:创建对象
  问题:
  传统方式创建对象:new 类名();,前提是必须预先知道要使用的类.但是,如果无法确定要执行的对象怎么办?
  如果要修改使用的类,必须修改源码.
      解决:
  使用反射.
      使用:
  获取类对象
      操作属性
  操作方法
      操作构造器

反射获取类对象的三种方式:

 Class.forName();//根据全限定路径获取 
// 对象名.getClass();//根据对象获取
//   类名.class//根据类名获取
----------------------------------------------------
//   代码体现:
  //第一种方式--->创建类对象
  Class cla01=Class.forName("com.bjsxt.pojo.Person");
  //第二种方式---->调用底层使用反射封装的方法
  Class cla02=Person.class;
  //第三种方式---->调用底层使用反射封装的方法
  Class cla03=new Person().getClass();
//   常用的方法:
      System.out.println("获取类对象的包名---->"+cla01.getPackage());
    System.out.println("获取类的修饰符----->"+cla01.getModifiers());
    System.out.println("获取类的名称(全限定)----->"+cla01.getName());
    System.out.println("获取类的名称(类名)----->"+cla01.getSimpleName());
    System.out.println("获取类的父类的类对象----->"+cla01.getSuperclass());
//  注意: 通过反射创建的类对象只有一个.

反射操作元素属性:

获取类对象 获取反射类的属性 操作反射类的属性 操作静态 操作非静态

*   操作属性:
  *    获取类对象
  • 获取类属性
    
  •  getFields()      获取所有的公共字段包括父类    返回Field[]
    *     getDeclaredFields()     获取所有声明的字段(不包括父类)  返回Field[]
    
  •  getField(String name)    获取指定的公共字段包括父类    返回Field
    
  •  getDeclaredField(String name)  获取指定的声明的字段(不包括父类)   返回Field
    
  • 操作类属性
    
  •  操作静态属性
    
  •   类属性对象.get(null)    返回静态属性的值
    
  •   类属性对象.set(null,"值")   赋值
    
  •  操作非静态属性
    
  •   类属性对象.get(Object obj);
    
  •   类属性对象.set(Object obj,"值");
    

  public static void operField() throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException{
    //获取类对象
    Class cla=Class.forName("com.bjsxt.pojo.Student");
    //获取反射类属性
    //获取类及其父类的公共字段
    Field[] fds = cla.getFields();
    for(Field f:fds){
      System.out.println("获取属性名------>"+f.getName());
      System.out.println("获取修饰符------>"+f.getModifiers());
      System.out.println("获取类型------>"+f.getType());//返回的是类型的Class对象
    }
    System.out.println("******************************");
    //获取类声明的所有字段
    Field[] fds2=cla.getDeclaredFields();
    for(Field f:fds2){
      System.out.println("获取属性名----->"+f.getName());
      System.out.println("获取修饰符------>"+f.getModifiers());
      System.out.println("获取类型------>"+f.getType());//返回的是类型的Class对象
    }
    System.out.println("******************************");
    //获取指定的字段
    Field f=cla.getField("pname");//指定获取类及其父类的公共字段
    System.out.println(f.getName());
    Field f2=cla.getDeclaredField("money");//指定获取类的所有字段
    System.out.println(f2.getName());
    Field f3=cla.getSuperclass().getDeclaredField("pname");//指定获取父类声明的字段
    System.out.println(f3.getName());
    //操作字段值
    System.out.println("************操作静态字段**********************");
    //操作静态属性
    Field fs=cla.getDeclaredField("money");
    fs.set(null,2000);
    System.out.println(fs.get(null));
    System.out.println("************操作非静态字段**********************");
    //操作非静态属性
    Field fd=cla.getDeclaredField("sname");
    Object obj=cla.newInstance();
    fd.set(obj, "李四");
    System.out.println(fd.get(obj));
    //暴力反射操作私有化属性(了解)
    Field fd2=cla.getDeclaredField("ssex");
    fd2.setAccessible(true);//暴力反射,操作私有化属性,不安全
    Object obj2=cla.newInstance();//获取实例化对象
    System.out.println(fd2.get(obj2));


  }

反射操作方法:

获取类对象
获取方法对象
操作方法对象
静态方法
非静态方法

操作方法:

  • 获取类对象
  • 获取方法对象
  • getMethods() 获取所有的公共方法包括父类
  • getDeclaredMethods() 获取所有声明的方法不包括父类
  • getMethod(String name,Class...cla) 获取指定的公共方法
  • String name 表示方法名
  • Class...cla 表示方法接收的参数类型的类对象
  • getDeclaredMethod(String name,Class...cla) 获取指定的声明方法
  • String name 表示方法名
  • Class...cla 表示方法接收的参数类型的类对象
  • 操作方法
  • 静态方法
  • 方法对象.invoke(null,参数值1,参数值2,....);
  • 方法对象.invoke(null,null);
  • 非静态方法
  • Object obj=cla.newInstance();
  • 方法对象.invoke(obj,参数值1,参数值2,....)
  • 方法对象.invoke(obj,null)




  //操作方法
  private static void operMethod()
      throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
//获取类对象
    Class cla = Class.forName("com.bjsxt.pojo.Student");
//获取类方法对象
//获取所有的公共方法包括父类
    Method[] ms = cla.getMethods();
    for (Method m : ms) {
      System.out.println("获取方法名--->" + m.getName());
    }
    System.out.println("************************************");
//获取所有声明的方法不包括父类
    Method[] ms2 = cla.getDeclaredMethods();
    for (Method m : ms2) {
      System.out.println("获取方法名--->" + m.getName());
    }
//获取指定的公共方法包括父类
    Method m = cla.getMethod("pHi", int.class, String.class);
    System.out.println(m.getReturnType());
//获取指定的声明的方法,不包括父类
    Method m2 = cla.getDeclaredMethod("sHello", null);
    System.out.println(m2.getName());
//执行方法
//静态方法
    Method m3 = cla.getDeclaredMethod("sHi", String.class);
    m3.invoke(null, "今天学了反射,好开心");
//非静态
    Method m4 = cla.getDeclaredMethod("sHi", int.class, String.class);
    m4.invoke(cla.newInstance(), 3, "反射功能好强大");
  }

反射操作构造器:

获取类对象 获取构造器对象 创建对象: 有参 无参

示例代码:

//反射操作构造器
private static void operConstructor()
throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
//获取类对象
Class cla = Class.forName("com.bjsxt.pojo.Student");
//获取构造器方法对象
Constructor[] cs = cla.getConstructors();
for (Constructor c : cs) {
System.out.println(c.getName());
}
//获取指定的构造器
Constructor c = cla.getConstructor(String.class);
//创建实例化对象
Object obj = c.newInstance("女");
System.out.println(cla.getDeclaredMethod("getSsex", null).invoke(obj, null));

Student s = new Student("女");
System.out.println(s.getSsex());
}