目录
一、反射的概念
反射:指在运行期内,可以动态的获取并调用任何一个类的方法、属性等内容的功能。
二、反射基础类
1、Class类
java中的反射所涉及到的第一个类是Class类。简单来说,是一个用Final关键字修饰的,封装了所有类的类名、所继承的父类、接口等相关信息的类。也就是说,只要拿到一个类的Class对象,就能够获取该类的所有信息。
获取一个类的Class对象(实例)的方法有如下三种:
(1)、通过类名访问
类名.Class
(2)、通过该类的实例对象访问
A a = new A();
a.getClass();
(3)、通过Class类的静态方法
Class.ForName();
传入的参数是类的完全限定名(可通过外部文件动态传入)
注:1、上述方法中的(1)和(2)都是在编译期,方法(3)是在运行期确定对象的类型。
2、上述三种方法得到的同一个类的Class对象是相同的。
3、一个类只会被加载一次,产生一个该类的Class对象
eg:
Class cls1 = A.Class
Class cls2 = A.Class
Class cls3 = A.Class
(A是一个类名)上述三个cls1,cls2和cls3的哈希值完全相等,原因就是上述第3点。
得到某个类的Class对象cls后。使用newInstance()方法创建对象。
Object obj = cls.newInstance() ===>相当于A a = new A(),也就是执行了A类中的构造方法
注:每用一次newInstance()方法就会创建一个对象,且创建的对象都是不同的。
2、Constructor类
获取所有的public(公有)的构造方法:
getConstructors()
该方法返回一个Constructor[ ],并且数组中的每一个元素都是一个构造方法,并且带有参数类型。
获取某一个指定的构造方法:
Constructor c = getConstructor()
注:
不传参数==>代表获取的是无参构造方法
若传参数==>代表获取的是有参数的构造方法(传入的是参数类型的Class对象 eg:String.class)
执行构造方法:
c.newInstance();
参数为:(1)若执行无参构造,不传任何参数
(2)执行有参构造,传入相对应的具体值
3、Field类
获得所有的成员变量:
cls.getFields();
该方法返回的一个Field[ ]
使用某一个成员变量:
(1)、创建目标类的对象
Object obj = cls.newInstance();
(2)、获取一个成员变量(根据字段名称获取):
cls.Field() ==>返回值类型是Field
参数为:字段(定义的成员变量)名称。
(3)、使用成员变量(赋值)
a.set(A, B) 注:a是Field类型的对象
参数为:A:目标类的对象名称 B:要给变量赋的具体的值
(4)、拿到目标字段的值
a.get( A )
参数为:A是目标类的对象名称。
4、Method类
获取目标类中的所有方法:
Method[ ] m1 = cls.getMethods()
注:此方法获取的方法中包括父类中的方法。
Method[ ] m1 = cls.getDeclaredMethods()
==>此方法获取的所有方法中不包含父类,仅有当前类的
获得方法中的参数类型:
getParameterTypes() ==>只获得参数类型,返回Class[ ]
获取方法中的参数
getParameters() ==>获得参数类型和参数(在控制台输出的参数是arg0),返回的 是Parameter[]
获取单一指定的方法:
Method m = cls.getMethod()
参数为:1、获取没有参数的方法:只写要获取的方法名称
2、获取有参数的方法:需要传两个参数(A,B);A是方法名称,B是原方法中的参数 类型的Class对象,例如:int.class
拿到某个方法后,该执行拿到的方法:
m.invoke( ) ==>invoke()的作用就是执行方法
参数为:1、传一个参数 => 传入该类的对象(Object A = cls.newInstance() ),实际传入的就是A
2、传入两个参数(A,B)=> A与上述一样;B是要传入的具体的值。
注:
若执行的是静态方法,则A=null,不需要传对象。
若A类继承自B类,且A类重写了B类中的dosth()方法,也就是说A是子类,B是父类。
则:B.class.getMethod( "dosth" ).invoke( new A() );
这句代码最后执行的方法仍然是A类中的dosth()方法。
5、InstanceOf、isAssignableFrom
(1)、InstanceOf运算符
A InstanceOf B =>返回的结果是boolean值
作用:判断对象A是否是B类型
注:A,B均为引用类型;B若是A的父类、接口,结果都为true
(2)、isAssignableFrom
A isAssignableFrom B =>返回结果是boolean值
作用:判断是否可以将B类型的值赋给A
注:A,B均为Class对象;B是A的子类,结果为true;B是A的实现类,结果为true。
6、补充
上述获得的方法、构造方法和字段都是公有的访问权限,如果要获得除公有外的其他访问权限,则:
getDeclaredConstructors ==>获得所有的构造方法(包括私有)
getDeclaredFields(); ==> 获得所有的成员变量(包括私有)
在获取到私有的方法、属性后,若要调用执行,需要设置setAccessible(true);为true(默认为false),设置为true后才能执行私有的方法、字段等。
若不设置为true,能够获得但是不能被调用执行!