首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Java中处理静态final和static成员?

如何在Java中处理静态final和static成员?
EN

Stack Overflow用户
提问于 2019-02-19 03:26:29
回答 1查看 0关注 0票数 0

我已经在Stack Overflow和Web上的其他地方看到了一些关于静态变量的事情。但是答案对我来说并不清楚。当我认为我找到答案时,其他一些来源与该陈述相矛盾(或者至少,我认为它确实如此)。

我的问题可以分为两个不同的问题:

  • 在Java中,是在运行时或编译时创建的类的静态变量吗?
  • 在Java中,是在运行时或编译时创建的类的最终静态变量?

我的意思是编译时间与运行时间:

  • 编译时:编译源代码时(所以当创建.class文件时)
  • 运行时间:程序实际运行时

某些代码仅用于此问题的目的:

代码语言:javascript
复制
// MyClass.java
public class MyClass {
    public static int instances;
    public final static double PI = 3.14159265359

    public MyClass() {
        instances++;
    }
    // ...
}

// Main.java ; version 1
public 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 2
public 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.14159265359
2

如果在运行时创建静态最终静态变量,则在Main的第一个版本中,都不会创建MyClass类的静态变量(实例和PI)。但我希望最终的静态变量PI将在编译时创建(因此它将“嵌入”.class文件中),因为我认为这会有更好的性能(无论类如何发生) MyClass,PI将始终为3.14159265359,因此它也可以放在二进制文件中)。 这可能与静态变量相同,但它可能会在整个程序中发生变化。

EN

回答 1

Stack Overflow用户

发布于 2019-02-19 12:56:47

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

如果创建的意思是分配和初始化,那么在编译时不会在Java中“创建”变量。它们都是在运行时创建的。无论他们是staticstatic final有没有关系,当他们得到分配。

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

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

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

代码语言:javascript
复制
private long timeoutMillis = 10 * 24 * 3600 * 1000;

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

代码语言:javascript
复制
private static final String DEFAULT_HEADER = "A long headers that is " +
   "broker into two lines\n";

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

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100008953

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档