为什么数据字段应该是静态的和最终的
Why should data fields be static and final
Deitel 的编程方法 Java 书说:
A final field should also be declared static if it is initialized in its declaration to a value.
这是为什么?
public class A
{
private final int x = 5;
private static final int y = 5;
}
我认为x和y是一样的
static
限定符在这里有什么关系?
static
限定符对软件工程观察有什么好处?
因为它是最终的,所以它将始终保持相同的值。
如果您不声明它 static
,您将为 class 的每个实例创建一个变量。 static
意味着您只需声明一次变量,避免不必要的内存使用。
将变量声明为静态变量可提高内存效率。例如,在您的示例中,无论您创建了多少次 new A()
,因为字段 x
和字段 y
已声明为静态,它们只会分配一次内存。如果您不将它们声明为 static
,它们将在每个新的 class 实例中分配内存。
明智的做法是将已像您一样初始化的 final
变量声明为静态变量,因为它无法更改,因此只分配一次内存是可以接受的。
本质上是为了节省内存。如果无论如何常量始终相同,那么您不妨将其设为静态,这样就不会为每个对象都创建它。但是,如果每个对象的常量不一定相同(例如,如果您的常量在构造函数中的某处初始化),您不想将其设为静态。
x
是实例变量,而 y
是全局变量。
这是什么意思?
我们来看这个例子:
public class A {
public A() {
System.out.println("create A");
}
}
public class B {
public B() {
System.out.println("create B");
}
}
public class C {
private static B b = new B();
private A a = new A();
}
然后一个主要的:
public static void main(String[] args) {
C c1 = new C();
C c2 = new C();
}
打印:
> create B
> create A
> create A
c1
和 c2
共享同一个 B
实例,同时他们都创建了自己的 A
实例!
所以 c1.b == c2.b
而 c1.a != c2.a
.
所以总结:
对于 class C (c1, c2) 的每个实例,字段 b 只有一个相同的 place/address
但是对于字段 a 在不同的实例中有不同的 places/addresses。
示例有点过大 class A 和 B:
即使对于简单字段(int、float、...),在每个 class.
实例中对于静态字段也是相同的 place/occurrence
它节省了内存,因为它只为变量的 1 个副本分配。如果您要为非静态变量创建一个新实例,它将为该指定实例创建一个新副本。
由于它们是最终的,因此无法更改,因此将它们设为静态是有意义的,因此当您创建新实例时,不会为变量分配任何新内容,因为它们甚至无法更改。
Deitel 的编程方法 Java 书说:
A final field should also be declared static if it is initialized in its declaration to a value.
这是为什么?
public class A
{
private final int x = 5;
private static final int y = 5;
}
我认为x和y是一样的
static
限定符在这里有什么关系?
static
限定符对软件工程观察有什么好处?
因为它是最终的,所以它将始终保持相同的值。
如果您不声明它 static
,您将为 class 的每个实例创建一个变量。 static
意味着您只需声明一次变量,避免不必要的内存使用。
将变量声明为静态变量可提高内存效率。例如,在您的示例中,无论您创建了多少次 new A()
,因为字段 x
和字段 y
已声明为静态,它们只会分配一次内存。如果您不将它们声明为 static
,它们将在每个新的 class 实例中分配内存。
明智的做法是将已像您一样初始化的 final
变量声明为静态变量,因为它无法更改,因此只分配一次内存是可以接受的。
本质上是为了节省内存。如果无论如何常量始终相同,那么您不妨将其设为静态,这样就不会为每个对象都创建它。但是,如果每个对象的常量不一定相同(例如,如果您的常量在构造函数中的某处初始化),您不想将其设为静态。
x
是实例变量,而 y
是全局变量。
这是什么意思?
我们来看这个例子:
public class A {
public A() {
System.out.println("create A");
}
}
public class B {
public B() {
System.out.println("create B");
}
}
public class C {
private static B b = new B();
private A a = new A();
}
然后一个主要的:
public static void main(String[] args) {
C c1 = new C();
C c2 = new C();
}
打印:
> create B
> create A
> create A
c1
和 c2
共享同一个 B
实例,同时他们都创建了自己的 A
实例!
所以 c1.b == c2.b
而 c1.a != c2.a
.
所以总结: 对于 class C (c1, c2) 的每个实例,字段 b 只有一个相同的 place/address 但是对于字段 a 在不同的实例中有不同的 places/addresses。
示例有点过大 class A 和 B: 即使对于简单字段(int、float、...),在每个 class.
实例中对于静态字段也是相同的 place/occurrence它节省了内存,因为它只为变量的 1 个副本分配。如果您要为非静态变量创建一个新实例,它将为该指定实例创建一个新副本。
由于它们是最终的,因此无法更改,因此将它们设为静态是有意义的,因此当您创建新实例时,不会为变量分配任何新内容,因为它们甚至无法更改。