一.Java反射原理
我们知道Java对象首先通过编译器,加载成.Class文件,然后JVM类加载器通过.Class文件,将类信息加载到JVM的方法区。并且创建对应的Class对象
反射可以通过获取这个Class对象,来动态获取类的信息.
获取Class类对象的方法
1.调用对象的getClass()方法
Person person = new Person();
Class class1 = person.getClass();
2.通过类.class获取
Class<? extend Person> class2 = Person.class
3.通过Class.forname(“全类名”)获取
Class<?> class3 = Class.forname(“Person”);
//此方法不仅可以获取对象的class类对象,还可以初始化class类对象,例如加载jdbc驱动,Class.forName(“com.mysql.jdbc.Driver”);
同一种类型的对象获取的类对象都是同一个
Car car = new Car();
Car car1 = new Car();
Class<? extends Car> aClass = car.getClass();
Class<? extends Car> aClass1 = car1.getClass();
System.out.println(aClass == aClass1)//true
Class类对象具有的方法如下
getName():获得类的完整名字。
getFields():获得类的public类型的属性。
getDeclaredFields():获得类的所有属性。包括private 声明的和继承类
getMethods():获得类的public类型的方法。
getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类
getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。
getConstructors():获得类的public类型的构造方法。
getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。
newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
Class能实现的功能
1.获取所有的属性,并且可以访问(包括private属性)
2.获取所有的方法,并且可以调用(包括private方法)
public class Test {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Person person = new Person();
Class<? extends Person> class1 = person.getClass();
//获取私有属性
Field age = class1.getDeclaredField("age");
//给person对象的私有属性赋值
age.setAccessible(true);//设置访问私有属性的权限
age.set(person,18);
//获取私有方法
Method say = class1.getDeclaredMethod("say");
say.setAccessible(true);//设置访问私有方法的权限
//调用person对象的私有方法
say.invoke(person);
}
}
反射的使用场景
1.jdbc加载数据库驱动
2.IOC容器装配bean对象
3.Springboot的自动装配功能
反射的作用:就是在程序运行过程中,不需要JVM重新编译,就可以获取jvm运行时需要的Class类对象,这也是很多框架经常使用到的思想,包括Springboot的自动装配,按需装配,Spring的IOC的实现原理