前言
反射作为java基础体系里非常重要的一环,我们在日常的编码过程中很难触碰到这一块,虽然触碰比较少但是不代表它就不重要。作为java程序员我们有义务去了解它以及它的常用API。
问题
- 什么是反射
- 为什么要用到反射(反射的作用)
- 反射的使用场景
什么是反射?
反射是指程序在运行期间来获取任意一个类的完整构造以及相关成员变量和方法,并且能够调用任意一个对象的任意方法。反射中的反指的就是在运行期间我们才知道需要调用类是什么并且对它进行操作,与之相对应的就是“正”,一般情况下我们需要使用一个类必定知道这个类是什么有什么方法,并对它进行初始化然后对对象进行方法的调用,这就是“正”。
反射就是指到运行期才知道需要操作的类是什么,并且可以在运行期间获取完整的构造以及调用任意方法
为什么要用到反射(反射的作用)
我们一直在说反射指的是直到运行期间程序才知道要操作什么类以及调用相关方法。那么针对一些比方说需要在运行期间来读取相关一些配置文件来获取类名的,你在一开始并不知道他们的名字没办法进行 new ClassName()所以需要用到反射。
反射的使用场景
- spring/mybatis框架里大量使用了java的反射机制
- 动态生成对象,应用于工厂模式中。spring的bean容器就是一个大工厂
- jdk的动态代理实现,就是通过反射来获取传入接口的实现类
反射相关API
java反射里包含了4个相关的类
- Class类 java里的类的类,在java世界里万物皆对象,所以类也是一种对象,而类就是java.lang.Class的实例化对象。通过它可以获取到一个类的属性和方法。
- Constructor类 处于java.lang.reflec包下,它表示的是类的构造方法,可以用来创建类的实例化对象。
- Filed类 处于java.lang.reflec包下,它表示类的成员变量,可以用来获取和设置类的属性。
- Method类处于java.lang.reflec包下,它表示类的方法,可以用来获取类的方法相关信息或者执行方法。
获取Class的方法
//根据路径(包名+类名) 来获取Class方法
Class clazz = Class.forName("com.suxin.myRelfect.Person");
//直接调用某个类的class属性来获取Class
Class clazz2 = Person.class;
//调用类的对象的getClass方法来获取Class
Person person = new Person();
Class clazz3 = person.getClass();
获取Constructor类并且使用它来创建相应的对象
//直接通过class类里的newInstance方法,需要Person类里有默认的空构造方法
Person p1 = (Person) clazz.newInstance();
//通过class类的getDeclaredConstructor方法,通过参数类型来指定某个构造方法并进行生成对象
Constructor<Person> constructor = clazz.getDeclaredConstructor(String.class,Integer.class);
Person p2 = constructor.newInstance("老夫",10);
获取Filed类和Method类
//获取类的所有成员属性
Field[] fields = clazz.getDeclaredFields();
for(Field field: fields) {
System.out.println(field.toString());
}
//获取类的所有方法
Method[] methods = clazz.getDeclaredMethods();
for(Method method : methods) {
System.out.println(method.toString());
}
getDeclaredMethods与getMethods,getDeclaredFields与getFields,getDeclaredConstructors与getConstructors的不同区别
- 最关键的区别就是前者可以获取到类的无论成员变量还是方法无关乎它是不是public访问权限的都可以获取到,而后者只能获取到被public访问权限申明的变量或者方法。
网友评论