为什么静态最终变量在内部类中被接受?

时间:2013-06-13 07:06:51

标签: java static inner-classes final

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

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

为什么呢?什么是允许这样的声明? 此外,它仍然可以在本地课程中做同样的事情:

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

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

提前致谢。

2 个答案:

答案 0 :(得分:3)

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

<强> JLS 8.1.3. : Inner Classes and Enclosing Instances

  

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

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

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

幸运的是,当你声明它是最终的时,你知道每个实例都是一样的,所以你不必担心这个问题。这就是允许的原因。

答案 1 :(得分:1)

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

此限制声明为in the 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是静态的,因此它应该只存在于一个地方(在B的Klass对象中)但是因为B是一个内部类,它应该特定于该A的实例。如果我们允许静态非最终字段,我们需要为每个外部类的实例创建一个特定于实例的Klass对象。我们不想要这样做!

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