我在网上找不到任何关于此的参考资料。但只是想知道一个类中的最终字段是否应该总是static
或者只是一个约定。根据我对它们用途的理解,我觉得这更像是一种合乎逻辑的事情,而不是语言强加的事情。
8 回答
当然不是。如果它们属于类,它们必须是静态的,如果它们属于类的实例,它们就不是静态的:
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
}
不,绝对不是——而且这不是惯例。
static
并且final
是完全不同的东西。static
表示该字段与类型相关,而不是与该类型的任何特定实例相关。final
表示该字段在初始分配后不能更改值(必须在类型/实例初始化期间发生)。
static final
字段通常用于常量 - 而实例字段final
通常用于创建不可变类型。
他们并不总是聚在一起,这也不是约定俗成的。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范围内的常量。
1 - 准确地说,类加载器范围内
最终字段不需要是静态的,有时拥有一个非静态的最终实例变量会很有用。标记为 static 和 final 的字段通常用于常量,如下所示:
public static final int BORDER_WIDTH = 5;
但是,当对象具有不可变属性时,有时您会看到非静态 final 字段。通常,由于通常的原因,非静态final
字段仍然被标记private
,所以它更多的是额外的检查,所以编译器可以确保你永远不会再次设置属性。
如果您想像 一样访问它们ClassName.FIELD
,那么是的,您必须这样做。如果您不使其成为静态,则必须执行类似 的操作new ClassName().FIELD
,这是不必要且毫无意义的对象创建。
但是,如果您只是在课堂上使用它或制作它private
,那么不要让它成为静态的。如果您在实际班级中,则可以执行FIELD
.
要完全掌握这个概念,你必须知道是什么static
意思。静态意味着它属于实际类,而不是它的实例。
绝对不。考虑:
class Point {
public final int x;
public final int y;
public Point(int _x, int _y) {
x = _x;
y = _y;
}
}
删除final
,该类变为可变的。加一个static
,你所有的点都是一样的,没有合法的方法来写构造函数。
绝对不。例如,不可变对象具有final
只能由构造函数设置一次的属性。
更多信息,请参见:http ://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html
不可变对象不是final
使用属性的唯一情况,但它们提供了一个明显的例子来说明它们的用处。
答案是不。
静止的
“表示只有一个这样的数据字段可用于此类的所有实例。没有此修饰符,每个实例都有自己的数据字段副本”
...意味着只能有一个
最后
“无法修改为数据字段提供的值”
...意味着这是一个常数