类的加载过程
当程序主动使用某个类时,如果该类还未被加载到内存中,则系统会通过几个步骤来对该类进行初始化。
- 类的加载(Load):将类的class文件读入内存,并为之创建一个java.lang.Class对象。此过程由类加载器完成。
- 类的链接(Link):将类的二进制数据合并到JRE中。
- 类的初始化(initialize):JVM负责对类进行初始化。
加载
将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后生成一个代表该类的java.lang.Class对象,作为方法区中类数据的访问入口(引用地址)。
所有需要访问和使用类数据只能通过这个Class对象,这个加载的过程需要类加载器参与。
链接
将Java类的二进制代码合并到JVM的运行状态之中的过程。
在这个阶段将为static类变量分配内存并设置其为默认初始值,这些内存将在方法区中进行分配。
将虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程。
初始化
执行类构造器()方法的过程,类构造器()方法由编译期自动收集类中所有变量的赋值动作和静态代码块中的语句合并产生。(类构造器是构造类信息的,不是构造该类对象的构造器)
类加载器ClassLoader
作用
将class文件字节码内容加载到内存中,并将其静态数据转换成方法区的运行时数据结构,然后在堆中生成代表这个类的Class对象,作为方法区中类数据的访问入口。
类缓存
类加载器可以按要求查找类,如果某类被加载到类加载器中,将维持加载一段时间,JVM垃圾回收机制可以回收这些Class对象。
- 引导类加载器:JVM自带的类加载器,负责Java平台核心库,用来装载核心类库,无法直接获取。
- 扩展类加载器:负责jre/lib/ext目录下的jar包或指定目录下的jar包装入工作库。
- 系统类加载器:最常用的加载器,负责java -classpath及其它目录下的类。
加载配置文件
Properties pros = new Properties();
//方式一:
//此时的文件默认在当前module下
FileInputStream fis = new FileInputStream("jdbc.properties");
pros.load(fis);
//然后可以通过pros的get方法读取配置
//方式二 此时的配置文件默认在当前module的src下
ClassLoader classLoader = test.class.getClassLoader();
InputStream is = classLoader.getResourceAsStream("jdbc.properties");
pros.load(is);
java.lang.Class类
概述
- 程序经过javac命令后,会生成一个或多个字节码文件(.class文件)
- 使用java命令对字节码文件进行解释运行。 相当于将某个字节码文件加载到内存中,此过程称为类的加载。
- 加载到内存中的类被称为运行时类,此运行时类,可以作为Class的一个实例。
- 换句话说,Class的实例就对应着一个运行时类。
- 加载到内存中的运行时类会缓存一定的时间,在此时间之内,可以通过不同的方式来获取此运行时类。
获取Class实例
public static void main(String[] args) throws ClassNotFoundException {
//前三种需要掌握
//方式一 调用运行时类的属性
Class cl1 = Person.class;
//方式二 通过运行时类的对象
Person p1 = new Person();
Class cl2 = p1.getClass();
//方式三 调用Class的静态方法:forName(String classpath)
//注意是完整路径 我这边完整的就是person
Class cl3 = Class.forName("Person");
//方式四 使用类的加载器:Classloader
ClassLoader classLoader = test.class.getClassLoader();
//注意是完整路径 我这边完整的就是person
Class cl4 = classLoader.loadClass("Person");
}
Class的newInstance()
空参构造器:1.便于利用反射创建运行时类的对象 2.便于子类继承时调用super()
Class cl1 = Person.class;
//Class的newInstance():调用此方法创建对应的运行时类的对象 内部调用的是空参构造器
//空餐构造器的访问权限通常设置为public
Person obj = (Person) cl1.newInstance();