类反射的概述:
将JAVA类里所有的成分逐一拆分,并将其映射成一个独自功能的类。
作用:
当程序不知道要调用什么类型的时候就可以通过反射机制来确定所要调用类的TYPE,生成的.CLASS是一个字节码文件, 我们通过类反射.getClass将其初始化,然后封装成Class类,通过Class对外提供的方法,可以很简单的获取到整个类里的东西
各种反射类的实现方法:
Class实例对象,基本的八大类型+void,还有数组的反射实例对象(以代码做演示)
一个类可以有多种反射方法获取到实例:
String str1 = "abc"; // 一个String类型,可以有3种反射方法找到所对应的实例对象
Class cls1 = str1.getClass(); //通过初始化的对象获取到String反射的实例对象
Class cls2 = String.class; // 内置的预定义String实例对象
Class cls3 = Class.forName("java.lang.String"); // 通过类的全名寻找到String实例对象,, 它有2种状态一个是直接调用了Class里已经生成好的字节码文件类,, 还有一个就是自己生成出来一份字节码文件类
Constructor: 获取到反射的实例对象里的构造方法。
String str = new String(new StringBuffer("abc"));
//通过参数可以知道调用的是String里一个构造函数参数为StringBuffrer的方法
Constructor constructor1 = String.class.getConstructor(StringBuffer.class);
//先通过String.class获取到String的字节实例,然后通过Constructor得到构造方法,接着传入对应的参数类型的字节实例
Constructor运用:
String str2 = (String)constructor1.newInstance(new StringBuffer("abc"));
//构造方法获取到了实例,然后赋值,参数的个数以及类型必须匹配
// 由于获取到的是一个Constructor对象,不知道是什么类型的,在我们确定类型的情况下,直接强转
Field:获取到反射实例对象里的成员变量。
public class Round {
private double r = 100.0; //圆里面只有一个半径
public double getR() {
return r;
}
public void setR(double r) {
this.r = r;
}
public static void main(String[] args) throws Exception {
Round round = new Round();
Field f = round.getClass().getDeclaredField("r");
//先获取到成员变量的名字, 由于是私有的, 所以必须是用getDeclaredField方法,不管它是不是私有的全部都获取到
f.setAccessible(true); //但是获取到私有的成员变量还是会报错, 原因,是被设置了不可见, 依旧是找不到,
//所以这里必须setAccessible(true),设置数据可见
System.out.println(f.get(round)); //打印结果为100.0
}
}
Method:获取到反射实例对象里的方法。
public class Round {
private double r = 100.0; //圆里面只有一个半径
public double getR() {
return r;
}
public void setR(double r) {
this.r = r;
}
public static void main(String[] args) throws Exception {
Round round = new Round();
Method m = round.getClass().getMethod("setR",double.class);
//依照惯例, 获取实例,然后获取到方法的名字,带入参数类型.
m.invoke(round,20.0);
//方法的作用,invoke就相当于发了一条指令,指定做什么事,这里是指定了round调用setR方法,值为20.0;
//set方法是空值,因为set只负责传值,所以set方法是空值
Method m2 = round.getClass().getMethod("getR");
//接着再获取getR的方法, 前面说过了反射就是将所有的成分映射成类, 所以这里又是一个类
System.out.println(m2.invoke(round)); //打印值为20.0 PS:如果直接调用getR,默认值是100.0
}
}