【问题标题】:Usage of static members in Inner Classes in javajava内部类中静态成员的使用
【发布时间】:2019-10-19 22:34:58
【问题描述】:

我知道 java 中的内部类不能有静态成员,除非它们被声明为 final 。但是理论上不应该在本地类中声明静态成员吗​​?

例如。

public class OuterClass
{
  class innerClass
  {
    public static int i = 1;
  // inner class code goes here
  }
}

我知道内部类的标准初始化是这样发生的:

OuterClass outerClass = new OuterClass();
OuterClass.innerClass innerclassInstance = outerClass.new innerClass();

但是为什么不这样呢??

OuterClass outerClass = new OuterClass();
outerClass.innerClass innerclassInstance = new outerClass.innerClass();

每当创建 OuterClass 的实例时,它还包含一个 innerClass 的副本。因此,如果允许静态(只是静态但不是最终)成员存在于 innerClass 中,那么它们应该(或可以)以这种方式访问​​

outerClassInstance.innerClass.member

我想错了吗?内部类的设计方式有什么特别的原因吗?

希望我很清楚。对不起我的英语不好。

【问题讨论】:

  • 因为静态成员从不依赖实例。
  • 我知道类中的静态变量应该(并且将)永远不会依赖于该类的实例。但我不明白为什么内部类中的静态变量不应该依赖于封闭类(或外部类)的实例。@csabinho 你能详细说明一下吗。提前谢谢
  • 好吧,为什么要这样呢?你能给我举个例子,内部类的静态变量依赖于外部类的实例吗?
  • 如果是这样,那么内部类的所有实例都有可能拥有一个公共变量,他们可以修改该变量并将该变量用于某种目的(如同步),而无需触及外部类中的字段这使得代码更紧凑。不是吗?
  • 我不太明白。你能在你的问题中编辑一个代码示例吗?

标签: java inner-classes


【解决方案1】:

但是理论上不应该在本地类中声明静态成员吗​​?

内部类与其外部类的对象隐式关联,因此 InnerClass 类的存在完全取决于 OuterClass 类的每个封闭对象。

让我们想象一下,您没有将 'i' 声明为 final,并且您创建了 OuterClass 类的实例 a 和 b,这两个实例相互独立。我们可以设置:

OuterClass a = new OuterClass();
OuterClass.InnerClass a1 = a.new InnerClass();
a1.i = 9;

OuterClass b = new OuterClass();
OuterClass.InnerClass b1 = b.new InnerClass();
b1.i = 18;

嗯,两个不同值的静态变量,并行存在,相互独立(因为a和b相互独立)。

这不可能发生,因为静态变量本质上是全局变量。 InnerClass 类的所有实例必须共享同一个静态变量。

但是为什么不这样呢??

OuterClass outer = new OuterClass(); //I modified the variable name to avoid confusion
outer.InnerClass innerclassInstance = new outer.InnerClass();

按照惯例,

Type name = new Type();

,所以outer(名称)无法解析为类型。

你可以这样做:

OuterClass.InnerClass innerclassInstance = new OuterClass().new InnerClass();

希望我的回答对你有所帮助。

【讨论】:

  • 感谢您的回答。为什么不允许 a1.i 和 b1.i 具有不同的值,因为它们来自不同的环境(这里是 a 和 b)并且是独立的。
  • 这里,因为静态变量本质上是全局变量。 InnerClass 类的所有实例必须共享同一个静态变量。我们最初的假设导致的结论与“静态”的定义相矛盾。
  • 我刚找到这篇文章:stackoverflow.com/questions/1953530/…。可以参考了解一下。
  • 我已经浏览了链接。我的问题是重复的,在提出问题之前我应该​​对以前的问题进行足够的搜索。无论如何,非常感谢@Do Van Tuan。我相信你已经给出了最好的答案。
  • 很高兴为您提供帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-13
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
  • 2012-09-02
  • 2013-07-27
相关资源
最近更新 更多