1、反射的使用场景
比如我们知道一个object类型的对象,我们不知道他具体什么类型,我们就可以通过反射来先获取class类对象,通过class类对象可以获取对应类型类的成员变量,私有变量,成员方法,私有方法,满参构造,无参构造等等。
- 逆向代码 ,例如反编译
- 与注解相结合的框架 例如Retrofit
- 单纯的反射机制应用框架 例如EventBus 2.x
- 动态生成类框架 例如Gson
2、反射reflect实现的三种方法
package Reflex;
public class People {
private int age;
private String name;
private int sex;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public People(int age, String name, int sex) {
this.age = age;
this.name = name;
this.sex = sex;
}
public People() {
}
}
package Reflex;
public class ReflexDemo1 {
// 本测试是测试反射的三种写法
public static void main(String[] args) throws ClassNotFoundException {
//因为可能会出现类找不到的异常,所以需要throws或try..catch 处理异常
System.out.println(peopleClass);
//这是反射的第一种写法
//Class.forname(类的路径)
Class peopleclass1 = Class.forName("Reflex.People");
System.out.println("这是反射的第一种写法:Class.forname(类的路径)");
System.out.println(peopleclass1);
//这是反射的第二种写法
//对象.getClass()
People people =new People();
Class peopleClass2 = people.getClass();
System.out.println("这是反射的第二种写法:对象.getClass()");
System.out.println(peopleClass2);
//这是反射的第三种写法
//类名.class
Class peopleClass3 = People.class;
System.out.println("这是反射的第三种写法:类名.class");
System.out.println(peopleClass3);
}
}
2.通过反射获取Class对象的作用,可以获取类,成员变量,构造方法,公开方法,私有方法等等。
getDeclaredConstructors(); //获取所有的构造函数
getDeclaredConstructor(参数类型); //获取一个所有的构造函数
getConstructors(); //获取所有公开的构造函数
getConstructor(参数类型); //获取单个公开的构造函数
getModifiers(); //获取所有修饰符
//返回类型:String,可以反射类名,方法名,构造函数名等等
getName(); //获取全名 例如:com.bean.Book
getSimpleName() //获取类名 例如:Book
getPackage(); //获取包名
getInterfaces() //获取接口名
getSuperclass() //获取父类名
getMethods() //获取所有公开的方法
getMethod(String name) //获取单个公开的方法,参数是可以指定方法名(使用方法如下)
Method method = clz.getMethod("printAll"); //获取单个的公开方法
method.invoke(clz.newInstance(),null);
getDeclaredMethods() //获取所有的方法
getDeclaredMethod(String name) //获取单个的所有方法 参数是可指定方法名
getFields() //获取所有的公开字段
getField(String name) //参数可以指定字段 获取单个public字段
getDeclaredFields() //获取所有的字段
getDeclaredField(String name) //获取单个字段 参数可以指定字段
newInstance(Object initargs) //实例化对象
3.使用demo
public class Test{
public static void main(String[] args) throws Exception {
//获得Dog类的Class对象
Class<?> classType = Class.forName("Dog");
//生成对象的实例
Object obj = classType.newInstance();
//取得dogName属性
Field dogName = classType.getDeclaredField("dogName");
//禁止Field的访问控制检查
dogName.setAccessible(true);
//将Field的值设为“Xiao Qiang”
dogName.set(obj, "Xiao Qiang");
//取得say()方法
Method say = classType.getDeclaredMethod("say", new Class[]{});
//禁止say方法的访问控制检查
say.setAccessible(true);
//调用say方法
say.invoke(obj, new Object[]{});
}
}
class Dog {
//私有的属性
private String dogName = "Wang Cai";
//私有的方法
private void say() {
System.out.println(dogName + ": Wang Wang");
}
}