为什么允许实例化静态嵌套类对象?

24

我已经开始学习Java语言,用于Android应用程序开发。

根据我对静态类的理解,我们无法实例化静态类的对象。

但是为什么在以下情况下允许实例化静态嵌套类的对象呢?

class EnclosingClass 
{     
      //...     
      class static StaticInnerClass 
      {         
          //...     
      } 
} 

如果内部类被标记为静态,为什么我们可以创建它的对象?

EnclosingClass.StaticInnerClass s = new EnclosingClass.StaticInnerClass()

2
这里有一句好的引用来自文档:"嵌套类分为两类:静态和非静态。声明为静态的嵌套类被简称为静态嵌套类。非静态嵌套类被称为内部类。"(链接)。如果您向下滚动,他们会解释它们的用法。 - keyser
1
@ParagMeshram,你对赏金有什么期望?Jon Skeet的回答不清楚吗? - assylias
文档(https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html)中另一个清晰且有用的引用是:“实际上,静态嵌套类在行为上是一个顶级类,它已经被嵌套在另一个顶级类中以方便打包。” - ShacharSh
3个回答

31
根据我理解,基于静态类,我们无法实例化静态类的对象。
你对“静态类”含义的理解是不正确的。在 Java 中,“静态类”基本上是指一个嵌套类,它没有对包含类实例的隐式引用。请参阅JLS第8.5.1节了解更多信息,特别是:

static关键字可以修改非内部类或接口T的成员类型C的声明。其效果是声明C不是内部类。正如T的静态方法在其体中没有当前T的实例一样,C也没有T的任何当前实例,也没有任何词法封闭实例。

也许你正在考虑 C# 中的静态类,但它们完全不同?

2
@Keyser:不,我指的是一个嵌套类。请看JLS中的引用:静态类表示该类不是内部类。来自JLS第8.1.3节:“内部类是一个未明确或隐式声明为静态的嵌套类。” - Jon Skeet
它的作用是声明C不是内部类。我不明白为什么他们不直接创建一个新的关键字,将声明为"static"的意思解释为"非内部"是很误导人的,你觉得呢?声明嵌套类为静态还有其他含义吗? - samus
1
@SamusArin:不存在“非嵌套静态类”的概念。 - Jon Skeet
1
@JonSkeet 好的,我最近一直在用C#编程,所以这就是我的问题,因为它确实有这些功能。非常感谢! - samus
1
@SamusArin:没错 - C#的静态类和Java的嵌套静态类是完全不同的。Java没有像C#的静态类那样的东西,而C#也没有像Java的内部类那样的东西。(如果你想在C#中引用包含类的实例,你需要明确地指定它。) - Jon Skeet
显示剩余5条评论

3
为什么我们可以在内部类被标记为静态时创建对象?
您可能需要在静态上下文中使用嵌套类,例如:
public class Test {

    public static void main(String args[]) {
        InnerClass innerClass = new InnerClass();
    }

    class InnerClass {

    }
}  

在这种情况下,当你尝试实例化 innerClass 时会出现以下错误:

No enclosing instance of type Test is accessible. Must qualify the allocation with an enclosing instance of type Test (e.g. x.new A() where x is an instance of Test).

为了避免这种情况,您可以实例化一个类型为 Test 的对象,并从中创建一个 innerClass 的实例:
Test test = new Test();
InnerClass innerClass = test.new InnerClass();

或者更好的方法是,将innerClass也声明为静态类,并在静态上下文中实例化它:
public class Test {

    public static void main(String args[]) {
        InnerClass innerClass = new InnerClass();
    }

    static class InnerClass {

    }
}

0

看看吧,也许它可以帮助你 嵌套类


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接