------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
反射
1. 反射的概念
反射就是对一个类的class文件的操作,将这个class文件看成是对象,进行解剖,从class文件中,直接获取方法运行
class文件是一个对象,描述类 java.lang.Class
构造方法是一个对象,描述类 java.lang.reflect.Constructor
成员变量是一个对象,描述类 java.lang.reflect.Field
成员方法是一个对象,描述类 java.lang.reflect.Method
获取class文件的对象,获取class文件中的构造方法并运行,获取class文件中的成员变量,修改值, 获取成员方法并运行
反射通过配置文件运行指定的类和方法
使用反射绕过编译期间的泛型检查,将不同的数据类型,存储到带有泛型的集合中
1. 获取字节码文件的对象的三种方式
l 使用对象获取
l 使用类名获取
l 使用Class类的静态方法forName()获取
2. 获取构造方法并运行
获取class文件对象
使用Class类提供的方法,获取构造方法
返回值就是Constructor类型 Constructor[] getCoConstructors() -- public权限
获取指定的构造方法,并运行 Constructor类型 getConstructor(Class...c)
传递响应的参数列表,获取指定的构造方法
运行构造方法 Constructor类有没有运行构造方法的方法
Object newInstance(Object...o)
Class类的方法获取私有构造方法
getDeclaredConstructors()获取所有私有构造方法,
返回数组
获取指定的构造方法getDeclaredConstructor(Class...c)
运行私有的,找到Constructor类的父类AccessibleObject,有一个方法setAccessible(true)
暴力访问,取消Java语言的访问期间检查
Classs类中有一个方法,可以直接运行构造方法运行,保证类有public空参构造
Object newInstance()
3. 反射获取成员变量并修改值
Class类中的方法 Field[] getFields()获取字节码文件中的所有公共成员变量
获取指定的成员变量修改值 Field getField(String name)传递变量的名字
Field类的方法修改成员变量值 set(Object obj,Object value)需要对象,新值
4. 反射获取成员方法并运行
Class类的方法,Method[] getMethods()获取公共的方法,包含继承的
获取指定的方法运行 Method getMethod(String name,Class...c)方法名,参数列表
运行方法,找Method类中,有没有运行方法的方法 invoke(Object obj,Object...value)
需要对象支持,传递的实际参数
5. 通过反射,读取配置文件运行
配置文件,键值对 IO读,加载到集合 Properties
package cn.itcast.reflecttest;
/*
* 使用反射 集合 配置文件 IO
* 实现读取配置文件运行
*/
import java.lang.reflect.*;
import java.io.*;
import java.util.*;
public class ReflectTest {
public static void main(String[] args) throws Exception{
//使用IO流,读取配置文件,加载到集合中
FileInputStream fis = new FileInputStream("c:\\config.properties");
//创建集合对象
Properties prop = new Properties();
prop.load(fis);
//获取键值对
for(int x = 1 ; x <= prop.size() / 2; x++){
String className = prop.getProperty("className"+x);
String methodName = prop.getProperty("methodName"+x);
//反射获取指定类的字节码文件对象
Class clazz = Class.forName(className);
Object obj = clazz.newInstance();
//获取方法
Method m = clazz.getMethod(methodName);
m.invoke(obj);
}
fis.close();
}
}
7.练习
反射绕过编译器检查,泛型的擦除
package cn.itcast.reflecttest;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
/*
* 反射绕过编译器检查
* 泛型的擦除
*/
public class ReflectGeneric {
public static void main(String[] args) throws Exception{
ArrayList<String> array = new ArrayList<String>();
array.add("eh");
array.add("qh");
//获取ArrayList类的class文件对象
Class clazz = array.getClass();
//直接获取ArrayList的方法add
Method m = clazz.getMethod("add", Object.class);
m.invoke(array, false);
m.invoke(array, 123);
System.out.println(array);
/*
Iterator it = array.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
for(String s : array){
System.out.println(s);
}*/
}
}