我知道常量是那些值无法改变的变量,但是如果程序的任何部分没有改变它们的值,它们是否仍然需要被声明为final
?它似乎也必须是静态的。这是为什么?
你实际上是在问我想要回答的几个问题。
常量用于避免代码中的magic numbers/strings。如果您的代码中有多个字符串出现,那么一旦您需要更改该字符串,您只需要更改常量定义,而不是更改代码中每次出现的字符串。此外,如果只使用一个常数,它通常是一件好事,因为它具有更好的可见性。
final
关键字。它的目的(至少在这种情况下)是双重的。一个是让程序员无法改变价值。你可能已经忘记它是一个常数。另一种是告诉编译器该值在运行时不能更改。这可以用于创建优化的字节码(例如,可以移除常量,并且编译器将每次出现的值替换为其值)。
static
关键字。在Java中,一切都是类。每个Class都可以有多个实例(对象)。如果你不将你的常数标记为static
那么每个对象都有“自己的常数”。既然你不想要将它标记为静态是有意义的。静态字段(或方法)每个类只存在一次(而不是每个类的对象一次)。
宣布非静态决赛当然是可能的:
class Employee {
final String empId;
public Employee(String empId) { this.empId = empId; }
}
在其他情况下,您希望字段在类的所有实例中保持不变:
class Color {
final static int BLACK = 0xFFFFFF;
}
至于你为什么要声明它们final
而不是永远不改变它们,
因为static属于class而不是任何实例。
当它是所有实例共享的static
单一副本时。 instance
会员拥有个人副本的地方。
考虑你需要在游戏的每个阶段(阶段级别)增加/减少游戏分数(count
)。
通常,当您要在代码上使用常量值时,声明最终的静态变量。这可以防止你在代码周围散布“神奇的价值”,这不是一个好的做法,因为可持续性和易读性的原因。
如果您没有声明它们是最终的,那么其他人(或者您,如果您忘记了初始意图)制作的代码可能会修改该变量。
如果你没有将它们声明为静态,那么你创建的类的每个实例都会有一个副本,你也必须创建一个实例来获取值。通常,这不是你想要的。
我们声明常量因为我们总是需要一些在代码中修复的“幻数”。使用常量意味着它们更容易被发现,并且当您更改它们时,您将通过编辑更改所有这些常量。
想象一下,您的代码定义了您的窗口将显示15
记录,并且当他们是15
岁时您将把人们视为成年人。没有常数,改变窗口的大小意味着你必须找到15
发生,不要错过任何一个,并且不要改变一个错误地表示年龄的15
。
static
部分是因为您不想实例化一个对象来获取与特定实例无关的数据(这正是static
的意思,顺便说一句,不仅仅是用于常量)。
这不是绝对必要的,但出于内存效率的原因,建议使用它:
如果你没有将你的常量声明为static
,那么创建的每个类的实例(可能是数千个)将保留它在内存中的常量(或至少是对它的引用),而static
成员只保留每个班级一次 - 因为它无论如何都是不变的,这就足够了。