java类的最终字段是否应该是静态的?
我在网上找不到任何关于此的参考资料。 但只是想知道一个类中的最终字段是否应该始终是static
还是仅仅是一个约定。 基于我对它们的用途的理解,我觉得比语言强加的东西更符合逻辑。
当然不是。 如果它们属于类,则它们必须是静态的,如果它们属于类的实例,则它们不是静态的:
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- wide常量。
1 – 井,类装载机范围,确切地说
最终字段不需要是静态的,有时候有一个非静态的最终实例变量会很有用。 标记为static和final的字段通常用于常量,如下所示:
public static final int BORDER_WIDTH = 5;
但是,有时当对象具有不可变属性时,您将看到非静态最终字段。 通常情况下,非静态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
,class级变得可变。 添加一个static
,所有的点都是相同的,并且没有合法的方法来编写构造函数。
绝对不。 例如,不可变对象具有final
属性,构造函数只能设置一次。
有关详细信息,请参阅: http : //docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html
不可变对象不是使用final
属性的唯一情况,但它们提供了它们有用性的明显示例。
答案是不。
静态的
-
“表示只有一个此类数据字段可用于此类的所有实例。如果没有此修饰符,则每个实例都有自己的数据字段副本”
……意思是只能有一个
最后
-
“无法修改为数据字段提供的值”
……这意味着这是一个常数