【问题标题】:Should initialized final fields that are immutable always be made static?是否应该将不可变的已初始化最终字段始终设为静态?
【发布时间】:2018-03-03 09:23:53
【问题描述】:

我想知道非空白/初始化的不可变最终字段是否会有合法用例。

换句话说:

class Foo {
  private final String bar = "bar";
}

对比

class Foo {
  private static final String BAR = "bar";
}

【问题讨论】:

  • 私有最终字符串 bar = “bar”;根本没有意义,您只是有一个对等对象常量变量,而不是整个程序的单个常量。 IE。 'static final' 减少内存使用
  • @BoristheSpider 不为字符串节省空间,但为引用节省空间。
  • @BoristheSpider static final 字段占用的内存少于instance final。对象只有一个引用,而不是每个实例一个。
  • @Boris the Spider 取决于 JVM。 JVM 可能会也可能不会使用字符串缓存。 HotSpot 使用它,所以只会使用一个 chaster 数组(但我不知道有多少 java.lang.String 引用)。另一件事 - javac 编译器优化,可以自动添加static。在消息格式(或 StringBuilder 例如)的情况下,不是线程安全的方法 - 不要将其用作static final,也不要简单地使用“private final”。顺便提一句。 Joshua Bloch Effective Java 解释了所有这些事情。
  • @VictorGubin JLS 要求共享字符串文字。这不是 JVM 实现者自己决定的事情。

标签: java


【解决方案1】:

在大多数情况下,答案是:视情况而定

static 是什么意思?实际上,这意味着让所有实例使用该字段的相同值

大多数情况下,不可变对象可以在所有实例之间共享而不会出现问题。就像在这种情况下,将其设为静态是有意义的,因为您希望类的所有实例都使用该字段的相同

但不要忘记,即使对象是不可变的,它仍然具有可变属性,例如用于同步机制的monitor。假设你的班级有

private final Object lock = new Object(); 

并且每个实例都应该使用自己的lock 对象进行同步(如synchronize(lock){...})。尽管Object 是不可变的,但将lock 设为静态并不是我们想要的(lock 的值不应共享,而应为每个实例分开)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-23
    • 2014-10-06
    • 2019-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-30
    相关资源
    最近更新 更多