Java反射机制
Java反射机制概念
Java的反射机制本质是在运行时,通过对象实例来动态加载对象的信息。是为了解决在运行期间,对某个实例不知道是什么类的情况下,如何调用其声明方法、字段的问题。
场景举例
现有主类Main、Person类和Person的子类Student,主类的main函数中获取Student类的一个实例stu,并传入test方法。但是由于test方法的参数是顶级父类Object对象,调用test方法时可以传入任何对象,所以对于test方法内部来说,并不能知道实际传入的对象是什么,如果想要在test中访问具体传入对象的属性和方法怎么办呢?
这种情况下,通过反射就可以在test方法中得到此时传入的object具体实例以及访问它的方法和字段
1 | public class Main{ |
获取class实例的方式
- 当知道class时(以java.lang.String为例),直接通过class的静态变量
class
获取
1 | Class c = String.class; |
- 当知道class完整类名时(以java.lang.String为例),通过静态方法
Class.forName()
获取
1 | Class c = Class.forName("java.lang.String"); |
- 当有实例变量时,可以通过改实例变量的
getClass()
方法获取,如上例子中test方法就可通过这种方式获得object的真正class实例
1 | public static void test(Object object){ |
获取字段和方法的方式
对于任意一个Object
实例,只要获取了其class,就可以获取关于它的全部数据结构
字段(field)
获取字段信息
Field getField(name)
获取某个public
的field
(包括从父类继承的)
1
2
3
4
5//以上文test方法为例
public static void test(Object object){
Class c = object.getClass();
Field ageField = c.getField("age") //ageField值为:public int Person.age
}Field[] getFields()
获取所有public
的field
(包括从父类继承的)Field getDeclaredField(name)
:获取当前类的某个field
(不包括父类)Field[] getDeclaredFields()
:获取当前类的所有field
(不包括父类)
获取字段值
- 通过get方法获得具体值
1
2
3
4
5
6
7
8
9
10//以上文test方法为例
import java.lang.reflect.Field;
...
public static void test(Object object){
Class c = object.getClass();
Field ageField = c.getField("age");
//已知age是int型,通过ageField.getInt,传入object,获得具体值
System.out.println(ageField.getInt(object));//输出22
}
...
方法
获取方法信息
Method getMethod(name, Class...)
:获取某个public
的Method
(包括从父类继承的)Method[] getMethods()
:获取所有public
的Method
(包括从父类继承的)Method getDeclaredMethod(name, Class...)
:获取当前类的某个Method
(不包括父类)Method[] getDeclaredMethods()
:获取当前类的所有Method
(不包括父类)
调用方法
- 通过invoke方法进行调用
1
2
3
4
5
6
7
8
9
10//以上文test方法为例
import java.lang.reflect.Method;
...
public static void test(Object object){
Class c = object.getClass();
Method m = c.getDeclaredMethod('hello');
//传入object,通过m.invoke调用方法。如果hello方法有参数,通过m.invoke(object,parm1,parm2...)传入参数
m.invoke(object);
}
...
用途
- 通过反射机制访问java对象的属性和方法等
- 开发通用框架,通过反射可以根据配置文件加载不同类或对象,调用不同的方法
参考文章
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 只取壹瓢饮!