【问题标题】:Why use a static declaration when initializing a new non-static object为什么在初始化新的非静态对象时使用静态声明
【发布时间】:2017-06-24 17:46:52
【问题描述】:

如果这是多余的,我深表歉意,但我找不到类似的问题。而且,TBH,我什至不知道如何正确地提出问题。

这是来自 Java 8 OCA 学习指南的一个复习问题。问题是关于静态初始化程序的,我理解得很好。但是有一行代码我没有得到,因为问题不是关于它,所以没有很好的解释。

private static Rope rope = new Rope();

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

有人能指点我解释的方向吗?就像我说的,我什至不确定这应该叫什么,所以我很难自己找到一个好的答案。


编辑以放入整个班级:

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);
  }
}

【问题讨论】:

  • rope 不是“非静态对象”。 Rope 不是静态类这一事实无关紧要。
  • 我删除了关于 Rope 不是“静态类”的行,因为人们似乎对这个事实感到困惑。这是可以理解的混淆,但与您看到的语法无关。

标签: java static initialization


【解决方案1】:

这使得单个 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;
  }
}

如果您创建多个 Foo 实例(new Foo(1);、'new Foo(2) 等),它们都将共享同一个 rope 实例,并且 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 字段之后)。

【讨论】:

  • 让我再说一遍以确保我明白了:因为初始化器被声明为静态的,所以它可以在没有构造它所编写的类的实例的情况下访问。
  • 嗯,有点。因为 field 被声明为静态的,所以它会在类第一次加载时被初始化,在类的任何实例被构造之前。但是因为它是private,除了定义private static 字段的类的实例之外,没有任何东西可以访问该字段。
  • 这很酷。谢谢你。我相信我现在明白了。谢谢您的帮助。测试复习题充满了诸如此类的“陷阱”代码,这让我摸不着头脑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-11
  • 1970-01-01
  • 1970-01-01
  • 2017-12-07
  • 1970-01-01
相关资源
最近更新 更多