Java 何时为非staic最终变量分配内存?
我们知道,在类加载时,内存被分配给静态变量。对于最终的非静态变量也是如此。我知道最终变量的新副本将存在于类的每个实例中。我认为,最终非静态变量的第一个副本将在类加载时创建。请解释非静态字段是在对象创建时创建的。考虑这个例子。Java 何时为非staic最终变量分配内存?,java,Java,我们知道,在类加载时,内存被分配给静态变量。对于最终的非静态变量也是如此。我知道最终变量的新副本将存在于类的每个实例中。我认为,最终非静态变量的第一个副本将在类加载时创建。请解释非静态字段是在对象创建时创建的。考虑这个例子。 class MyClass { public static int staticVar = 1; public final int finalVar = staticVar; public static void main(String[] ar
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二,
非静态字段在对象创建时创建。考虑这个例子。
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二,
非静态字段在对象创建时创建。考虑这个例子。
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二,
非静态字段在对象创建时创建。考虑这个例子。
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二,
静态字段的内存确实是在类加载时分配的。或者更确切地说,在类链接阶段,它与加载分离 但这与最终的非静态场无关 首先,如果不为字段所属的整个对象分配内存,就不能为字段“分配”内存。该字段将成为对象的一部分。并且只有当您为对象使用
new
操作符时,才会为其分配空间
但也许您认为它的值将在类加载期间提前准备好,然后在创建新实例后立即复制到新实例中
考虑以下情况:
class A {
private final int myInt;
public A( int valueForMyInt ) {
myInt = valueForMyInt;
}
// Other constructors and methods
}
此处的myInt
值在施工期间设置。字段是final的事实并不意味着它在所有实例中的所有副本都是相同的。您可以使用常量初始值设定项、初始化块或在构造函数中初始化final字段,并且它们在其中设置的值不必对每个实例都相同。您可以使用new A(15)
、new A(27)
或任何您想要的整数创建新实例
因此,没有理由在实例的其余部分之前设置final字段。它的分配方式与非最终字段完全相同。唯一的区别是它不能被第二次分配。静态字段的内存确实是在类加载时分配的。或者更确切地说,在类链接阶段,它与加载分离 但这与最终的非静态场无关 首先,如果不为字段所属的整个对象分配内存,就不能为字段“分配”内存。该字段将成为对象的一部分。并且只有当您为对象使用
new
操作符时,才会为其分配空间
但也许您认为它的值将在类加载期间提前准备好,然后在创建新实例后立即复制到新实例中
考虑以下情况:
class A {
private final int myInt;
public A( int valueForMyInt ) {
myInt = valueForMyInt;
}
// Other constructors and methods
}
此处的myInt
值在施工期间设置。字段是final的事实并不意味着它在所有实例中的所有副本都是相同的。您可以使用常量初始值设定项、初始化块或在构造函数中初始化final字段,并且它们在其中设置的值不必对每个实例都相同。您可以使用new A(15)
、new A(27)
或任何您想要的整数创建新实例
因此,没有理由在实例的其余部分之前设置final字段。它的分配方式与非最终字段完全相同。唯一的区别是它不能被第二次分配。静态字段的内存确实是在类加载时分配的。或者更确切地说,在类链接阶段,它与加载分离 但这与最终的非静态场无关 首先,如果不为字段所属的整个对象分配内存,就不能为字段“分配”内存。该字段将成为对象的一部分。并且只有当您为对象使用
new
操作符时,才会为其分配空间
但也许您认为它的值将在类加载期间提前准备好,然后在创建新实例后立即复制到新实例中
考虑以下情况:
class A {
private final int myInt;
public A( int valueForMyInt ) {
myInt = valueForMyInt;
}
// Other constructors and methods
}
此处的myInt
值在施工期间设置。字段是final的事实并不意味着它在所有实例中的所有副本都是相同的。您可以使用常量初始值设定项、初始化块或在构造函数中初始化final字段,并且它们在其中设置的值不必对每个实例都相同。您可以使用new A(15)
、new A(27)
或任何您想要的整数创建新实例
因此,没有理由在实例的其余部分之前设置final字段。它的分配方式与非最终字段完全相同。唯一的区别是它不能被第二次分配。静态字段的内存确实是在类加载时分配的。或者更确切地说,在类链接阶段,它与加载分离 但这与最终的非静态场无关 首先,如果不为字段所属的整个对象分配内存,就不能为字段“分配”内存。该字段将成为对象的一部分。并且只有当您为对象使用
new
操作符时,才会为其分配空间
但也许您认为它的值将在类加载期间提前准备好,然后在创建新实例后立即复制到新实例中
考虑以下情况:
class A {
private final int myInt;
public A( int valueForMyInt ) {
myInt = valueForMyInt;
}
// Other constructors and methods
}
此处的myInt
值在施工期间设置。字段是final并不意味着它在所有实例中的所有副本都是final