22

我在网上找不到任何关于此的参考资料。但只是想知道一个类中的最终字段是否应该总是static或者只是一个约定。根据我对它们用途的理解,我觉得这更像是一种合乎逻辑的事情,而不是语言强加的事情。

4

8 回答 8

40

当然不是。如果它们属于类,它们必须是静态的,如果它们属于类的实例,它们就不是静态的:

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
}
于 2013-02-16T18:09:30.377 回答
25

不,绝对不是——而且这不是惯例。

static并且final完全不同的东西。static表示该字段与类型相关,而不是与该类型的任何特定实例相关。final表示该字段在初始分配后不能更改值(必须在类型/实例初始化期间发生)。

static final字段通常用于常量 - 而实例字段final通常用于创建不可变类型。

于 2013-02-16T18:09:06.267 回答
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范围内的常量。

1 - 准确地说,类加载器范围内

于 2013-02-16T18:09:01.007 回答
7

最终字段不需要是静态的,有时拥有一个非静态的最终实例变量会很有用。标记为 static 和 final 的字段通常用于常量,如下所示:

public static final int BORDER_WIDTH = 5;

但是,当对象具有不可变属性时,有时您会看到非静态 final 字段。通常,由于通常的原因,非静态final字段仍然被标记private,所以它更多的是额外的检查,所以编译器可以确保你永远不会再次设置属性。

于 2013-02-16T18:10:03.873 回答
4

如果您想像 一样访问它们ClassName.FIELD,那么是的,您必须这样做。如果您不使其成为静态,则必须执行类似 的操作new ClassName().FIELD,这是不必要且毫无意义的对象创建。

但是,如果您只是在课堂上使用它或制作它private,那么不要让它成为静态的。如果您在实际班级中,则可以执行FIELD.

要完全掌握这个概念,你必须知道是什么static意思。静态意味着它属于实际类,而不是它的实例。

于 2013-02-16T18:08:26.603 回答
3

绝对不。考虑:

class Point {
    public final int x;
    public final int y;

    public Point(int _x, int _y) {
        x = _x;
        y = _y;
    }
}

删除final,该类变为可变的。加一个static,你所有的点都是一样的,没有合法的方法来写构造函数。

于 2013-02-16T18:11:21.630 回答
2

绝对不。例如,不可变对象具有final只能由构造函数设置一次的属性。

更多信息,请参见:http ://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html

不可变对象不是final使用属性的唯一情况,但它们提供了一个明显的例子来说明它们的用处。

于 2013-02-16T18:08:47.040 回答
0

答案是不。

静止的

  • “表示只有一个这样的数据字段可用于此类的所有实例。没有此修饰符,每个实例都有自己的数据字段副本”

    ...意味着只能有一个

最后

  • “无法修改为数据字段提供的值”

    ...意味着这是一个常数

于 2018-01-31T22:12:50.237 回答