------- android培训、java培训、期待与您交流! ----------
一.反射的基石
1.反射的基石--Class类
Java程序中的每个类属于同一类事物,描述这类事物的Java类名就是Class。
2.Class类的实例对象:是每个类在内存中的字节码文件。注:一个类被类加载器加载到内存中,会占用一块用内存空间,这个内存空间中的内容就是这个类的字节码文件。
3.获得Class类的实例对象:
--通过具体类的class静态属性获得。 Class 变量名 = 类名.class// 类名是被加载到内存中的类的名称。如:Class cls = Math.class//Math.class表示Math类的字节码
--通过对象的getClass()方法获得。如:Person p1 = new Person(); Class cls = p1.getClass();
--通过Class类的静态方法获得。如:Class cls = Class.forName("java.lang.String");//获得String类的字节码,如果该类字节码还没有加载,会先加载该类的字节码,然后返回该字节码。注:虚拟机会将加载的字节码存储在虚拟机的缓存中,之后如果再使用该类的字节码,就不会再加载,而是直接使用缓存中的字节码。
示例代码:
// 创建一个字符串对象
String str = "123";
//通过三种不同的方法来获取同一个类的字节码文件
Class cls1 = String.class;
Class cls1 = str.getClass();
Class cls1 = Class.forName("java.lang.String");
//判断不同的方法获得的字节码文件是否是同一个文件,
System.out.println(cls1==cls2);//true
System.out.println(cls1==cls2);//true
//结论:三种不同的方法获取某一个类的字节码文件,所获得地是同一个文件。
4.预定义Class 实例对象
指的是每一种数据类型(包含基本数据类型和引用数据类型)都有各自的实例对象。
二.反射
1.什么是反射:把类中定义的各种组成部分映射成对应类,每个具体的部分是该类的一个对象。.
2.构造函数所映射的类Constructor。
Constructor类中常用方法
--获得某个类的所有构造函数。如:Constructor[] con= Class.forName('包名.类名").getConstructor90;//首先获得该类的字节码文件实例对象,在调用对象的getConstructor()方法,就能获得该类的所有构造方法。
--获得某个类的某个构造函数。如:Constructor con= Class.forName('包名.类名").getConstructor(StringBuffer.class)//根据构造函数接收的参数来区分构造函数。
**通过构造函数对象创建某个类的对象。如:String str = (String)con.newInstance(new StringBuffer("abc"));
****Class类中的newInstance()方法创建实例对象。
String str = (String)Class.forName("java.lang.String").newInstance()//先获得某个类的字节码文件对象,然后通过该类字节码文件对象的newInstance()方法来创建该类的对象
3.成员变量所映射的类Filed
示例代码:
编写一个类包含两个成员变量和一个构造方法。
class ReflectPoint{
private int x;
public int y;
public ReflectPoint(int x , int y){
super()
this.x = x;
this.y = y;
}
}
//编写测试类
public class Test{
public static void main(String[] args){
ReflectPoint rp1 = new ReflectPoint(3,5);
Field fieldY = rp.getClass().getField("y"); //获得类中的某个成员变量映射类的对象。成员变量通过变量名区分。getField只能获取非私有的成员变量映射类的对象。
fieldY.get(rp1)//把rp1所指对象中对应的值取出来。
Field fieldX = rp.getClass().getDeclaredField("x");//getDeclaredField能获得私有成员变量映射类的对象。
fieldX.setAccessible(true);//由于x成员变量时私有的,所有要暴力破除。
fieldX.get(rp);//在将值取出来。
}
}
4.成员方法所映射的类Method
使用反射来调用某个类的方法
1.通过反射获取该类的字节码文件对象。
2.通过字节码文件对象的getMethod(string name,参数类型.class)获得具体方法的映射对象//类中可能有多个重载方法,需要使用参数来区分这些方法。
3.通过具体方法的映射对象的invoke(object o , 对应方法的参数)方法来调用对应的方法。如果对于的方法是静态的,传递NULL对象,如果不是静态的要传递具体方法的映射对象。
****使用反射调用某个类中的main方法
第一步,二步同上。
映射对象名.invoke(null,(object)new String[]{"123","456"})//(object)告诉编译器,把数组作为对象。
5.数组所映射的类Array