|
|
1
112
因为内部类的实例与外部类的实例隐式关联,所以它本身不能定义任何静态方法。由于静态嵌套类不能直接引用其封闭类中定义的实例变量或方法,因此只能通过对象引用使用它们,因此在静态嵌套类中声明静态方法是安全的。 |
|
|
2
48
在非静态内部类中允许静态方法没有多大意义;您将如何访问它?如果不经过外部类实例,则无法访问(至少最初)非静态内部类实例。没有纯粹静态的方法来创建非静态的内部类。
外流阶级
对于静态内部类
然而,如果
Paul Bellora是正确的,语言设计者本可以允许这样做。然后,他们必须小心地禁止在非静态内部类的静态方法中访问对外部类的隐式引用。在这一点上,如果不能引用外部类(静态引用除外),那么作为一个内部类,它的值是什么?如果静态访问很好,那么为什么不将整个内部类声明为静态呢?如果您只是将内部类本身设置为静态,那么您就没有对外部类的隐式引用,也不再有这种模糊性。 如果你真的 需要 非静态内部类上的静态方法,那么您可能需要重新考虑您的设计。 |
|
|
3
21
首先,您应该了解一些关于如何在Java中实现内部类的知识。假设你有这样一门课:
现在,如果我们确实允许在非静态内部类中使用静态方法,那么您可能需要这样做。
... 这看起来相当合理,因为
... 这显然行不通,因为
|
|
|
4
7
唯一的原因是“不是必须的”,那么为什么还要费心支持它呢?
如果您需要在的所有实例中共享某些内容
如果您需要在的所有实例中共享某些内容
我不同意“静态嵌套类实际上只是一个顶级类”的观点。我认为最好将静态嵌套类/内部类视为外部类的一部分,因为它们可以访问外部类的私有成员。外部阶级的成员也是“内部阶级的成员”。所以不需要在内部类中支持静态成员。外部类中的普通/静态成员就足够了。 |
|
|
5
4
发件人: https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
甲骨文的解释是肤浅和徒劳的。由于没有技术或语法上的理由来抢占内部类中的静态成员(其他语言如C#也允许这样做),Java设计者的动机可能是概念品味和/或技术便利。 以下是我的猜测: 与顶级类不同,内部类依赖于实例:内部类实例与其每个外部类的实例相关联,并且可以直接访问其成员。这是在Java中使用它们的主要动机。用另一种方式表示:内部类是 在外部类实例的上下文中实例化。没有外部类实例,内部类就不应该再存在了 而不是外部类的其他实例成员。让我们将其称为 属于内部阶级。 静态成员(不是面向对象的)的本质与 依赖实例 实例依赖精神 抢占这一更深层次的OOP攻击的额外好处。 实例依赖精神 ? 也许是因为 常数 不需要占用超过必要的内存(如果它们被强制为非静态的,那么它们会被复制到每个内部类实例中,这可能会造成浪费)。否则我无法想象例外的原因。 这可能不是坚如磐石的推理,但在我看来,它最能理解甲骨文对此事的草率评论。 |
|
|
6
3
需要内部类中的静态成员的主要原因是为了代码的干净性——仅由内部类使用的静态成员应该位于内部,而不必放置在外部类中。考虑:
当我使用不合格的标识符“OUTID”时,考虑GETIE()中的内容。此标识符出现的范围类似于:
在这里,同样因为javac就是这样工作的,所以作用域的“外部”级别包括外部的静态和实例成员。这是令人困惑的,因为我们通常被告知将类的静态部分视为作用域的另一个级别:
好的,这与内部类有什么关系?天真地说,我们认为内部类没有理由不能有一个静态作用域,因为我们将作用域描绘成这样:
换句话说,内部类中的静态声明和外部类中的实例声明都在内部类的实例上下文中的范围内,但它们实际上都没有嵌套在另一个类中;两者都嵌套在Outer的静态范围中。 javac不是这样工作的——静态和实例成员都有一个单一级别的作用域,并且作用域总是严格嵌套的。甚至继承也是通过将声明复制到子类而不是分支和搜索超类范围来实现的。 为了支持内部类的静态成员,javac必须拆分静态范围和实例范围 和 支持分支和重新连接作用域层次结构,否则它必须扩展其简单的布尔“静态上下文”思想,以更改跟踪当前作用域中所有嵌套类级别的上下文类型。 |
|
7
3
非静态嵌套类称为内部类,因此您没有
如果没有外部类的对应实例,内部类实例就不存在。内部类不能声明编译时常量以外的静态成员。如果允许的话,这个词的意思就会模棱两可
这就是为什么设计师可能决定根本不处理这个问题。 同样,不能使内部类成为静态的,而可以将静态类声明为嵌套的。在这种情况下,这个嵌套类实际上是外部类的一部分,可以有静态成员,而不会出现任何问题。 |
|
|
8
3
这个话题已经引起了很多人的注意,但我还是会尝试用最简单的术语来解释。 首先,关于 http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1
简化这一点,为了访问静态成员,我们需要一个外部类的实例,从中我们将再次需要创建一个非静态内部类的实例。静态成员不应绑定到实例,因此会收到编译错误。 |
|
|
9
2
|
|
|
10
2
要向其中添加记录的工作
JDK16
还提到静态方法和字段现在可以与内部类一起使用,即使允许
|
|
|
11
0
假设有两个外部类的实例&它们都实例化了内部类。现在,如果内部类有一个静态成员,那么它将在堆区域中只保留该成员的一个副本。在这种情况下,外部类的两个对象都将引用这个单一副本&它们可以一起修改。这可能会导致“脏读”情况,从而阻止此Java应用此限制。支持此论点的另一个优点是Java允许此处的最终静态成员,即其值不能从任何外部类对象更改的成员。 如果我错了,请一定要告诉我。 |
|
|
12
0
但是对于这种情况,我们可以直接在外部类中定义成员。它将与外部类实例中内部类的所有对象相关联。
可以这样写吗
|
|
|
13
-1
试着把这个类当作一个普通的字段,然后你就会明白了。
|
|
|
14
-2
允许在静态嵌套类上使用静态方法。例如
|
|
|
15
-2
将内部类成员作为静态成员是没有用的,因为您首先将无法访问它们。
|