反射

类的加载器

类的加载

当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。

l  加载

就是指将class文件读入内存,并为之创建一个Class对象。

任何类被使用时系统都会建立一个Class对象

l  连接

验证 是否有正确的内部结构,并和其他类协调一致

准备 负责为类的静态成员分配内存,并设置默认初始化值

解析 将类的二进制数据中的符号引用替换为直接引用(变量赋值)

l  初始化

就是我们以前讲过的初始化步骤

反射

Class

获取Class的三种方式:

Person p=new Person();//自定义类

//1.通过Object类中的getClass方法获取

Class c1=p.getClass();

//2.通过类名获取

Class c2=Person.class;

//3.通过完整的包名加类名获取

Class c3=Class.forName("com.oracle.d03.Person");

Constructor通过反射获取构造方法:

getConstructors()  //反射获取所有公共构造方法,返回个Constructor[]

getConstructor(Class<?>... parameterTypes)  //反射获取某个指定参公共构造方法,

newInstance(参数)  //通过反射获取的构造方法,创建对象,

例:

//获取某个公共的构造方法

    Constructor con1=c.getConstructor(String.class,int.class);

    //通过构造方法创建对象

    Object obj=con1.newInstance("000",2);

    System.out.println(obj);

getDeclaredConstructors()  //获取所有构造方法(包含私有)

getDeclaredConstructor(Class<?>... parameterTypes)  //获取某个指定参构造方法(包含私有)

setAccessible(boolean  flag)  //暴力反射,违反了面向对象的封装,所有不使用。

例:

//获取某个私有构造方法

Constructor cons=c.getDeclaredConstructor(String.class);

//暴力反射

cons.setAccessible(true);

Object obj=cons.newInstance("aaa");

Field通过反射获取成员变量

getFields() 获取所有公共变量

getField (String name) 获取某个公共成员变量

 

getDeclaredFields() 获取所有成员变量

getDeclaredField(String name) 获取某个成员变量

set(Object , 值)  方法,给获取的变量赋值

通过反射获取成员变量并赋值:

获取指定的成员变量(私有成员变量,通过setAccessible(boolean flag)方法暴力访问)

 

Field fields=c.getDeclaredField("age"); //获取指定成员变量

Person p=new Person(); //创建对象

fields.set(p, 18); //赋值

System.out.println(p);

Method通过反射获取成员方法:

getMethods() 获取所有public 修饰的方法

getMethods(String  name , Class<?>... parameterTypes)  获取某个成员方法

newInstance(参数)  通过反射获取的方法,创建对象,

newInstance()  Class类中方法,快速创建对象,只能调空参方法

invoke(Object obj , 参数)  调用当前Method代表的方法

例:

获取单个成员方法

    Method method=c.getMethod("sleep",String.class);

Object p = c.newInstance(); //创建对象

    method.invoke(p,"aa"); //调用

获取私有成员方法,步骤如下:

1. 获取Class对象

2. 获取构造方法

3. 通过构造方法,创建对象

4. 获取指定的方法

5. 开启暴力访问

6. 执行找到的方法

泛型擦除

程序编译后产生的.class文件中是没有泛型约束的,这种现象我们称为泛型的擦除。我们可以通过反射技术,来完成向有泛型约束的集合中,添加任意类型的元素

 

ArrayList<Integer> arr=new ArrayList<Integer>();

//通过ArrayList的字节码文件对象

Class c=arr.getClass();

//通过反射获取add方法

Method add=c.getMethod("add",Object.class);

add.invoke(arr, "aaa");

反射配置文件

读取Peoperties.txt文件中的数据,通过反射技术,来完成Person对象的创建

//明确配置文件的路径,IO字符输入流

FileReader fr=new FileReader("src/com/oracle/d02/config.Properties");

//创建Properties集合

Properties pro=new Properties();

//从配置文件中读取键值队到集合中

pro.load(fr);

//从集合中获取完整的包名加类名

String ClassName=pro.getProperty("ClassName");

//获取方法名

String MethodName=pro.getProperty("MethodName");

//通过反射获取字节码文件

Class c=Class.forName(ClassName);

//创建对象

Object obj=c.newInstance();

//获取方法

Method method=c.getMethod(MethodName);

//调用方法

method.invoke(obj);

原文地址:https://www.cnblogs.com/hhthtt/p/10632640.html