java基础:反射

来源:互联网 发布:android sdk windows 编辑:程序博客网 时间:2024/06/05 09:30

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

  • 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}

0 0