常规中是否接受非静态最终变量?

时间:2014-09-07 22:14:36

标签: java

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

我的问题(我要快点,因为我很忙)是在变量上使用最终修饰符,初始化后没有任何东西可以改变它,对吧?

因此,假设我在名为animal的类中有一个值为10的静态最终Integer:

public static final int SIZE = 10;

这意味着从动物类型创建的所有对象都将具有SIZE = 10。

何时使用非静态但最终变量是有用的,实用的还是可接受的:

public final int SIZE = 10;

这也意味着从动物类型创建的所有对象都将具有SIZE = 10。

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

4 个答案:

答案 0 :(得分:4)

当同一种动物有这样的领域时:

private final Animal mother;

每个人只有一个亲生母亲并且没有共享的母亲,这意味着每个实例都具体。

使其成为static意味着该值在所有实例之间共享。如果这是你想要的那么它就是有道理的。

答案 1 :(得分:1)

一个常见的用例是锁定对象。

private final Object lock = new Object();
...
synchronized(lock) {...}

此模式有时需要锁定对象属于实例而不属于类(static)。

答案 2 :(得分:1)

Java中的

final不要与C ++中的const混淆。声明变量final意味着无法重新分配变量final。如果变量是基本类型,这很好。如果变量是引用类型,则声明它int不会阻止它变异。

这是安全的(因为class Week { public static final int NUMBER_OF_DAYS = 7; } Week.NUMBER_OF_DAYS = 6; // error: cannot reassign final variable 是原始类型)并且通常被接受:

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 没有改变其价值的方法,它必须永远不会得到一个或一个非常基本的语言级合同将被打破。)我仍然发现许多人不喜欢这种公共属性的使用和许多风格指南禁止它

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!

这不安全:

java.util.Collection

使用Collection不会让最后一个例子变得更好。有{{1}}个截断所有变异方法,但这会给我们带来的唯一一个错误就是运行时错误。编译器无法在这里提供帮助。

答案 3 :(得分:0)

如果字段类型是不可变的,那么只有当它是由构造函数指定的值时才有意义。

final class Point {
    final double x, y;
    Point(double x, double y) {
        this.x = x;
        this.y = y;
    }
}

如果字段的值是可变的,那么在其声明站点初始化final字段是有意义的,因为每个实例都将获得自己的引用。

final class ListWrapper<A> {
    final List<A> list = new ArrayList<>();
}

但是在你给出的例子中,不,将字段初始化为public final int SIZE = 10;永远没有意义。