关于类加载过程中静态常量的赋值

在类加载过程中的准备阶段中,除了对静态变量分配内存并设置零值之外,是不是还要对静态常量进行赋值?
此外常量的赋值是在哪个阶段完成的?编译阶段吗?

阅读 4.7k
3 个回答

是的,而且是初始化为确定值,原文

准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存
都将在方法区中进行分配。这个阶段中有两个容易产生混淆的概念需要强调一下,首先,这
时候进行内存分配的仅包括类变量(被static修饰的变量),而不包括实例变量,实例变量将
会在对象实例化时随着对象一起分配在Java堆中。其次,这里所说的初始值“通常情况”下是
数据类型的零值,假设一个类变量的定义为:

public static int value=123;
那变量value在准备阶段过后的初始值为0而不是123,因为这时候尚未开始执行任何Java
方法,而把value赋值为123的putstatic指令是程序被编译后,存放于类构造器<clinit>()方
法之中,所以把value赋值为123的动作将在初始化阶段才会执行。表7-1列出了Java中所有基
本数据类型的零值。

上面提到,在“通常情况”下初始值是零值,那相对的会有一些“特殊情况”:如果类字段
的字段属性表中存在ConstantValue属性,那在准备阶段变量value就会被初始化为
ConstantValue属性所指定的值,假设上面类变量value的定义变为:

public static final int value=123;

编译时Javac将会为value生成ConstantValue属性,在准备阶段虚拟机就会根据
ConstantValue的设置将value赋值为123。

类加载分为三个阶段:

  • 加载,双亲委派方式把class文件加载到内存
  • 链接,验证class内容,并把静态变量赋予默认值,解析符号引用为直接引用
  • 初始化,加载类初始化方法,静态变量赋值为定义的初始值

准备阶段静态变量赋值初始默认值。
初始化阶段对静态变量进行赋值。
常量编译阶段就已经赋值了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题