反射就是通过类的字节码直接获取类的对象或各种信息
想一下类都有那些部分呢?

  • field:
  • 按类型
  • 静态field
  • 普通field
  • 按权限
  • 共有
  • 私有
  • method
  • 静态
  • 普通
  • 公开
  • 私有
  • 构造器
  • Anotation

或许还有什么东西,反正一句话:只要他有的我都能获取

下面具体找一找方法:

  • 得到field:
    //Field[] field = cla.getFields();//找到的只有public的field
    //Field[] field = cla.getDeclaredFields();//得到所有的field
    //通过名字得到field
    //Field field = cla.getField(“text”);
    //Field field = cla.getDeclaredField(“text”);
  • 得到field的属性
  • 获取对象中field的值:
  • public或protected权限
  • 用方法直接取出
    方法:
  • field.get(obj)
  • field.getInt(obj)
  • ……
  • private权限
  • 先声明可访问
  • field.setAccessible(true);
  • 用方法取出(同上)
  • 设置对象中field的值
  • public或protected权限
  • field.set(obj, “lala”);
  • field.setInt(obj, i);
  • …….
  • private权限
  • 先声明可访问
  • field.setAccessible(true);
  • 设置值(同上)
  • 其他
  • field.getName()
  • field.getType()
  • 得到方法相关方法:
  • 构造方法及相关属性
  • con.newInstance(initargs)
  • con.getParameterTypes()
  • con.getDeclaringClass()
  • con.getName() //得到构造方法的类名(String)
  • con.getParameters()
  • con.getParameterCount()
  • con.toString() //或是直接输出con,打印出构造方法原型
  • 普通方法
  • cla.getDeclaredMethod(methodName, null);
    只能得到本类的方法(包括私有和公有),但不能得到父类的任何方法
    如果是private方法,还需要m.setAccessible(true);设置可访问
  • cla.getMethod(methodName, null);
    这货只能得到public方法(包括本类和父类),但不能得到private和protected方法
    思考怎么获取父类的私有方法?
  • 普通方法的相关属性
  • m.invoke(obj, args); //调用方法,参一为调用对象,参二为可变参数
  • m.toString()//打印出方法声明
  • m.getReturnType()//返回值
  • m.getParameterCount()//参数个数
  • m.getName()//方法名
  • m.getClass()//Object类的方法,返回对象的Class对象
  • m.getDeclaringClass()//返回方法的声明类Class对象
  • m.getParameters();//Parameter[]//得到所有的参数
  • m.getParameterTypes(); //得到所有的参数类型
  • m.toString() //或是直接输出m,打印出方法原型
  • 方法参数类Parameter
  • 没什么有价值的方法:p.getType();//得到参数的类型
  • Class对象,类的字节码
    除了可获得方法,field,还能得到其父类,得到类名,包名
    class.isArray(); //通过字节码判断对象是否是数组
  • 数组的反射:
  • 相同维度,相同类型的数组的字节码相同
  • 数组的父类是Object
  • Array类用于数组的反射操作(都是静态方法)
  • setXXX(Object array, int index, T value)
  • getXXX(Object array, int index)
  • getLength(Object array)
  • Array.newInstance(Class type, int length);
  • 此方法返回一个对象(数组对象),类型强转就行

特殊情况:
jdk1.4中没有可变参数,为了向上兼容,在method.invoke(obj, 数组);
如果传入的数组,编译器就会把数组中的每个元素当成多个参数
可是如果参数真的是数组,那就麻烦了
解决办法:
- 把数组转为Object对象,(Object)Array
- 把数组放到Object数组中,new Object[]{Array}