简介
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
原理
《深入理解Java虚拟机》一文中介绍,类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载、连接、初始化、使用、卸载。而JVM在加载阶段要完成的3件事情中正好有Class对象的生成:
- 通过一个类的全限定名来获取定义此类的二进制字节流。
- 将这个字节流所代表的的静态存储结构转化为方法区的运行时数据结构。
- 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。
获取一个类的Class对象的三种方法,对应的通过Class对象创建类实例也有三种方法:
Class<TestClass> class = Class.forName("com.zkw.TestClass");
Clas<TestClass> class = TestClass.class;
TestClass tc = new TestClass();
Class<TestClass> class = tc.getClass();
TestClass testClass = class.newInstance();
使用
在正式开始前,先介绍一个最重要的方法setAccessible(),使用反射可以获取一个类的所有方法及属性,但是某些方法和属性是私有的,这时候就需要通过该方法将方法和类设置为public;
注: setAccessible()方法并不是修改类的访问权限,而是是否禁止Java 语言访问检查(值为true则禁止)
相关类
类名 | 用途 |
---|
Class类 | 代表类的实体,在运行的Java应用程序中表示类和接口 |
Field类 | 代表类的成员变量(成员变量也称为类的属性) |
Method类 | 代表类的方法 |
Constructor类 | 代表类的构造方法 |
class类
● 获得类相关的方法
方法 | 用途 |
---|
Cast | 把对象转换成代表类或是接口的对象 |
getClassLoader() | 获得类的加载器 |
getClasses() | 返回一个数组,数组中包含该类中所有公共类和接口类的对象 |
getDeclaredClasses() | 返回一个数组,数组中包含该类中所有类和接口类的对象 |
forName(String className) | 根据类名返回类的对象 |
getName() | 获得类的完整路径名字 |
newInstance() | 创建类的实例(不推荐使用,而是使用Constructor的newInstance()方法) |
getPackage() | 获得类的包 |
getSimpleName() | 获得类的名字 |
getSuperclass() | 获得当前类继承的父类的名字 |
getInterfaces() | 获得当前类实现的类或是接口 |
● 获得类中属性相关的方法
方法 | 用途 |
---|
getField(String name) | 获得某个公有的属性对象 |
getFields() | 获得所有公有的属性对象 |
getDeclaredField(String name) | 获得某个属性对象 |
getDeclaredFields() | 获得所有属性对象 |
● 获得类中注解相关的方法
方法 | 用途 |
---|
getAnnotation(Class annotationClass) | 返回该类中与参数类型匹配的公有注解对象 |
getAnnotations() | 返回该类所有的公有注解对象 |
getDeclaredAnnotation(Class annotationClass) | 返回该类中与参数类型匹配的所有注解对象 |
getDeclaredAnnotations() | 返回该类所有的注解对象 |
● 获得类中构造器相关的方法
方法 | 用途 |
---|
getConstructor(Class…> parameterTypes ) | 获得该类中与参数类型匹配的公有构造方法 |
getConstructors() | 获得该类的所有公有构造方法 |
getDeclaredConstructor(Class…> parameterTypes) | 获得该类中与参数类型匹配的构造方法 |
getDeclaredConstructors() | 获得该类所有构造方法 |
● 获得类中方法相关的方法
方法 | 用途 |
---|
getMethod(String name, Class…> parameterTypes) | 获得该类某个公有的方法 |
getMethods() | 获得该类所有公有的方法 |
getDeclaredMethod(String name, Class…> parameterTypes) | 获得该类某个方法 |
getDeclaredMethods() | 获得该类所有方法 |
Field类
方法 | 用途 |
---|
equals(Object obj) | 属性与obj相等则返回true |
get(Object obj) | 获得obj中对应的属性值 |
set(Object obj, Object value) | 设置obj中对应属性值 |
getModifiers() | 获取该属性的修饰符(static、final等) |
Method类
方法 | 用途 |
---|
invoke(Object obj, Object… args) | 传递object对象及参数调用该对象对应的方法 |
Constructor类
方法 | 用途 |
---|
newInstance(Object… initargs) | 根据传递的参数创建类的对象 |
实战
在日常开发中反射用的最多的地方可能是将map转换为实体bean:
publicclass MapUtilByReflect {
public static Map beanToMap(Object object) throws IllegalAccessException {
Map<String, Object> map = new HashMap<String, Object>();
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
map.put(field.getName(), field.get(object));
}
return map;
}
publicstatic <T> T mapToBean(Map map, Class<T> beanClass) throws Exception {
T object = beanClass.newInstance();
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
int mod = field.getModifiers();
if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
continue;
}
field.setAccessible(true);
if (map.containsKey(field.getName())) {
field.set(object, map.get(field.getName()));
}
}
return object;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48