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需要的时间?(动态代理)
