ParentClass.NestedClass nc = new NestedClass(); 隐式地实例化父类实例吗?

4

我有一段来自教科书的代码:

public class Question_3_4 {
  public static class Inner {
    private void doIt() {
      System.out.println("doIt()");
    }
  }
  public static void main(String[] args) {
    Question_3_4.Inner i = new Inner();
    i.doIt();
  }
}

嗯,内部类是静态的,所以我认为上面的代码隐式地实例化了Question_3_4的实例?

Question_3_4.Inner i = new Question_3_4.Inner();

与上述代码产生相同的结果。

因此,我认为

  Question_3_4.Inner i = new Question_3_4.Inner();   

and

  Question_3_4.Inner i = new Inner();

它们是同一件事。

如果我的假设是错误的,我在这里缺少什么?

3个回答

3
首先,你没有使用正确的术语。
你没有声明内部类,而是静态嵌套类。
引用:
术语:嵌套类分为两类:静态和非静态。声明为静态的嵌套类称为静态嵌套类。非静态嵌套类称为内部类。
您可以在Java Oracle Nested Classes教程中获得有关术语以及如何以及为什么使用嵌套类的有用信息:Java Oracle Nested Classes tutorial 关于你的问题:
嗯,内部类是静态的,所以我假设上面的代码隐式地实例化了Question_3_4的实例?
你不需要实例化外部类来实例化嵌套类或者说也是一个静态嵌套类。 此外,如果需要但未实例化外部类,则编译器不会为您实例化它,而是会发出编译错误。
只有在内部类(没有静态嵌套类)的情况下才需要实例化外部类。
例如,如果移除嵌套类的static修饰符,则会在Question_3_4.Inner i = new Inner();行产生编译错误,因为它要求必须有外部类的实例才能被实例化。
public class Question_3_4 {

     public class Inner {
             private void doIt() {
                     System.out.println("doIt()");
             }
     }
     public static void main(String[] args) {
             Question_3_4.Inner i = new Inner(); 
             ^--- error: non-static variable this cannot be referenced from a static context              
             i.doIt();
     }

}

非常感谢davidxxx。我现在有点迷失了,因为静态通常意味着它不与特定实例绑定,并且可由所有实例访问(例如,静态变量和方法可由类的所有实例访问)。那么“实例化静态内部类”是什么意思?在这种情况下(如果它是一个实例),它将无法直接被所有实例成员访问,只能使用实例变量(对吗?它只能通过实例变量访问吗?)。我的意思是,这不是静态含义丧失的情况吗? - Ula
实例化一个静态内部类并不意味着什么。嵌套类要么是“静态”的,要么是“内部的”。不能同时兼备。因为“静态”通常意味着它不与某个特定实例绑定,并且可供所有实例访问,这点是正确的。但更普遍的情况是,“静态”成员是指与实例无关的成员。因此,任何实例都可以引用“静态”成员,但是你也不需要实例就可以引用它。 - davidxxx
请仔细阅读我的回答,并通过以下教程加深理解:https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html 和 https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html,您将毫无问题地掌握它。 - davidxxx

2

在这种情况下不需要实例化父类,因为内部类是静态的,所以创建内部类实例时不需要父类实例。...

你可以通过编写父类的构造函数并检查它从未被调用来验证这一点...

public class Calculator {
    public Calculator() {
        System.out.println("Hello Constructor Calc");
    }

    public static class Inner {
        private void doIt() {
            System.out.println("doIt()");
        }
    }

    public static void main(String[] args) {
        Calculator.Inner i = new Inner();
        i.doIt();
        Calculator.Inner i2 = new Calculator.Inner();
        i2.doIt();
    }
}

实例i和i2都只会产生

doIt()

doIt()


非常感谢 ΦXocę 웃 Пepeúpa ツ。我现在有点迷茫,因为静态通常意味着它不与一个特定的实例绑定,并且可以被所有实例访问(例如,静态变量和方法可由类的所有实例访问)。那么,“实例化静态内部类”是什么意思?在这种情况下(如果它是一个实例),它将不能直接被所有实例成员访问,只能使用实例变量(对吗?它只能通过实例变量访问吗?)。我的意思是,这不是静态含义丧失的情况吗? - Ula

1

不需要外部类引用即可访问静态内部类。

静态嵌套类就像任何一个顶层类一样,只是为了保持关联而分组。它根本不是外部类的成员。您可以直接访问它。

注意:静态嵌套类 与其外围类(和其他类)的实例成员交互,就像任何其他顶级类一样。实际上,静态嵌套类在行为上是一个顶级类,在另一个顶级类中被嵌套以提供方便的封装。

然而,在非静态内部类中,你所说的是正确的。

嵌套类 是其封闭类的成员。非静态嵌套类(内部类)可以访问封闭类的其他成员,即使它们被声明为私有。静态嵌套类无法访问封闭类的其他成员。

要实例化内部类,您必须先实例化外部类,然后使用以下语法在外部对象中创建内部对象:

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

非常感谢@SURESHATTA。我有点迷失了,因为静态通常意味着它不与一个特定的实例绑定,并且可被所有实例访问(例如,静态变量和方法可以被类的所有实例访问)。那么,“实例化静态内部类”是什么意思?在这种情况下(如果它是一个实例),它将不能直接被所有实例成员访问,只能通过使用实例变量来访问(对吗?它只能通过实例变量访问吗?)。我的意思是,这不是静态含义丧失的情况吗? - Ula
是的,在这里不适用静态的一般含义。为了使事情更清楚,您可以假设在这种情况下,静态类的一般规则不适用。 - Suresh Atta

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