一、使用方式
1、主动使用
2、被动使用
所用的Java虚拟机实现必须在每个类或者接口被Java程序“首次主动使用”时,才初始化它们
二、主动使用
1、创建类的实例(new)
2、访问某个类或者接口的静态变量,或者对静态赋值
3、调用类的静态方法【2和3的本质是一样的,getStatic、putStatic、invokeStatic 助记符】
4、反射(Class.forName("com.test.child"))
5、初始化一个类的子类
6、Java虚拟机启动时被标记为启动类的类(包含main方法的类)
7、JDK 1.7开始提供动态语言支持
Java.lang.invoke.MethoHhandle实例的解析结果,没有初始化,就去初始化。
* 其他都是被动使用,都不会导致类的初始化(第三个阶段呦)
三、概念
1、类的加载:将类的.class 文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在内存中创建一个java.lang.Class 对象(规范并未说明Class对象位于哪里,HotSpot 虚拟机将其放在了方法区中)用来封装类在方法区内的数据结构
四、加载.class文件的方式
1、从本地系统中直接加载
2、通过网络下载.class文件
3、从 zip、jar等归档文件中加载.class 文件
4、从转悠数据库提取.class文件(用的很少)
5、将Java源文件动态编译为.class文件(动态代理,运行期才生成)
jsp(html+Java)----》servelet(Java代码)----》class文件
五、被动使用的例子:
package com.shengsiyuan.jvm.classloder;
/*
* 对于静态字段,只有直接定义了该字段的类才会初始化
* 即只初始化该静态字段所在的类,当然包括他的父类,没有子类
* 可以分别main函数中的两行代码,在一起运行两行代码,不一样,因为初始化仅初始话一次
* My Parent1 static block
hello world
My Child1 static block
welcome
* */
public class MyTest1 {
public static void main(String[] args) {
System.out.println(MyChild1.str);//只有父类的被初始化。
/*
My Parent1 static block
hello world
*/
//System.out.println(MyChild1.str2);
/*
My Parent1 static block
My Child1 static block
welcome
*/
}
}
//静态代码块在加载的时候被执行
class Myparent1{
public static String str ="hello world";
static {
System.out.println("My Parent1 static block");
}
}
//初始化子类,父类一定被执行
class MyChild1 extends Myparent1{
public static String str2 ="welcome";
static {
System.out.println("My Child1 static block");
}
}
坚持
本文深入探讨Java类加载过程,包括主动使用与被动使用场景,类初始化时机,以及类加载的不同方式。通过具体代码示例,展示静态字段访问如何影响类的加载与初始化。
235

被折叠的 条评论
为什么被折叠?



