1. 反射概述(反射是框架设计的灵魂)
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
要想解剖一个类,必须先获取该类的字节码文件对象,而解剖使用的就是Class类中的方法,所以要先获取到每一个字节码文件对应的Class类型的对象。
2. 获取字节码文件的三种方式:
Person p = new Person();(三个clazz是同一个字节码文件,运行期间,一个类只有一个Class对象产生)
A. getClass静态加载
-->Class clazz = p.getClass();
B. 静态属性class,锁对象
-->Class clazz = Person.class;当作静态方法的锁对象;
C. Class类中静态方法forName()读取配置文件(常用)
-->Class clazz = Class.forName(“带包名的类路径”);读取配置文件。
3. 通过Class对象可以获取某个类中的:构造方法、成员变量、成员方法;并访问成员;
A.获取构造方法:
1). 批量的方法:
public Constructor[] getConstructors():所有"公有的"构造方法
public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
2). 获取单个的方法,并调用:
public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:
public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;
3). 调用构造方法:
Constructor-->newInstance(Object... initargs)
B. 获取成员变量并调用:
1). 批量的
Field[] getFields():获取所有的"公有字段"
Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有;
2). 获取单个的:
public Field getField(String fieldName):获取某个"公有的"字段;
public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)
f.setAccessible(true);//暴力反射,解除私有限定
3). 设置字段的值:
Field --> public void set(Object obj,Object value):
参数说明:1.obj:要设置的字段所在的对象;
2. value:要为字段设置的值;
C. 获取成员方法并调用:
1). 批量的:
public Method[] getMethods():获取所有"公有方法";(包含了父类的方法也包含Object类)
public Method[] getDeclaredMethods():获取所有的成员方法,包括私有的(不包括继承的)
2). 获取单个的:
public Method getMethod(String name,Class<?>... parameterTypes):
参数:1.name : 方法名;
2.Class ... : 形参的Class类型对象
public Method getDeclaredMethod(String name,Class<?>... parameterTypes)
3). 调用方法:Method --> public Object invoke(Object obj,Object... args):
参数说明:1.obj : 要调用方法的对象;
2. args:调用方式时所传递的实参;
D. ArrayList<Integer>的一个对象,在这个集合中添加一个字符串数据,如何实现?
* 泛型只在编译期有效,在运行期间会被擦除掉