Java的反射编程 Reflection
一、反射编程对Java编程有深远的影响:获得类的基因信息,创建对象,调用方法。
(1)获得类型的基因信息(class类型的对象)
(2)根据该基因信息探察出类属性和方法
(类的所有细节,修饰符、包名、方法名...)
(3)根据该基因信息能“克隆”实例化该类的对象
(4)能够调用对象的属性和方法
二、Class类 java.lang.Class用来描述其他类型,保存某种数据类型的基因信息(元数据)
数据类型包括基本类型、引用类型。
Class没有构造方法,说明Class的对象不能通过new来创建。
1、Class类的实例有三种创建方式:
1)Class c1 = Class.forName("类的全限定名");
类的全限定名:就是包名.类名
能够加载一个类,入JVM的Code区域,还会返回一个该类类型的Class对象。
这是最常用的一种方式,只需要提供一个类的全名。
2)Class c2 = 类名.class;虚拟机行为。
前提是:编程时必须知道类的名称。
类名硬编码(固定)在程序中,没有第一种方式灵活。
3)Student stu = new Student();
Class c3 = stu.getClass();//Object中的Class对象
前提(使用场合)是:必须先有该类的实例,再获取Class对象。
系统只为一种类型维护一个Class类型的实例(单例)。
基本类型只能通过.class获取Class对象。
2、类加载的时机:
1)new Student();
2)类名.xxx
3)Class.forName("package.AAA");有可能会抛出一个类找不到的异常。
三、反射编程的优劣势:
优势:面向通用编程,不会形成应编码,是框架程序的重要技术组成。
劣势:代码量大、繁琐、效率偏低。
四、反射编程的一般步骤:
//step1: 通过类名获得类对象
Class c = Class.forName(args[0]);
//step2: 获得我们想要的构造方法对象 Constructor
Class[] paramTypes = {String.class, int.class};
Constructor con = c.getDeclaredConstructor(paramTypes);
//step3: 调用构造方法,获得实例
//step4: 获得想要调用的方法对象
Class[] paTypes = {String.class};
Method m = c.getMethod("move", paTypes);
//step5: 对创建好的实例调用指定的方法
Object[] os2 = {"NewYork"};
Object res = m.invoke(obj, os2); //针对obj对象调用m方法,参数存于os2
System.out.println(res); //res 就是方法的返回值
一、反射编程对Java编程有深远的影响:获得类的基因信息,创建对象,调用方法。
(1)获得类型的基因信息(class类型的对象)
(2)根据该基因信息探察出类属性和方法
(类的所有细节,修饰符、包名、方法名...)
(3)根据该基因信息能“克隆”实例化该类的对象
(4)能够调用对象的属性和方法
二、Class类 java.lang.Class用来描述其他类型,保存某种数据类型的基因信息(元数据)
数据类型包括基本类型、引用类型。
Class没有构造方法,说明Class的对象不能通过new来创建。
1、Class类的实例有三种创建方式:
1)Class c1 = Class.forName("类的全限定名");
类的全限定名:就是包名.类名
能够加载一个类,入JVM的Code区域,还会返回一个该类类型的Class对象。
这是最常用的一种方式,只需要提供一个类的全名。
2)Class c2 = 类名.class;虚拟机行为。
前提是:编程时必须知道类的名称。
类名硬编码(固定)在程序中,没有第一种方式灵活。
3)Student stu = new Student();
Class c3 = stu.getClass();//Object中的Class对象
前提(使用场合)是:必须先有该类的实例,再获取Class对象。
系统只为一种类型维护一个Class类型的实例(单例)。
基本类型只能通过.class获取Class对象。
2、类加载的时机:
1)new Student();
2)类名.xxx
3)Class.forName("package.AAA");有可能会抛出一个类找不到的异常。
三、反射编程的优劣势:
优势:面向通用编程,不会形成应编码,是框架程序的重要技术组成。
劣势:代码量大、繁琐、效率偏低。
四、反射编程的一般步骤:
//step1: 通过类名获得类对象
Class c = Class.forName(args[0]);
//step2: 获得我们想要的构造方法对象 Constructor
Class[] paramTypes = {String.class, int.class};
Constructor con = c.getDeclaredConstructor(paramTypes);
//step3: 调用构造方法,获得实例
Object[] os1 = {"Mary", 20};
Object obj = con.newInstance(os1);//step4: 获得想要调用的方法对象
Class[] paTypes = {String.class};
Method m = c.getMethod("move", paTypes);
//step5: 对创建好的实例调用指定的方法
Object[] os2 = {"NewYork"};
Object res = m.invoke(obj, os2); //针对obj对象调用m方法,参数存于os2
System.out.println(res); //res 就是方法的返回值