为什么在初始化新的非静态对象时使用静态声明

时间:2017-06-24 17:46:52

标签: java static initialization

如果这是多余的,我道歉,但我无法找到类似的问题。而且,TBH,我甚至不知道如何正确地构建问题。

这是来自Java 8 OCA学习指南的评论问题。问题是关于静态初始化器,我理解得很好。然而,有一行代码是我无法得到的,而且因为问题与此无关,所以对它没有很好的解释。

private static Rope rope = new Rope();

所以这不是关于Singletons或静态类。我不明白为什么要初始化这样的对象。并且,如果有充分理由说明为什么你可以并且愿意这样做,那么原因是什么?

有人会指出我的解释方向吗?就像我说的那样,我甚至不确定这是什么,所以我很难找到一个好的答案。

编辑以放入整个班级:

import rope.*;
import static rope.Rope.*;

public class RopeSwing
{
  private static Rope rope1 = new Rope("rope 1");
  private static Rope rope2 = new Rope("rope 2");

  {
    System.out.println(rope1.length);
  }

  public static void main(String[] args) {
    rope1.length = 2;
    rope2.length = 8;
    System.out.println(rope1.length);
  }
}

1 个答案:

答案 0 :(得分:0)

这使得整个类可以使用单个Rope实例 - 它将被声明的类的所有实例共享。当有一些共享信息或状态全部时,这可能很有用。实例应该依赖。

通常,private static字段也会声明final,这使得它们constants(假设字段的类型是不可变的)。看一下你的完整例子,我怀疑作者应该制作它们private static final

例如:

public class Foo {
  private static Rope rope = new Rope();
  private int value;

  public Foo(int value) { this.value = value; }

  @Override public String toString() {
    return "static rope: " + rope + " instance value: " + value;
  }
}

如果您创建了多个Foonew Foo(1);,' new Foo(2)等)的实例,则它们将共享相同的rope实例和{{ 1}}只会被调用一次(首次加载类时)。

非常量静态字段的示例可能是共享计数器。假设您希望在应用程序的任何位置唯一标识构造的对象的每个实例。您可以使用new Rope()执行此操作,AtomicInteger本质上是一个线程安全的int

public class Unique {
  // despite being final this is not a "constant" because it's mutable
  private static final AtomicInteger counter = new AtomicInteger();
  private final int id;

  public Unique() {
    id = counter.getAndIncrement();
  }

  @Override public String toString() { return "ID: " + id; }
}

试一试 - Unique的每个实例都有一个唯一的ID。

在您的示例代码中,有一个instance initializer,在创建新实例时会调用它(因此在static字段初始化之后)。