这个问题讨论了非静态最终变量的实践。
我的问题(由于我很忙,我将使其变得快速)是在变量上使用final修饰符后,没有什么可以更改它,对吗?
所以可以说我在一个名为animal的类中有一个静态最终Integer,值10。
public static final int SIZE = 10;
Run Code Online (Sandbox Code Playgroud)
这意味着所有从animal类型创建的对象的SIZE = 10。
什么时候使用非静态的但最终的变量有用,实用或被接受:
public final int SIZE = 10;
Run Code Online (Sandbox Code Playgroud)
这也意味着所有从animal类型创建的对象的大小都将为SIZE = 10。
那么后者在什么情况下有用?因为它基本上意味着同一件事。
当同一只动物具有这样的字段时:
private final Animal mother;
Run Code Online (Sandbox Code Playgroud)
每个人只有一个亲生母亲,没有共享的妈妈,这意味着每个人都有自己的母亲。
使其static表示该值在所有实例之间共享。如果这是您想要的,那么它当然很有意义。
final在 Java 中不要与const在 C++ 中混淆。声明一个变量final意味着它不能被重新分配。如果变量是原始类型,这很好。如果变量是引用类型,声明它final不会阻止它发生变异。
这是安全的(作为int原始类型)并且被普遍接受:
class Week {
public static final int NUMBER_OF_DAYS = 7;
}
Week.NUMBER_OF_DAYS = 6; // error: cannot reassign final variable
Run Code Online (Sandbox Code Playgroud)
这也是安全的。虽然java.lang.String不是原始类型,但它保证是不可变的。(即String没有方法可以改变它的值,它永远不能得到一个,否则一个非常基本的语言级契约将被破坏。)我仍然发现很多人不喜欢这种公共属性的使用,许多风格指南禁止它。
class Weekday {
public final String name;
public Weekday(String name) {
this.name = name;
}
}
Weekday monday = new Weekday("Monday");
monday.name = "Tuesday"; // error: cannot reassign final variable
Run Code Online (Sandbox Code Playgroud)
这不安全:
class Week {
public static final String[] DAYS_OF_THE_WEEK = {
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday",
};
}
Week.DAYS_OF_THE_WEEK = new String[6]; // error: cannot reassign final variable
Week.DAYS_OF_THE_WEEK[2] = "February"; // this is not prevented!
Run Code Online (Sandbox Code Playgroud)
使用 ajava.util.Collection不会使最后一个例子更好。有一些Collections 可以截断所有变异方法,但这会给我们带来的唯一好处是运行时错误。编译器在这里无能为力。