反射

作者: 你的益达233 | 来源:发表于2020-02-03 15:55 被阅读0次

    正常方式:引入需要的“包.类”名称 ---> 通过new实例化 --->取得实例化对象
    反射方式:实例化对象--->getClass()方法--->得到完整的“包.类”名称

    Class类是反射的源头

    实例化Class类对象方法有三种:

    1、通过forName()方法,需要完整的包名加类名
    示例代码:Class<?> c1 = Class.forName("com.cong.Student")
    2、类.class
    Class<?> c2 = Student.class
    3、对象.getClass()
    Class<?> c3 = new Student().getClass()

    Class的使用

    对象实例化正常操作使用new关键字实例化,但如果实例化好了Class对象,也可以用Class对象来进行具体类的实例化
    示例代码:
    Person p = (Person)c.newInstance()
    这其实是调用的是Person的无参构造方法。
    如果要调用有参构造方法实例化,则需要用到Constructor。 比较复杂,如果要使用Class实例化对象,最好保证类中存在一个无参构造方法

    反射的应用

    取得类的结构

    一、取得类所实现的全部接口
    public Class<?>[] getInterfaces()

    二、取得类所实现的父类
    Class<?> c2 = c1.getSuperclass()

    三、取得类的构造方法
    Constructor<?> con[] = c1.getConstructors()
    取得修饰符:public int getModifiers()
    取得方法名称:public String getName()
    取得全部参数的类型:public Class<?>[] getParameterTypes()
    还原修饰符 Modifier.toString(con[i].getModifiers())

    四、取得全部方法
    Method[] methods = c1.getDeclareMethods()
    public Method[] getDeclareMethods() : 输出的是本类的全部方法
    public Method[] getMethods() :输出全部方法,包括父类
    取得返回值类型:Class<?> r = methods[i].getReturnType()
    取得全部异常类型 Class<?>[] ex = methods[i].getExceptionTypes()

    五、取得全部属性
    public Field[] getDeclaredFields():输出本类中的全部属性,不包括父类和接口的
    public Field[] getFields():得到实现的接口或父类中的公共属性,不包括本类的
    取得属性类型:Class<?> r = f[i].getType(),进一步r.getName()

    在一般开发工具中经常看见随笔提示功能,实际上此功能就是利用以上程序完成的

    深入应用

    1、通过反射调用类中的方法

    如果想调用的话,则肯定必须清楚的知道要调用的方法名称是什么,之后通过Class类中的
    public Method getMethod(String name,Class<?>... parameterTypes)

    执行调用的方法:

    public Object invoke(Object obj,Object... args)  
    如method.invoke(activity,bindGet.param());
    

    在如method.invoke(c1.newInstance())
    调用无参方法:
    Method met = c1.getMethod("say");
    met.invoke(c1.newInstance())
    调用有参方法:
    Method met = c1.getMethod("sayHello",String.class,int.class)
    met.invoke(c1.newInstance(),"小明",30)

    通过反射调用类setter及getter

    setter及getter方法是一个标准的属性的访问方法,实际上此方法的操作之所以要这样规定,主要原因是由于反射机制可以给予支持
    方法中属性首字母大写化
    原理示例代码
    public static void setter(Object obj,String att,Object value,Class<?> type){
    Method met = obj.getClass().getMethod("set"+initStr(att),type)
    met.invoke(obj,value)
    }
    initStr(att)设首字母大写

    2、通过反射调用属性

    要操作一个类中的属性,可以通过Filed来完成
    public Field getDeclareField(String name)
    示例代码:
    Class<?> c1 = Class.forName("org.demo.Person")
    Object obj = c1.newInstance()
    Field nameField = c1.getDeclareField("name")
    nameField.setAccessible(true)
    nameField.set(obj,"小明")
    注:该操作与setter和getter无关

    3、通过反射操作数组

    public Class<?> getComponentType()
    示例代码:
    int temp[] = {1,2,3}
    Class<?> c = temp.getClass().getComponentType()
    相关操作
    取得第一位内容:Array.get(temp,0)

    开辟新数组以及修改数组的大小
    public static Object newInstance(Class<?> componentType,int... dimensions)
    示例代码:
    public static Object arrayInc(Object obj,int len){
    Class<?> c = obj.getClass();
    Class<?> arr = c.getComponentType();
    Object newO = Array.newInstance(arr,len); //根据已知数组类型新建数组,长度为len
    System.arraycopy(obj,0,newO,0,co)
    }

    相关文章

      网友评论

          本文标题:反射

          本文链接:https://www.haomeiwen.com/subject/whwhxhtx.html