1.类加载:
加载-------》连接-----》初始化
加载:将class文件读入内存,并为之创建一个Class对象
连接:(1)验证:是否有正确的内部结构,并和其他类协调一致
(2)准备:负责为类的静态成员分配内存,并设置默认初始化值(Static随着类的加载而加载)
(3)解析:将类的二进制数据中的符号引用替换为直接引用(地址引用)
初始化:内存开辟空间等
类加载器:
Bootstrap ClassLoader 根类加载器
Extension ClassLoader 扩展类加载器
Sysetm ClassLoader 系统类加载器
2.反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制
就是通过class文件对象,去使用该文件中的成员变量,构造方法,成员方法。
要想这样使用,首先你必须得到class文件对象,其实也就是得到Class类的对象。
* Class类:
* 成员变量 Field
* 构造方法 Constructor
* 成员方法 Method
获取class文件对象的方式:
A:Object类的getClass()方法
B:数据类型的静态属性class
C:Class类中的静态方法public static Class forName(String className)
一般我们到底使用谁呢?
A:自己玩 任选一种,第二种比较方便
B:开发 第三种
因为第三种是一个字符串,而不是一个具体的类名。这样我们就可以把这样的字符串配置到配置文件中。
(1)通过反射获取构造方法并使用:
获取构造方法 getConstructors getDeclaredConstructors
创建对象 con.newInstance(“zhangsan", 20);
(2)通过反射获取成员变量并使用:
获取所有成员 getFields,getDeclaredFields
获取单个成员 getField,getDeclaredField
修改成员的值 set(Object obj,Object value) 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
(3)通过反射获取成员方法并使用:
获取所有方法 getMethods(public) getDeclaredMethods
获取单个方法 getMethod getDeclaredMethod
暴力访问 method.setAccessible(true);
// 获取字节码文件对象
Class c = Class.forName("cn.itcast_01.Person");
Constructor con = c.getConstructor();
Object obj = con.newInstance();
// 获取name并对其赋值
// NoSuchFieldException
Field nameField = c.getDeclaredField("name");
// IllegalAccessException
nameField.setAccessible(true);
nameField.set(obj, "林青霞");
// public Method getMethod(String name,Class<?>... parameterTypes)
// 第一个参数表示的方法名,第二个参数表示的是方法的参数的class类型
Method m1 = c.getMethod("show");
// public Object invoke(Object obj,Object... args)
// 返回值是Object接收,第一个参数表示对象是谁,第二参数表示调用该方法的实际参数
m1.invoke(obj); // 调用obj对象的m1方法
3.动态代理的实现---反射
代理模式:静态代理,动态代理,cglib代理
面试问题:
如何在一个ArrryList<Integer>里面添加一个String?(反射)
public class ArrayListDemo {
public static void main(String[] args) throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
// 创建集合对象
ArrayList<Integer> array = new ArrayList<Integer>();
// array.add("hello");
// array.add(10);
Class c = array.getClass(); // 集合ArrayList的class文件对象
Method m = c.getMethod("add", Object.class);
m.invoke(array, "hello"); // 调用array的add方法,传入的值是hello
m.invoke(array, "world");
m.invoke(array, "java");
System.out.println(array);
}
}
计算往arrayList里面add String需要的时间?(动态代理)