1

我知道可以执行以下操作:

public class Indeed{
    private class inner {
        static final int try1 = 10;
    }
}

为什么?允许这样的声明有什么意义?此外,在本地类中仍然可以做同样的事情:

public void doThing() {
    class LocalClass {
         static final int try1 = 10;
    }
}

在这些代码中使用静态 final 有什么用?我很确定我永远不会使用它们,但是我需要了解为什么要使用它们,因为我要参加 OCPJP7 考试。

提前致谢。

4

2 回答 2

3

静态变量的目的是由类的所有实例共享。在这两个示例中,您可以拥有私有类/本地类的多个实例,因此按照指定,它们将在实例之间共享静态变量。如果你只能实例化你的类一次,那将毫无意义。

JLS 8.1.3。: 内部类和封闭实例

内部类不能声明静态成员,除非它们是常量变量(第 4.12.4 节),或者发生编译时错误。

我在规格中看到它的方式不必回答以下困境:

  • 内部类的静态变量在同一个外部类实例的所有实例之间共享(但它们可以从一个外部类实例到另一个具有不同的值)
  • 内部类的静态变量在 VM 中的所有现有实例之间共享,无论它们的外部类实例如何。

幸运的是,当您将其声明为 final 时,您知道它对于每个实例都是相同的,因此您不必担心这个问题。这就是它被允许的原因。

于 2013-06-13T07:17:22.247 回答
1

对于“为什么内部类的静态字段必须是最终的”这个问题:

该限制在 JLS中声明为

内部类不能声明静态成员,除非它们是常量变量(第 4.12.4 节),或者发生编译时错误。

但这并不能告诉我们原因。让我们想想我们如何使用内部类。想象一下我写(尝试)这个。

public class A{
  private class B{
    static x;
  }
  public void updateX(int y){
    B.x=y;
  }
  public void printX(){
    System.out.println(x);
  }
}

当我这样做时会发生什么

A one = new A();
A two = new A();
one.doStuff(1);
two.doStuff(2);
one.printX();
two.printX();

应该打印什么?1 然后 2 或 2 两次?x 是静态的,所以它应该只存在于一个地方(在KlassB 的对象中),但由于 B 是一个内部类,它应该特定于 A 的该实例。如果我们允许静态非最终字段,我们将需要创建一个实例-Klass每个外部类实例的特定对象。这是我们不想做的!

因此允许静态最终字段,因为它们可以Klass愉快地存在于 B 的对象中,并且可以在外部类的所有实例之间共享,因为它们永远不会改变(是最终的)。

于 2013-06-13T07:27:27.813 回答