黑马程序员---java高新技术----反射技术

时间:2023-02-17 22:44:17

------<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 使用类名获取

使用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);
}*/
}
}