为什么数据字段应该是静态的和最终的

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

c1c2 共享同一个 B 实例,同时他们都创建了自己的 A 实例!

所以 c1.b == c2.bc1.a != c2.a.

所以总结: 对于 class C (c1, c2) 的每个实例,字段 b 只有一个相同的 place/address 但是对于字段 a 在不同的实例中有不同的 places/addresses。

示例有点过大 class A 和 B: 即使对于简单字段(int、float、...),在每个 class.

实例中对于静态字段也是相同的 place/occurrence

它节省了内存,因为它只为变量的 1 个副本分配。如果您要为非静态变量创建一个新实例,它将为该指定实例创建一个新副本。

由于它们是最终的,因此无法更改,因此将它们设为静态是有意义的,因此当您创建新实例时,不会为变量分配任何新内容,因为它们甚至无法更改。