我们知道在类加载时为静态变量分配了内存。对于最终的非静态变量也是如此。我知道最终变量的新副本将存在于类的每个实例中。我认为,最后的非静态变量的第一个副本将在类加载时创建。请解释
答案 0 :(得分:3)
静态字段的内存确实是在类加载时分配的。或者更确切地说,在类链接阶段,它与加载分开。
但这与最终的非静态字段无关。
首先,如果没有为其所属的整个对象分配内存,就不能为字段“分配”内存。该字段将成为对象的一部分。一旦你使用new
运算符,对象就只会被分配空间。
但也许您认为它的值将在类加载期间提前准备好,然后在创建后立即复制到新实例中?
考虑以下情况:
class A {
private final int myInt;
public A( int valueForMyInt ) {
myInt = valueForMyInt;
}
// Other constructors and methods
}
此处myInt
的值是在 contruction 时间内设置的。字段为final的事实并不意味着所有实例中的所有副本都是相同的。您可以使用常量初始化程序,初始化块或构造函数初始化最终字段,并且它们在其中设置的值对于每个实例不必相同。您可以使用new A(15)
,new A(27)
或任何您想要的整数创建新实例。
因此,没有理由应该比实例的其余部分更早地设置最终字段。它的分配方式与非最终字段完全相同。唯一的区别是它不能再次分配。
答案 1 :(得分:0)
在对象的创建时创建非静态字段。考虑这个例子。
class MyClass {
public static int staticVar = 1;
public final int finalVar = staticVar;
public static void main(String[] args){
MyClass m1 = new MyClass();
MyClass.staticVar = 2;
MyClass m2 = new MyClass();
System.out.println(m1.finalVar);
System.out.println(m2.finalVar);
}
}
输出:
1
2