在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应方法。
因为反射是运行时动态的去创建类的对象,所以运行效率上必然比直接创建对象要慢。
当我们不知道要初始化的类对象是什么但又需要创建类对象时候。
使用场景1.突破私有权限修饰符的约束限制。(须小心使用)
2.写框架代码的时候经常需要用。
3.阅读源码。
public class Demo {
String str;
private int number;
public Demo() {
}
public Demo(String str, int number) {
this.str = str;
this.number = number;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
System.out.println("str");
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
System.out.println("number");
}
private void priMethod(){
System.out.println("priMethod");
}
}Demo demo = new Demo();
//1
Class test = Demo.class
//2
Class test = demo.getClass();
//3
Class test = Class.forName("全限定名"); //全限定名指包名+类名,通常我们都采用方式三进行反射。
Demo demo = (Demo) test.newInstance();Class<Demo>clazz = (Class<Demo>)Class.forName("包名+Demo");
//获取全部Constructor对象
Constructor<Demo> [] constructors = (Constructor<Demo>
[])clazz.getConstructor();
//获取带参数的构造方法
Constructor<Demo> constructor = clazz.getConstructor(String.class,int.class);注意:获取带参数的构造方法时不需要进行转型
通过有参数的构造拿到对象实例
Demo demo = constructor.newInstance("Demo",1);获取clazz对应类中的所有方法,包括从父类继承来的所有方法,但不能获取private修饰的方法
//获取clazz对应类中的所有方法,包括从父类继承来的所有方法,但不能获取private方法
Method [] methods = clazz.getMethods();如果只获取当前类的方法,并包含私有方法,则使用getDeclareMethods即可。
Method [] methods = clazz.getDeclareMethods();如果只获取指定方法,若方法有参数则需要参数名称和参数列表,无参就不需要写了。
注意:与获取构造方法一样,带参方法也不需要转型
Method methodStr = clazz.getDeclaredMethod("setStr",String.class);
Method methodInt = clazz.getDeclaredMethod("setNumber",int.class);获取clazz对应类中的所有变量,包括父类的变量,但不能获取private修饰的变量
//获取clazz对应类中的所有变量,包括父类的所有变量,但不能获取private变量
Field [] fields = clazz.getFields();如果只获取当前类的变量,并包含私有变量,则使用getDeclaredFields即可。
Field [] fields = clazz.getDeclaredFields();如果只获取指定变量,需要传入变量的名字。
Field fieldStr = clazz.getDeclaredField("str");非私有方法调用时采用method.invoke(类的实例)方法,传入②或③步拿到的类的实例,和方法需要的参数即可。
methodInt.invoke(demo,1);私有方法调用时,须在method.invoke(类的实例)方法前,调用method.setAccessible(true);方法。
Method methodPriMethod = clazz.getDeclaredMethod("priMethod");
methodPriMethod.setAccessible(true);
methodPriMethod.invoke(demo);注意:与私有方法一样,若想获取私有变量的值,需先写field.setAccessible(true);方法。
Demo demo = new Demo("str",1);
fieldStr.get(demo);
fieldStr.set(demo,"test");最后送一句话给自己也与各位共勉
行百里者半九十,不要轻易自满,永远记得坚持超越自己,加油!!!