黑马程序员_基础加强第一天——Java反射机制

时间:2022-08-30 00:34:27
  • 反射的基石:Class类
    • Class类描述了类的名字,访问属性,属于的包名,字段名称的列表,方法名称的列表等信息
    • 如何得到各个字节码对应的实例对象(Class类实例)?
      1. 类名.class
      2. 对象.getClass();
      3. Class.forName("类名(包括包名)");
    • 基本数据类型.class.isPrimitive()返回true
    • int.class==Integer.TYPE返回true
  • 反射
    • 一个Java类用一个Class类的对象表示
    • Class类提供方法来获得Java类的信息。Field, Method, Constructor, Package等等。
    • 学习反射的要点是获得这些对象之后如何用
  • Constructor类
    • 得到某个类的所有构造方法:Constructor[] cons = Class.forName("java.lang.String").getConstructors();
    • 得到某个类的某个构造方法:Constructor con = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
    • 创建实例对象:
      • 通常方式:String s = new String(new StringBuffer("abc"));
      • 反射方式:String s = (String)constructor.newInstance(new StringBuffer("abc"));
    • Class.newInstance方法:
      • String s = (String)Class.forName("java.lang.String").newInstance();
      • 该方法内部先得到默认的构造方法
  • Field类:
    • 示例:获取一个对象中的成员值并且把对象中所有String类的成员变量中的b改成a
      public class ReflectPoint {
      private int x;
      public int y;
      public String str1 = "abandon";
      public String str2 = "basketball";
      public String str3 = "binbow";

      public ReflectPoint(int x, int y){
      this.x = x;
      this.y = y;
      }

      public String toString(){
      return str1 + " " + str2 + " " + str3;
      }
      }

      //主类:
      import java.lang.reflect.*;
      public class ReflectFieldDemo {

      public static void main(String[] args) throws Exception{
      // TODO Auto-generated method stub

      ReflectPoint rp = new ReflectPoint(3,5);
      //私有成员x:
      Field fieldX = rp.getClass().getDeclaredField("x");
      fieldX.setAccessible(true); //因为私有所以要强行获取
      System.out.println("x = " + fieldX.get(rp));
      //公有成员y:
      Field fieldY = rp.getClass().getField("y");
      System.out.println("y = " + fieldY.get(rp));

      //改变对象中String成员的方法:
      changeLetter(rp);
      System.out.println(rp);
      }

      //改变类的对象中String成员,将b换成a的方法:
      public static void changeLetter(Object obj) throws Exception{
      Field[] fields = obj.getClass().getFields();
      for(Field field:fields){
      if(field.getType() == String.class){
      String oldV = (String)field.get(obj);
      String newV = oldV.replace('b', 'a');
      field.set(obj, newV);
      }
      }
      }

      }

  • Method类
    • 得到类中的某一个方法: Method methodCharAt = Class.forName("java.lang.String").getMethod("charAt", int.class);
    • 调用方法: methodCharAt.invoke(str, 1);
    • 如果invoke的第一个参数为null,说明该方法是静态方法
  • 数组的反射
    • 具有相同维数和元素类型的数组属于同一个类型,既具有相同的Class类对象
    • 代表数组的Class类实例对象的getSuperClass方法返回的父类为Object对应的Class
    • 基本类型的一维数组可当做Object,不可当做Object[];非基本类型的一维数组都可。
    • Arrays.asList()方法处理int[]和String[]时的差异
    • Array工具类用于完成对数组的反射操作(java.lang.reflect.Array)