Java 静态最终变量和静态初始值设定项块
我创建了一个包含以下内容的类:Java 静态最终变量和静态初始值设定项块,java,Java,我创建了一个包含以下内容的类: static final变量 static带有System.out.println()语句的初始值设定项块 如果我从另一个类调用static final变量,则不会执行static块 据我所知,静态初始化程序块在类加载到内存中时执行 在这种情况下,内存级别发生了什么 类是否未加载到内存中?如果不是,其他类从哪里获取最终静态变量的地址 情况1:静态块不执行 class Test2 { static final int a = 20; static
static final
变量static
带有System.out.println()语句的初始值设定项块
static final
变量,则不会执行static
块
据我所知,静态
初始化程序块在类加载到内存中时执行
在这种情况下,内存级别发生了什么
类是否未加载到内存中?如果不是,其他类从哪里获取最终静态变量的地址
情况1:静态
块不执行
class Test2 {
static final int a = 20;
static {
System.out.println("one");
}
}
情况2:静态
块不执行
输出
class Test {
public static void main(String[] args) {
System.out.println(Test2.a);
}
}
- 案例1:
20
- 案例2:
one
20
那么,在这两个层面都发生了什么
静态final字段是编译时常量,其值为
硬编码到目标类中,不引用其
起源
因此,主类不会触发类的加载
包含字段
因此,不会执行该类中的静态初始值设定项
请参见从定义中删除final
的魔术。您将看到静态初始化器正在执行我猜您的字段是基元类型或字符串
,并使用编译时常量表达式初始化
对于使用常量表达式初始化的静态final字段(并且只有这样的字段)——任何引用该字段的代码都将在其中烘焙常量值,而不是通过静态字段进行初始化,这将导致类初始化。“常量表达式”部分很重要。我们可以通过一个小测试应用程序看到这一点:
class Fields {
public static final String CONSTANT = "Constant";
public static final String NON_CONSTANT = new String("Non-constant");
static {
System.out.println("Initializing");
}
}
public class Test {
public static void main(String arg[]) {
System.out.println(Fields.CONSTANT);
System.out.println(Fields.NON_CONSTANT);
}
}
输出为:
Constant
Initializing
Non-constant
访问常量字段不需要初始化,但访问非常量字段需要初始化。使用非final字段也会产生同样的效果:它基本上不再作为常量计算
关于“thisaconstant”的信息被烘焙到声明字段的类中。例如,使用javap-c字段
我们可以看到两个字段:
public static final java.lang.String CONSTANT;
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
ConstantValue: String Constant
public static final java.lang.String NON_CONSTANT;
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
请注意常量
字段元数据的常量值
部分,该部分在非常量
字段元数据中缺失
有关什么构成常量表达式的详细信息,请参见
指定初始化类的时间:
类或接口类型T将在第一次出现以下任一情况之前立即初始化:
- T是一个类,并且创建了T的一个实例
- T是一个类,调用由T声明的静态方法
- 分配了一个由T声明的静态字段
- 使用由T声明的静态字段,该字段不是常量变量(§4.12.4)
- T是一个顶级类(§7.6),执行嵌套在T(§8.1.3)中的assert语句(§14.10)
(我的重点。)发布您的代码!不知道你的问题是什么。您能提供一个示例代码吗?描述代码几乎总是不如仅仅显示它—理想情况下是一个简短但完整的程序来演示问题。您也可以发布输出吗?这实际上不是全部内容—它不适用于所有静态最终字段,正如您的第一点所暗示的那样。请参阅我的答案了解更多详细信息。实际上,我是在代码中第一次出现类名时阅读的。该时间类加载到内存中。是这样吗?如果加载类时出错?@deepak:这是错误的,正如您所看到的-有关初始化类的详细信息,请参阅我的编辑。第12.4.1节中的项目符号3可能会让人相信常量
被赋值为“常量”,从而导致类初始化,但该字段被初始化,因此项目符号3不适用。可以帮助区分字段初始化和赋值。顺便说一句,同一部分中的项目符号5已经不正常了。@Ichiro:修复了项目符号。我会留下你的评论来为自己说话。
public static final java.lang.String CONSTANT;
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
ConstantValue: String Constant
public static final java.lang.String NON_CONSTANT;
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL