反射概述
反射是Java中最强大的技术之一
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
举例,扎小人。B扎的是对象A的稻草人,但是反射的是A这个人,A会疼痛。B就是调用者。一个东西能够映射到A对象,那个东西就叫做反射对象(稻草人)。而这个反射对象在Java中有一个对应的类叫做Class
。我们首先要捏小人,捏小人这个过程,就是我们创建Class对象的过程。
反射就是说,我们已经能拿到Class对象了,拿到后我们可以指定操作某一个类里面的成员变量、成员方法、构造方法等。前提就是我们必须先获得Class对象。
获取Class类的三种方式
▪ 当用户想要获取任何一个Class类有三种方式:
1、通过Class.forName
方法来获取对象
2、通过类名.class
来获取
3、通过对象的getClass()
来获取
4、如果是一个基本数据类型,那么可以通过Type的方式来获取Class对象
▪ 前三种方式的对比:
– 第一种常用,只需要传入一个类的完全限定名即可
– 第二种需要导入对应的包,依赖太强
– 第三种已经创建对象,就意味着已经产生了Class类
1 | //1、通过Class.forName方法来获取对象 |
对于大部分来说,getName()
和getCanonicalName()
相同。前者返回由类对象表示的实体,后者返回由Java语言规范定义的基础类的规范名称。少部分时候不同,如果是数组就不同。如下:
1 | Class type = args.getClass(); |
反射基本用途
反射的常用api
▪ 获取类的成员变量
获取成员变量,包括子类及父类,同时只能包含公共的类型 getField
此方法返回的是当前类(不包括父类)的所有属性,不仅仅是局限于公共访问修饰符,所有的访问修饰符都可以拿到 getDeclaredFields
▪ 获取类的成员方法
获取该对象的普通方法,包含的方法范围是当前对象及父类对象的所有公共方法 getMethods
获取当前类中所有的方法,无论什么访问修饰符 getDeclaredMethods
▪ 获取类的构造方法
构造方法比较特殊,它不能进行一个继承。
只能获取公有的构造方法 getConstructors
获取所有构造方法,无论是私有还是公有 getDeclaredConstructors
1 | Class<?> clazz = Class.forName("reflect.Student"); |
反射 私有获取和调用
注意:
- 反射在一定程度上破坏了封装性,需要合理使用
- 如果把Student中无参构造方法省略掉,会报错。因为new instance会调用无参构造方法
Field
1.获取到属性
2.创建一个对象
3.把属性放到对象中
4.强转后直接打印
1 | Field address = clazz.getDeclaredField("address"); |
Method
1 | Method add = clazz.getDeclaredMethod("add", int.class, int.class); |
constructor
如何调用私有的构造方法?
1 | Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(String.class, int.class, String.class); |