我在网上找不到任何有关此内容的参考资料。但只是想知道一个类中的最终字段应该始终是static
还是只是一个约定。基于我对它们的用途的理解,我觉得做的事情比语言所强加的更为合乎逻辑。
答案 0 :(得分:37)
当然不是。如果它们属于类,则它们必须是静态的,如果它们属于类的实例,则它们不是静态的:
public class ImmutablePerson {
private static final int MAX_LAST_NAME_LENGTH = 255; // belongs to the type
private final String firstName; // belongs to the instance
private final String lastName; // belongs to the instance
public ImmutablePerson(String firstName, String lastName) {
if (lastName.length() > MAX_LAST_NAME_LENGTH) {
throw new IllegalArgumentException("last name too large");
}
this.firstName = firstName;
this.lastName = lastName;
}
// getters omitted for brevity
}
答案 1 :(得分:21)
不,绝对没有 - 并且它不是惯例。
static
和final
完全不同的东西。 static
表示该字段与类型相关,而不是与该类型的任何特定实例相关。 final
表示字段在初始分配后不能更改值(必须在类型/实例初始化期间发生)。
static final
字段通常用于常量 - 而实例字段final
通常在创建不可变类型时使用。
答案 2 :(得分:7)
他们并不总是聚在一起,这不是一个惯例。 final
字段通常用于创建不可变类型:
class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
另一方面,static
但不是final
字段并不常见且非常棘手。经常看到static final
,因为它意味着应用 1 -wide constant。
1 - 确切地说,类加载器范围
答案 3 :(得分:7)
最终字段不需要是静态的,有时候有一个非静态的最终实例变量会很有用。标记为static和final的字段通常用于常量,如下所示:
public static final int BORDER_WIDTH = 5;
但是,有时当对象具有不可变属性时,您将看到非静态最终字段。通常情况下,非静态final
字段仍然标记为private
,但是,这更多的是额外的检查,因此编译器可以确保您再也不会设置该属性。
答案 4 :(得分:4)
如果你想像ClassName.FIELD
那样访问它们,那么是的,你必须这样做。如果你不使它成为静态的,你必须做一些像new ClassName().FIELD
这样的事情,这是不必要的,也是一个毫无意义的对象创造。
但是,如果您只是在课堂上使用它或使其成为private
,那么请不要将其设为静态。如果您在实际课程中,则可以FIELD
。
要完全掌握这个概念,你必须知道static
的含义。静态意味着它属于实际的类,而不是它的实例。
答案 5 :(得分:3)
绝对不是。考虑:
class Point {
public final int x;
public final int y;
public Point(int _x, int _y) {
x = _x;
y = _y;
}
}
删除final
,该类变得可变。添加static
,您的所有点都相同,并且没有合法的方法来编写构造函数。
答案 6 :(得分:2)
绝对不是。例如,不可变对象具有final
属性,只能由构造函数设置一次。
有关详细信息,请参阅:http://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html
不可变对象不是唯一使用final
属性的情况,但它们提供了一个明显的实用例子。
答案 7 :(得分:0)
答案是否定的。
静态
“表示只有一个此类数据字段可供所有人使用 这个类的实例。没有这个修饰符,每个实例都有它 自己的数据字段副本“
...意味着只能有一个
最终
“无法修改为数据字段提供的值”
...意味着这是一个常数