约定是否接受非静态最终变量?

JCl*_*sic 2 java

这个问题讨论了非静态最终变量的实践。

我的问题(由于我很忙,我将使其变得快速)是在变量上使用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。

那么后者在什么情况下有用?因为它基本上意味着同一件事。

Jer*_*vel 5

当同一只动物具有这样的字段时:

private final Animal mother;
Run Code Online (Sandbox Code Playgroud)

每个人只有一个亲生母亲,没有共享的妈妈,这意味着每个人都有自己的母亲。

使其static表示该值在所有实例之间共享。如果这是您想要的,那么它当然很有意义。


5go*_*der 5

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 可以截断所有变异方法,但这会给我们带来的唯一好处是运行时错误。编译器在这里无能为力。