反射的基本使用
Java的反射机制是在运行期,对于任意的一个类,都能够知道改类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;能够通过一个类的字符串名字获取这个类的信息,根据方法的名字去调用方法,这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
Java的反射主要是如下几个类:
类名 | 作用 |
---|---|
Class | 对应于Java的一个类 |
Method | 对应于Java类的某一个方法 |
Field | 对应于Java类的某一个字段 |
Constructor | 对应于Java类的某一个构造方法 |
下面我们来看这四个对象的获取方式:
//Class对象的获取
Class aClass1 = String.class;
Class aClass2 = "".getClass();
try {
Class aClass3 = Class.forName("java.lang.String");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
当我们获取到Class对象之后,可以通过Class对象的方法来获取另外三个对象:
Method[] methods = aClass1.getMethods();
Method[] methods2 = aClass1.getDeclaredMethods();
Field[] fields = aClass1.getFields();
Field[] fields2 = aClass1.getDeclaredFields();
Constructor[] constructors = aClass1.getConstructors();
Constructor[] constructors2 = aClass1.getDeclaredConstructors();
其中带有Declared的表示获取当前类的所有方法,包括私有的方法,但不包括其父类的,而不带该参数的代表获取类的所有公共方法,包括其父类的公共方法。
然后我们可以通过这四个对象上的一些方法来达到创建对象,调用方法,获取属性等一些目的。
下面我们介绍几种反射的应用场景。
调用系统私有的方法
try {
Field field = Person.class.getDeclaredField("name");
field.setAccessible(true);
String name = (String) field.get(new Person("Tony",24));
System.out.println(name);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
当我们获取到私有属性或者私有字段所对应的反射对象之后,能够通过调用setAccessible方法来绕过系统的权限检查,来实现调用私有字段或者私有方法的目的。
反射调用当前编译环境没有,但是具体的运行环境有的类
在Java编程的时候,有些类我们当前的编译环境没有,但是在具体的运行环境有这个类,那么我们用常规的方法当然是调用不到的,但是我们可以通过反射去创建那个类,并调用里面的方法和字段,这在Android开发里面,如果使用中间件技术(在系统和app之间使用自己开发的中间件去通讯,最后中间件会打包到系统里面)的时候,可能会用到。但是这种最常用的方式是将中间件里面客户端会用到的部分专门暴露出接口,放于客户端以供调用。