java反射机制

来源:互联网 发布:淘宝试用联盟网 编辑:程序博客网 时间:2024/05/24 08:33

反射(reflective)

定义及用途

能够分析类能力的程序称为反射反射有以下用途:
  • 运行时分析类的能力
  • 运行时查看对象
  • 实现通用的数组操作代码
  • 利用method对象

Class类

    在程序运行期间,java运行时系统始终为所有的对象维护一个被称为运行时的类型标识。这个信息跟随着每个对象所属的类。虚拟机利用运行时类型信息选择相应的方法执行。    通俗的讲:面向对象的思想是一切皆对象,基本数据类型也有包装类,那么类是谁的对象?类是java.lang.Class类的对象,类就是java.lang.Class类的实例。

Class类实例的三种表示方式

java.lang.Class的构造方法是private,只有JVM可以创建其对象。任何一个类都是Class的实例对象。三种表示方式:例如:一个Person类
public class Person {    private String name;    private Double salary;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public Double getSalary() {        return salary;    }    public void setSalary(Double salary) {        this.salary = salary;    }}
  • Class c1 = Person.class;
  • Person p = new Person();
    Class c2 = p.getClass();

    c1==c2; //true,一个类只可能是Class类的一个实例对象

  • Class c3 = Class.forName(“com.zz.Person”);

newInstance方法

可以通过类类型创建该类的实例Person p = (Person)c1.newInstance();该方法是调用默认的构造器初始化新创建的对象,如果没有默认的构造器就会抛出异常。

动态加载类

方式:Class.forName("类全路径");静态加载类和动态加载类的区别:    编译时加载的类为静态加载类,使用new创建的对象在编译时就会加载所有可能用到的类。    运行时加载的类为动态加载类,只有使用到了才会去加载。

获取信息

可以获得一个类对象所属类的全部信息
public static void main(String[] args) {    //获取类类型    Class<Person> c = Person.class;    //获取类名称    System.out.println("类名称:"+c.getName());    //获取该类的所有public方法    Method[] methods = c.getMethods();    //c.getDeclaredMethods(); 获取自己声明的方法,不管访问权限    for (Method method : methods) {        //方法名        System.out.println(method.getName());        //得到返回值类型的类类型        Class<?> returnType = method.getReturnType();        //返回值的名称        System.out.println(returnType.getName());        //得到参数类型的类类型        Class<?>[] parameterTypes = method.getParameterTypes();        for (Class<?> parameterType : parameterTypes) {            System.out.println(parameterType.getName());            }        }    }

方法反射的基本操作

获取某个方法
方法名和参数列表才能决定某个方法
    //获取类类型    Class<Person> c = Person.class;    //获取某个方法    Method m = c.getMethod("printMessage", new Class[]{int.class,int.class});
方法的反射操作
方法的反射操作是利用方法的类类型进行方法调用
    Person p = new Person();    Class c = p.getClass();    Method m = c.getMethod("add",new Class[]{int.class,int.class});    Object o = m.invoke(p,2,3);  //方法操作对象    //与p.add(2,3)效果相同,对象操作方法    System.out.println(o);  //5

通过反射连接集合泛型的本质

    ArrayList list1 = new ArrayList();    ArrayList<String> list2 = new ArrayList<String>();    Class c1 = list1.getClass();    Class c2 = list2.getClass();    System.out.println(c1==c2);  //true
    反射的操作都是编译之后的操作,是在运行时操作的。c1==c2返回true说明编译之后集合是去泛型化的。    java集合中的泛型是防止错误输入的,只在编译阶段有效,绕过编译则无效。验证如下:
    ArrayList list1 = new ArrayList();    ArrayList<String> list2 = new ArrayList<String>();    Class c1 = list1.getClass();    Class c2 = list2.getClass();    System.out.println(c1==c2);  //true    Method mm = c2.getMethod("add", new Class[]{Object.class});    mm.invoke(list2, 5);  //绕过编译    System.out.println(list2.size());  //1,无报错证明添加成功