一、类加载器

1.类加载

        当程序要使用某个类时,如果该类未被加载到内存,则系统会通过类的加载类的连接类的初始化三个步骤来对类进行初始化。如果不出意外情况的话,JVM会连续完成这三个步骤,所以一般把这三步统称为类加载或类初始化
(1)类的加载:
        将class文件读入内存,并为之创建一个java.lang.Class对象
(2)类的连接:
    1)验证阶段:检验被加载的类是否有正确的内部结构,并和其他的类协调一致
    2)准备阶段:为类的变量分配内存,并设置默认初始化值
    3)解析阶段:将类的二进制数据中的符号引用替换为直接引用
(3)类的初始化:
        主要是对类变量进行初始化
    1)类的初始化步骤:
        ①假如类还未被加载和连接,则程序先加载和连接该类;
        ②假如该类的直接父类还未被初始化,则先初始化其直接父类;
        ③假如类中有初始化语句,则系统依次执行其初始化语句。
【tips】:第②步中,系统对直接父类的初始化也遵循以上三步。
    2)类的初始化时机:当系统首次执行以下操作时,会对类进行初始化:
        ①创建类的实例对象;
        ②调用类方法(类的静态方法);
        ③访问类或接口的类变量,或者为该类变量赋值;
        ④使用反射方式强制创建某个类或接口对应的java.lang.Class对象;
        ⑤初始化某个类的子类;  
        ⑥直接使用java.exe命令来运行某个主类。

2.类加载器

(1)作用:将.class文件加载到内存,并生成对应的java.lang.Class对象
(2)JVM的类加载机制
    1)全盘负责:
    2)父类委托:
    3)缓存机制:
(3)ClassLoder类:类加载器。Java运行时具有以下三种内置类加载器
    1)BootstrapClassLoder:是JVM的内置类加载器,通常表示为null ,是所有类加载器的祖先;
    2)PlatformClassLoader:平台类加载器,可以看到所有平台类 。平台类包括由平台类加载器或其祖先定义的Java SE平台API,其实现类和JDK特定的运行时类;
    3)SystemClassLoader:系统类加载器 (又叫应用程序类加载器),与平台类加载器不同。 系统类加载器通常用于定义应用程序类路径,模块路径和JDK特定工具上的类。 
【tips】:三者的继承关系:SystemClassLoader extends PlatformClassLoader extends BootstrapClassLoder
    ClassLoder中的常用方法:
static ClassLoader getSystemClassLoader()
返回用于委派的系统类加载器。
ClassLoader getParent()
返回其父类加载器。

二、反射

1.Java的反射机制

        在程序运行时可以获取一个类的变量和方法信息,并且可以通过这些获取到的信息来创建对象、调用方法,这种动态获取程序信息及动态调用对象的功能称为Java的反射机制。

2.Class类

        在通过反射使用一个类之前,需要先获取该类的字节码文件对象(即类型为Class的对象)。
        获取Class类对象的三种方式:
(1)使用类的class属性来获取Class对象(.class);
//使用类的class属性来获取Class类对象
Class<Student> studentClass = Student.class;
【tips】:基本数据类型也可以通过.class获取对应的Class对象:int.class。
(2)调用类的实例对象的getClass()方法来获取Class类对象;
//调用类的实例对象的getClass()方法来获取Class类对象
Student s = new Student();
Class<? extends Student> studentClass2 = s.getClass();
(3)使用Class类中的静态方法forName(String className),该方法需要传入类的完整路径。
//使用Class类中的静态方法forName(String className)
Class<?> studentClass3 = Class.forName("getClass.Student");

3.反射获取类的构造方法并使用

(1)获取构造方法的方法:
Constructor<T> getConstructor(Class<?>... parameterTypes)
返回一个Constructor对象,该对象表示由该Class对象表示的类的指定public构造方法
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
返回一个 Constructor对象,该对象表示由该Class对象表示的类或接口的指定构造方法(private、public、默认的都可以)。
Constructor<?>[] getConstructors()
返回一个包含Constructor对象的数组, Constructor对象表示由该 Class对象表示的类的所有public构造方法
Constructor<?>[] getDeclaredConstructors()
返回表示由该Class对象表示的类的所有构造方法的Constructor对象的数组。
(2)使用获取到的构造方法创建类的对象:
T newInstance(Object... initargs)
使用由此Constructor对象表示的构造方法和指定的初始化参数来创建类的对象
【tips】:暴力反射:使用void setAccessible(boolean flag)方法,当flag为true时,可以取消访问检查(即私有也能访问了)。

4.反射获取类的成员变量并使用

(1)获取成员变量的方法:
Field getField(String name)
返回一个Field对象,该对象表示由该Class对象表示的类或接口的名为name的public成员变量
Field getDeclaredField(String name)
返回一个Field对象,该对象表示由该Class对象表示的类或接口的名为name的成员变量(private、public、默认的都可以)
Field[] getFields()
返回一个包含Field对象的数组,Field对象表示由该Class对象表示的类或接口的所有public成员变量
Field[] getDeclaredFields()
返回一个Field对象的数组,反映了由该Class对象表示的类或接口声明的所有成员变量
(2)使用获取到的成员变量:
void set(Object obj, Object value)
将指定的对象参数中由此Field对象表示的成员变量值设置为value。

5.反射获取类的成员方法并使用

(1)获取成员方法的方法
Method getMethod(String name, Class<?>... parameterTypes)
返回单个成员方法对象。
Method getDeclaredMethod(String name, Class<?>... parameterTypes)
返回单个成员方法对象。
Method[] getMethods()
返回一个包含Method对象的数组,Method对象代表由该Class对象表示的类或接口的所有公共成员方法包括继承的
Method[] getDeclaredMethods()
返回一个包含 方法对象的数组, Method对象代表由该Class对象表示的类或接口的所有成员方法,但不包括继承方法
(2)调用获取到的成员方法:
Object invoke(Object obj, Object... args)
调用obj对象的成员方法,参数是args,返回值类型是Object。