反射(理解)
(1)反射:就是通过class文件对象,去使用构造方法,成员变量,成员方法。
(2)获取class文件对象
A:Object类的getClass()方法
B:数据类型的静态的class属性
C:Class类forName()静态方法
推荐:开发使用第三种。
(3)反射的应用
A:通过反射获取构造方法并使用
B:通过反射获取成员变量并使用
C:通过反射获取成员方法并使用
(4)案例:
A:通过反射修改成员变量的值,包括私有
B:通过反射运行配置文件
C:通过反射给ArrayList<Integer>中添加String类型的数据
(一)Class类无构造方法,但可以通过以下3种方法获取对象的Class对象。
1、对象名.class例如:Person.class;
2、对象,getClass();例如( newPerson()).getClass();注:getClass();从Ooject 类中继承。
3、Class.forName("类名");例如:Class.forName("java.lang.String");
(二) 九个预定义Class事例对象 byte char short int long float double booleanvoid,
可以通过 int.class 来表示其实例对象 等于 int.class ==Integer.TYPE ;
可以用 isPrimitive() 来判断是否是基本类型,如int.class.isPrimitive() 返回true
而int[] .class.isPrimitiva()返回false,但 数组类型的Class实例通过isArray();
总之,只要是在源程序中出现的类型,各自都有自己的Class实例对象,如int[] void等
(三)Class类中获取其他成分(如构造函数、类型等)的Class实例方法:
1、Constructor 表示 构造函数
获取方式: 如:Constructor con = Person.class.getConstructor(Class<?>... parameterTypes);
注意参数必须是Person类参数的Class对象,如Person(int x,String y),
则getConstructor(int.class,String.class);
获取步骤:Constructor con =Person.class.getConstructor(int.class,String.class);
Person p = (Person) con.newInstance(int, new String("name"));
也可以通过Class类中的newInstance()获取 如
Personp1= Person.class.newInstance();
如果某个方法有多个构造函数,则通过参数类型来判断是哪个构造函数的Class对象。
可以通过Constructor[] con =Person.class.getConstructors(),来获取这一类型数组。
2、Field 表示 成员变量
获取方式:Field field = Person.class.getField(String name)// name表示String st =""中的st
Fieled[] fields =Person.class.getFields(); 获取多个成员变量
获取后 通过 field.get(obj)返回一个该类型实例,如String str =(String)field.get(obj);
这个方法返回的是obj对象,故需要通过String来强转。
获取对象后可以对该对象进行一些操作,再通过set()方法 来改变指定对象中的字段的值。
3、Method 代表一个类中成员方法
获取方法: Method charAt = String.class.getMethod("charAt",int.class);函数类型参数为:
方法名 和 参数类型的Class对象
调用方法:
普通方法: Charch1 = str.charAt(1);
反射方法:Char ch2 = charAt.inVoke(str,1);
如果传递给inVoke()的表示对象的参数是null如:inVoker(null,1)这表示该方法是静态。
4、数组的反射:
数组的Class对象:具有相同的元素类型和相同的维度表示同一个类型,在内存中数组用[ 表示,相应的字符表示类型 如 [I 表示int[].
如 int[] a1 = new int[3];
int[] a2 = new int[4];
int[][] a3 = new int[2][3];
String[] a4 = new String[3];
System.out.print(a1.getClass==a2.getClass);返回 true;
System.out.print(a1.getClass==a3.getClass);返回false;
System.out.print(a1.getClass==a4.getClass);返回false;
可以通过Class实例 的getSuperClass()方法,数组的父类均为 java.lang.object
注意: 基本类型的一维数组可以当作Object类型使用,但不能当作Object[]使用,非基本类型的都可
以,这里可以通过 Arrays.list()方法处理 int[] 和String[]类型数组看到差异。
三、反射的作用 实现框架功能
框架与工具类的区别:工具类是被用户的类调用,而框架是调用用户提供的类。要实现框架这种功能,就必须要解决这个核心问题:无法知道用户类的名称,不能创建用户类的对象,这就要通过反射来实现。