一、类的加载
当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化
加载
就是将class文件读入内存,并为之创建一个Class对象
任何类被使用时系统都会建立一个Class对象
连接
验证 是否有正确的内部结构,并和其他类协调一致
准备 负责为类的静态成员分配内存,并设置默认初始化值
解析 将类的二进制数据中的符号引用替换为直接引用
** 初始化**
二、类初始化时机
创建类的实例
访问类的静态变量 ,或者为静态变量赋值
调用类的静态方法
使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
初始化某个类的子类
直接使用java.exe命运来运行某个主类
三、类加载器
负责将.class文件加载到内存中,并为之生成对应的Class对象。
虽然我们不需要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行。
类加载器的组成
Bootstrap ClassLoader 根类加载器
Extension ClassLoader 扩展类加载器
System ClassLoader 系统类加载器
四、反射
java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够任意调用它的任意一个方法和属性;
这种动态获取的信息以及动态调对象的方法的功能称为java语言的反射机制。
想要解剖一个类,必须先要获取到该类的字节码文件对象。
而解剖使用的就是Class类中的方法。
所以先要获取到每一个字节码文件对应的Class类型的对象
五、通过反射获取构造方法
类中的成员:
成员变量:Field
构造方法:Constructor
成员方法:Method
获取类的Class对象
//方式1:在对象已经存在的前提下获取
Student student = new Student("xiaohei",18,"anhui","nan");
Class<? extends Student> studentClass = student.getClass();
//方式2:通过类名.class的方式获取 在同步锁的场景下用的比较多
Class<Student> studentClass2 = Student.class;
System.out.println(studentClass2==studentClass);
//方式3:最常用的方式 利用Class类中的静态方法
//static Class<?> forName(String className) 传入的是类的路径
Class<?> studentClass = Class.forName("com.shujia.day17.Student");
Constructor<T> getConstructor(Class<?>... parameterTypes) 只能某一个获取公共的构造方法-
返回一个 Constructor对象,该对象反映 Constructor对象表示的类的指定的公共 类函数。

Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 获取某一个任意权限修饰符的构造方法

Constructor<?>[] getDeclaredConstructors() 获取所有的任意权限修饰符的构造方法

使用获取到的公共的构造方法
Constructor<?> constructor = studentClass.getConstructor(String.class, int.class, String.class, String.class);
T newInstance(Object... initargs)
Object o = constructor.newInstance("xxx", 18, "xxx", "男");
System.out.println(o);
使用获取到的私有的构造方法创建对象
Constructor<?> declaredConstructor = studentClass.getDeclaredConstructor();
绕过权限校验,暴力访问
declaredConstructor.setAccessible(true);
Object o = declaredConstructor.newInstance();
System.out.println(o);
六、通过反射获取成员变量并赋值
获取类的字节码文件对象
Class<?> studentClass = Class.forName("com.shujia.day17.Student");
Field getField(String name) 只能通过变量名获取公共的成员变量----------------------------------------------
Field gender = studentClass.getField("gender");
System.out.println(gender);
Field[] getFields() 只能获取所有公共的成员变量 ---------------------------------------------
Field[] fields = studentClass.getFields();
System.out.println(Arrays.toString(fields));
Field getDeclaredField(String name) 通过变量名获取任意权限修饰符的成员变量 ------------------------
Field name = studentClass.getDeclaredField("name");
System.out.println(name);
Field[] getDeclaredFields() 获取所有成员变量 ---------------------------------------------
Field[] declaredFields = studentClass.getDeclaredFields();
System.out.println(Arrays.toString(declaredFields));

七、通过反射获取成员方法并赋值
获取类的字节码文件对象
Class<?> studentClass = Class.forName("com.shujia.day17.Student");
Method getMethod(String name, Class<?>... parameterTypes) 只能获取公共的成员方法,当前和父类的公共都可以----------------------
Method fun4 = studentClass.getMethod("fun4");
System.out.println(fun4);
Method fun5 = studentClass.getMethod("fun5", String.class);
System.out.println(fun5);
Method fun1 = studentClass.getMethod("wait");
System.out.println(fun1);
getMethods 获取当前类及其父类中的所有公共的成员方法------------------------------------------
Method[] methods = studentClass.getMethods();
System.out.println(Arrays.toString(methods));
getDeclaredMethod() 获取任意一个权限修饰符的成员方法----------------------------------------
Method fun1 = studentClass.getDeclaredMethod("fun1");
System.out.println(fun1);
getDeclaredMethods 获取当前类中的所有成员方法----------------------------------------
Method[] declaredMethods = studentClass.getDeclaredMethods();
System.out.println(Arrays.toString(declaredMethods));
