为了账号安全,请及时绑定邮箱和手机立即绑定

Java 中如何处理静态最终成员和静态成员?

Java 中如何处理静态最终成员和静态成员?

MMTTMM 2022-06-23 19:31:58
我已经在 Stack Overflow 和网络上的其他地方看到了一些关于静态变量的内容。但是,我并不清楚答案。当我认为我找到了答案时,其他一些来源与该陈述相矛盾(或者至少,我认为确实如此)。例如:m0bius 告诉我们static 关键字在 Java 中是如何工作的?(在“何时创建此副本[编辑静态变量]?”部分中)静态变量是在运行时创建的。但是,如果我检查https://en.wikipedia.org/wiki/Class_variable(“静态成员变量和静态成员函数”部分),它会告诉我在某些语言中会发生相反的情况,而在其他语言中也会发生同样的情况。我的问题可以分为两个不同的问题:在Java中,类的静态变量是在运行时还是在编译时创建的?在Java中,类的最终静态变量是在运行时还是在编译时创建的?我的意思是编译时间与运行时间:编译时间:编译源代码的时间(即创建 .class 文件的时间)运行时间:程序实际运行的时间一些代码仅用于此问题:// MyClass.javapublic class MyClass {    public static int instances;    public final static double PI = 3.14159265359    public MyClass() {        instances++;    }    // ...}// Main.java ; version 1public class Main {    public static void main(String args[]) {        System.out.println("I am doing nothing with MyClass");    }}// OUTPUT: I am doing nothing with MyClass// Main.java ; version 2public class Main {    public static void main(String args[]) {        System.out.println("PI = " + MyClass.PI);        MyClass obj1 = new MyClass();        MyClass obj2 = new MyClass();        System.out.println("instances = " + MyClass.instances);    }}OUTPUT:3.141592653592如果静态变量和最终静态变量都在运行时创建,那么在 Main 的第一个版本中,MyClass 类的两个静态变量(实例和 PI)都不会创建。但我有点期望最终的静态变量 PI 将在编译时创建(因此它将被“嵌入”在 .class 文件中),因为我认为这会有更好的性能(无论类发生什么情况MyClass,PI 将始终为 3.14159265359,因此最好将其放入二进制文件中)。这可能与静态变量相同,但它可能会在整个程序中发生变化。
查看完整描述

1 回答

?
莫回无

TA贡献1865条经验 获得超7个赞

在Java中,类的静态变量是在运行时还是在编译时创建的?

Java 在编译时没有“创建”变量,如果创建意味着分配和初始化。它们都是在运行时创建的。它们是否static何时分配static final无关。

但我有点期望最终的静态变量 PI 将在编译时创建(因此它将被“嵌入”在 .class 文件中),因为我认为这会有更好的性能......

这不是它在 Java 中的工作方式。当类文件被“编译”时,它们实际上主要是被编码的。肯定有一些工作已经完成,但我们认为编译的超大比例(就 C 等语言而言)是在运行时发生的。当我们查看优化和内联时尤其如此。

如果可能的话,编译器会做一些前期工作,例如能够提前预先计算字段(静态或实例)的值。例如,如果你像下面这样定义你的字段,那么乘法将在编译时完成:

private long timeoutMillis = 10 * 24 * 3600 * 1000;

对于 s 也是如此,String如果可能,编译器会将常量字符串附加在一起。以下内容在运行时不使用 a StringBuilder,而是String在编译时创建一个:

private static final String DEFAULT_HEADER = "A long headers that is " +   "broker into two lines\n";

但是,在这两种情况下,字段( thelong timeoutMillis和 the String DEFAULT_HEADER)的分配和初始化都是在运行时完成的。

如果静态变量和最终静态变量都在运行时创建,那么在 Main 的第一个版本中,MyClass 类的两个静态变量(实例和 PI)都不会创建。

在您的示例中,第一次加载static类时分配和初始化字段(final或不) 。因此,在您的第一个or字段中,永远不会像您提到的那样创建。在你的第二个例子中。一旦被引用,类文件将被加载并创建字段。MaininstancesPI staticMyClassstatic


查看完整回答
反对 回复 2022-06-23
  • 1 回答
  • 0 关注
  • 130 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号