zoukankan      html  css  js  c++  java
  • (十)反射

    能够分析类能力的程序称为反射。

    Class类

    程序运行中,系统为每个对象维护一个运行时的类标识,该信息可以追踪对象所属的类。可以通过专门的java类访问这些信息,保存这些信息的类称为Class类。

    获取类型标识:

    Employee e;

    Class c1 = e.getClass();

    获取类名对应的Class对象

    String className = "java.util.Date";

    Class c2 = Class.forName(className);

    通过Class类实例化一个对象

    e.getClass().newInstance();

    将会调用e所属的类的默认构造器。如果需要为构造器提供参数,使用Constructor类的newInstance方法。

    虚拟机为每个类管理一个Class对象,因此可以使用==来比较两个Class对象,由此判断两个对象是否属于同一个类

    e.getClass()==g.getClass()

    注:getClass和instanceof的区别见这里

    利用反射分析类的能力

    检查类的结构

    java.lang.reflect包中有三个类Field,Method,Constructor分别描述类的域,方法和构造器。

    Class类中的getFields,getMethods,getConstructor方法返回类提供的public域,方法和构造器的数组,包括超类的公有成员。

    Class类中的getDeclareFields,getDeclareMethods,getDeclareConstructor返回类中声明的全部域,方法和构造器的数组,包括私有和保护的成员,不包括超类的成员。

     

    在运行时使用反射分析对象

    除了可以查看类的结构外,还可以查看数据域的实际内容。

    查看对象域的关键方法是Field的get方法。如果f是一个Field类型的对象,obj是某个包含f域的类的对象,f.get(obj)将返回一个对象,其值为obj域的当前值。

    举例:

    Employee harry = new Employee("Harry",3500,10,1,1989);

    Class c1 = harry.getClass();

    Field f = c1.getDeclaredField("name");

    Object v = f.get(harry);

     

    使用反射编写泛型数组代码

    java.lang.reflect的Array类允许动态创建数组。

    Class的getComponentType方法可以获取数组内元素的类型。

    下面,我们使用反射编写Arrays的copyOf方法:

    以下为该方法的解释

    static <T> T[]              copyOf(T[] original, int newLength)

    Copies the specified array, truncating or padding with nulls (if necessary) so the copy has the specified length.

    该方法将原来的对象数组拷贝到一个新的对象数组中,对象类型不确定。

    public static Object copyOf(Object a, int newLength)

    首先,我们需要通过Array类的newInstance动态创建一个新的数组,由于数组元素类型不确定,需要使用反射机制获取

    Class c1 = a.getClass();

    Class componentType = c1.getComponentType();

    接着,获取原来的数组长度

    int length = Array.getLength(a);

    其次,通过componentType和length创建数组对象

    Object newArray = Array.newInstance(componentType,length);

    最后,执行数组的复制

    System.arraycopy(a,0,newArray,Match.min(length,newLength));

    完整代码:

    public static Object copyOf(Object a, int newLength){
        Class c1 = a.getClass();
        if(!c1.isArray()) return null;
        Class componentType = c1.getComponentType();
        int length = Array.getLength(a);
        Object newArray = Array.newInstance(componentType,length);
        System.arraycopy(a,0,newArray,Match.min(length,newLength));
        return newArray;
    }

    调用任意方法

    Method类的invoke方法,它允许调用包装在当前Method对象中的方法。

    比如m1代表Employee类的getName方法,harry是Employee对象:

    String n = (String)m1.invoke(harry);

     

    详细信息看这里

  • 相关阅读:
    (转)tomcat与地址栏图标之研究(多浏览器)
    (转)Android学习笔记---SQLite介绍,以及使用Sqlite,进行数据库的创建,完成数据添删改查的理解
    (转) Tomcat部署Web应用方法总结
    (转)mysql账号权限密码设置方法
    (转) mysql的连接,创建账号,修改密码
    (转)mysql各个主要版本之间的差异
    (转)浅析Mysql的my.ini文件
    (转)如何在Windows上安装多个MySQL
    [笔记]线段树学习笔记
    [教程]对拍程序(linux)+ 考试(做题)生成数据 + 提交注意事项
  • 原文地址:https://www.cnblogs.com/wuchaodzxx/p/5962157.html
Copyright © 2011-2022 走看看