JVM(Java虚拟机)并不是在工程启动时就将所有类都加载到内存中,而是采用按需加载的方式,即在需要使用某个类时才会加载该类。
JVM的类加载机制包括了加载、验证、准备、解析和初始化五个阶段。当Java程序运行时,JVM会根据需要,通过类加载器查找并加载类的字节码数据。这些数据可以来源于本地文件系统、网络、jar包等多种途径。加载完成后,JVM会将类的二进制数据转换成方法区内部的数据结构,并生成一个代表该类的Class对象,存放在JVM的堆内存中。这个Class对象包含了类的各种信息,可以用于创建类的实例、获取类的方法和字段等操作。
在加载类的过程中,JVM还会遵循双亲委派机制。这意味着,当一个类加载器需要加载一个类时,它会首先请求其父类加载器尝试加载。如果父类加载器无法加载该类,那么当前类加载器才会尝试自己加载。这种方式有助于避免类的重复加载,并确保Java核心类库的安全性。
至于类的初始化,则是在类被首次主动使用时执行的。这包括创建类的实例、调用类的静态方法或访问类的静态字段等情况。在初始化阶段,JVM会执行类的初始化代码,包括静态变量的赋值和静态代码块的执行等操作。
因此,可以说JVM是在需要使用某个类时,才会将该类加载到内存中并进行初始化。这种方式有助于提高Java程序的运行效率和响应速度。
静态代码块(Static Block)在Java中是在类被首次加载到JVM(Java虚拟机)时执行的,而不是在整个工程启动时。这意味着,只有当该类被首次使用(例如,通过创建类的实例、访问类的静态成员或静态方法)时,静态代码块才会被执行。
这里有几点需要注意:
类加载:类加载是JVM将类的字节码转换成运行时数据结构,并初始化类的过程。当类被加载时,它的静态代码块会按顺序执行(如果有多个静态代码块的话)。
首次使用:首次使用类是指JVM首次需要该类信息的时候。例如,当你创建一个类的实例(new MyClass()),访问类的静态变量或方法(MyClass.staticVar 或 MyClass.staticMethod()),或者反射地引用类(Class.forName("MyClass"))时。
执行顺序:静态代码块的执行顺序是按照它们在类中出现的顺序进行的。如果有多个静态代码块,它们会按顺序依次执行。此外,静态代码块在静态变量初始化之后但在静态方法执行之前执行。
只执行一次:静态代码块在类生命周期内只执行一次,即使该类被多次使用。
下面是一个简单的例子来说明静态代码块的执行:
java
java
public class StaticBlockExample {
static {
System.out.println("Static block executed!");
}
public static void main(String[] args) {
System.out.println("Main method started!");
new StaticBlockExample();
new StaticBlockExample(); // 静态代码块不会再次执行
}
}
输出将是:
html
Static block executed!
Main method started!
在这个例子中,当StaticBlockExample类被首次使用时(即当main方法开始执行时),静态代码块被执行了一次,并且只执行了一次,即使随后创建了该类的两个实例。