一、反射解析
java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
二、JAVA反射机制提供了什么功能
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判段任意一个类所具有的成员变量和方法
- 在运行时调用任一个对象的方法
- 在运行时创建新类对象
三、反射机制实现原理
Java程序在运行时,Java运行时系统会同一生成一个java.lang.Class类,该Class对象记载了该类的字段,方法等等信息。虚拟机通常使用运行时类型信息选准正确方法去执行。 也就是说,ClassLoader找到了需要调用的类时,就会加载它,然后根据.class文件内记载的类信息来产生一个与该类相联系的独一无二的Class对象。就是根据内存中存在的该Class类所记载的信息(Class对象应该和我所了解的其他类一样会在堆内存内产生、消亡)来进行。
Class对象都是jvm产生的,而且,更伟大的是,基于这个基础,java实现了反射机制。
四、获取Class对象的三种方式
通过Object类的getClass()方法
Class c1 = new String("").getClass();
通过Class类的静态方法——forName()来实现
Class c2 = Class.forName("MyObject");
如果T是一个已定义的类型的话,在java中,它的.class文件名:T.class就代表了与其匹配的Class对象
Class c3 = Manager.class;
Class c4 = int.class;
Class c5 = Double[].class;
五、常见方法解析
- String getName/getSimpleName():获取对象实例的类名
- Object newInstance():该方法可以根据某个Class对象产生其对应类的实例。需要强调的是,它调用的是此类的默认无参构造方法。如果该对象没有重写无参构造函数,则会出现异常。
- Field[] getDeclaredField()/getField():获取当前类中的所有属性/获取当前类以及继承的属性
- Method[] getMethods()/getDeclaredMethods() :获取当前类中的所有属性/获取当前类以及继承的属性
- Method getMethod(String methodName):根据方法名称返回方法对象
- Class<?> getSuperClass():返回该类的父类。
- isArray()判断对象是否是一个数组对象
- Annotation getAnnotation(Class<Annotatin> annotation):返回当前类的注解类
- Constructors[] getConstructors():放回该类的所有构造函数
- Class<?>[] getInterfaces() :返回该类的所有实现接口
六、通过反射获取类的架构
static void test(Class<?> clazz){
System.out.println("类名:"+clazz.getSimpleName());
System.out.println("包名:"+clazz.getPackage());
Field[] fields = clazz.getDeclaredFields();
for (Field f : fields) {
System.out.println("属性名:"+f.getName()+",类型:"+f.getType().getName());
}
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
System.out.println("修饰词:"+Modifier.toString(method.getModifiers())+" 方法名:"+method.getName());
}
}
七、通过反射操作对象的属性
/**
* 获取属性值
* @param o
* @param field
* @return
*/
public static Object getProperty(Object o, String field) {
try {
Field f = o.getClass().getDeclaredField(field);
f.setAccessible(true);//设置该属性是可访问的,这样就可以访问private,protect类型的值
return f.get(o);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 添加屬性值
*
* @param o
* @param field
* @param value
*/
public static void setProperty(Object o, String field, Object value) {
try {
Field f = o.getClass().getDeclaredField(field);
f.setAccessible(true);
f.set(o, value);
} catch (Exception e) {
e.printStackTrace();
}
}
八、通过反射操作对象的方法
static void testCallMethod(Class<?> clazz){
try {
Method mehtod=clazz.getMethod("sayHello", String.class);
//设置方法的可访问性,这样就可以访问类中的方法了
mehtod.setAccessible(true);
mehtod.invoke(clazz.newInstance(), "hello world");
} catch (Exception e) {
e.printStackTrace();
}
}
public void sayHello(String str){
System.out.println(str);
}