我已经在Stack Overflow和Web上的其他地方看到了一些关于静态变量的事情。但是答案对我来说并不清楚。当我认为我找到答案时,其他一些来源与该陈述相矛盾(或者至少,我认为它确实如此)。
我的问题可以分为两个不同的问题:
我的意思是编译时间与运行时间:
某些代码仅用于此问题的目的:
// 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,因此它也可以放在二进制文件中)。 这可能与静态变量相同,但它可能会在整个程序中发生变化。
发布于 2019-02-19 12:56:47
在Java中,是在运行时或编译时创建的类的静态变量吗?
如果创建的意思是分配和初始化,那么在编译时不会在Java中“创建”变量。它们都是在运行时创建的。无论他们是static
或static final
有没有关系,当他们得到分配。
但我希望最终的静态变量PI将在编译时创建(因此它将“嵌入”.class文件中)因为我认为这会有更好的性能......
这不是它在Java中的工作方式。当类文件被“编译”时,它们实际上大部分都被编码。肯定有一些工作已经完成,但我们对编译的看法(就像C这样的语言而言)的超大比例正在运行时发生。当我们研究优化和内联时尤其如此。
编译器确实做了一些前期工作,例如能够提前预先计算字段的值(静态或实例)。例如,如果您像下面这样定义字段,那么乘法将在编译时完成:
private long timeoutMillis = 10 * 24 * 3600 * 1000;
对于String
编译器将尽可能将常量字符串附加在一起的s 也是如此。以下内容不在StringBuilder
运行时使用,而是String
在编译时创建单个:
private static final String DEFAULT_HEADER = "A long headers that is " +
"broker into two lines\n";
但是,在这两种情况下,字段(long timeoutMillis
和String DEFAULT_HEADER
)的分配和初始化都是在运行时完成的。
如果在运行时创建静态和最终静态变量,则在Main的第一个版本中,都不会创建MyClass类的静态变量(实例和PI)。
在您的示例中,第一次加载类时,将分配和初始化static
字段(final
或不分配)。因此,在您的第一个或者字段永远不会像您提到的那样创建。在你的第二个例子中。一旦引用,将加载类文件并创建字段。
https://stackoverflow.com/questions/-100008953
复制相似问题