码迷,mamicode.com
首页 > 编程语言 > 详细

Java基础学习笔记【12】Reflect反射(2)

时间:2015-10-08 19:54:21      阅读:260      评论:0      收藏:0      [点我收藏+]

标签:

  1. 使用反射来创建对象
    (1)public T newInstance():只能创建非private,无参的构造方法的对象;好比 new 类()
    1
    2
    Class<Teacher> clz = Teacher.class;
    Teacher t2 = clz.newInstance();
    (2)先得到一个构造器,调用构造器里的一个方法, T newInstance(Object... initargs) 、 initargs表示构造器的需要的实际参数 
    1
    2
    3
    Constructor<Teacher> con = clz.getDeclaredConstructor(String.class);
    con.setAccessible(true);//假如访问的是私有的就要把setAccsessable设置为true,因为是有成员不能直接访问
    Teacher t = con.newInstance("will");
    访问私有的成员之前:先设置其为可访问的,AccessibleObject: 表示可访问的对象,是Contructor,Method,Filed的父类;
    方法: void setAccessible(boolean flag) :用来设置是否可访问的,若要设置可访问的:obj.setAccessible(true);
  2. 反射访问执行获取的方法:
    1
    2
    3
    4
    5
    6
    Class<InvokeMethodByVarArgsDemo> clz =InvokeMethodByVarArgsDemo.class;
    Method m = clz.getMethod("show", int[].class);//调用public static void show(int ...is)
    m.invoke(null,new int[]{1,2,3});//YES                           
    //m.invoke(null,1,2,3);//ERROR
    m.invoke(null,(Object)new int[]{1,2,3});//YES
    m.invoke(null,new Object[]{new int[]{1,2,3}});//YES   访问静态方法不需要实例所以第一个参数可以为null
    1
    public Object invoke(Object obj,Object... args)   new Object[]{传递的实际参数};通用做法;
  3. T在这里应该制定其 极限(上限线或下限),反射泛型方法的时候有上限或者下限,应该以限定的最低标准执行例如 T extends Number,其类型上限最高为Number则用Number[].Class
    1
    2
    public static <T extends Number> List<T> asList(T... a) {  }
    Method m = clz.getMethod("asList", Number[].class);
  4. Object invoke(Object obj, Object... args) 对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。 
    (1)参数:obj - 从中调用底层方法的对象,就是要调用该方法的实例对象,静态的直接null    args - 用于方法调用的参数  
    (2)返回: 使用参数 args 在 obj 上指派该对象所表示方法的结果 
  5. Array类的静态方法也可以操作数组
    1
    2
    3
    Object ret=new Object[]{1,2,3}
    Array.getLength(ret)//获取数组的长度
    Array.get(ret, i)//获取数组ret中第i个的值
  6. 使用反射获取字段并且设置值:
    1
    2
    3
    4
    Class<Cat> clz = Cat.class;//使用反射得到Car类了的字段,并赋值,和取值
    Field[] fs = clz.getDeclaredFields();
    Field f = clz.getDeclaredField("name"); 
    f.getName() //取出字段的值
    设置字段的值:
    1
    void set(Object obj, Object value)
     将指定对象变量上此 Field 对象表示的字段设置为指定的新值。 
    参数: obj - 底层字段所属的对象(实例对象)  value - 正被修改的 obj 的字段的新值 
    1
    2
    3
    Cat c = clz.newInstance();  
    f.setAccessible(true);  //先设置可访问
    f.set(c, "Lucy"); //设置实例c的字段name的值为Lucy
  7. 反射获取泛型实际操作中的实例中泛型的具体类型:
    1
    2
    3
    4
    5
    Class<?> getType() //返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型。
    Type getGenericType() //返回一个 Type 对象,它表示此 Field 对象所表示字段的声明类型。
    ParameterizedType是Type子类, 表示参数化类型,也就是泛型类型
    Type[] getActualTypeArguments() //返回表示此类型实际类型参数的 Type 对象的数组。
    Type getRawType() //返回 Type 对象,表示声明此类型的类或接口。
  8. 当使用泛型作为父类的时候,需要返回T泛型,子类还没有实现不知道T的具体类型不能返回,使用反射可以获取T的类型并且返回
    类的构造方法中获取T的类型,因为子类实例化的时候会调用父类的无参数的构造函数
    1
    2
    3
    Type t = this.getClass().getGenericSuperclass();
    ParameterizedType pt = (ParameterizedType) t;
    clz = (Class<T>) pt.getActualTypeArguments()[0]; //获取的是数组,强转为指定的类型
    泛型中继承该类的子类实例化的时候,在泛型父类的构造函数中this代表之类的实例
    返回值
    return clz.newInstance();就表示T的实例



Java基础学习笔记【12】Reflect反射(2)

标签:

原文地址:http://www.cnblogs.com/lindongdong/p/605dbead1f1d10b838ccab708c7c4228.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!