How instantiating an inner class in Java really works?
我正在从内部类中创建一个实例,但我不明白此语法的含义。
1 2 3 | OuterClass outerObject = new OuterClass(); OuterClass.InnerClass innerObject = outerObject.new InnerClass(); |
我知道如果不从外部类
要实例化内部类,必须首先实例化外部类。然后,使用此语法
在外部对象内创建内部对象
如果我没记错的话,其语法含义如下:
1 2 3 4 5 6 7 8 9 10 11 12 | OuterClass.InnerClass innerObject = outerObject.new InnerClass(); InnerClass The class InnerClass . which is an inner class of OuterClass OuterClass innerObject has an instance named innerObject = which is assigned the value new InnerClass() of a new InnerClass instance . such that when you use OuterClass.this from within InnerClass methods invoked on innerObject, it refers to outerObject outerObject. |
关键是内部类是通过引用外部类来创建的。如果您的InnerClass是静态的(整个OuterClass类一个InnerClass),您将看到对外部类的引用是静态的:
1 2 3 4 5 | static class InnerClass { ... } ... //Initialization will become: OuterClass.InnerClass innerObject = new OuterClass.InnerClass(); ^ this part is a static OuterClass reference |
另一方面,在您当前的情况下(InnerClass不是静态的),必须以对象
从InnerClass中访问
OuterClass.java
1 2 3 4 5 6 7 8 9 10 | public class OuterClass { class InnerClass { public OuterClass getOuterClassReference() { return OuterClass.this; } } } |
Main.java
1 2 3 4 5 6 7 8 9 10 11 | class Main { public static void main(String[] args) { OuterClass outerObject = new OuterClass(); OuterClass.InnerClass innerObject = outerObject.new InnerClass(); System.out.println(outerObject); System.out.println(innerObject.getOuterClassReference()); System.out.println(outerObject == innerObject.getOuterClassReference()); } } |
输出:
OuterClass@36baf30c
OuterClass@36baf30c
true
在这里,输出中的
JVM在
1 2 3 4 5 6 7 8 9 10 | public class OuterClass { public class InnerClass { public OuterClass getOuterClassReference() { return OuterClass.this; } } } OuterClass outerObject = new OuterClass(); OuterClass.InnterClass innerObject = outerObject.new InnerClass(); // innerObject has this reference to outerObject |
1 2 3 4 5 6 | public class OuterClass { public static class InnerClass {} } OuterClass outerObject = new OuterClass(); OuterClass.InnerClass innerObject = new OuterClass.InnerClass(); // innerObject does not have this reference to outerObject |
换句话说,您可以像这样自己模仿
1 2 3 4 5 6 7 8 9 10 | public class OuterClass { } public class InnerClass { private final OuterClass outer; public InnerClass(OuterClass outer) { this.outer = outer; } } |
这是类的名称,很可能以此方式命名,以使编译器更容易找到定义。
如果将变量声明为只是
点符号表示它实际上是
这与使用库中的类相同,
1 | com.example.MyLibrary.ExternalClass myExternalObject; |
您可以将内部类定义为OuterClass的静态成员
1 2 3 4 5 6 7 8 9 10 | public class OuterClass { public static class StaticInnerClass { int i = 0; public String call() { i++; return this.getClass().getName() +" i=" + i; } } } |
因此,在定义静态内部类时,编译器知道成员是一个类,存储区在编译时被实例化(可以以静态方式访问),并且您可以将new运算符和new运算符实例应用于另一个类中内存区域。
例如在主类中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public class Main { public static void main(String[] args) { /** * https://stackoverflow.com/questions/57581397/how-instantiating-an-inner-class-in-java-really-works * * @@@ New instance of Inner class */ OuterClass.StaticInnerClass staticInnerClass = new OuterClass.StaticInnerClass(); System.out.println(staticInnerClass.call()); System.out.println(staticInnerClass.call()); staticInnerClass = new OuterClass.StaticInnerClass(); System.out.println("\ " + staticInnerClass.call()); System.out.println(staticInnerClass.call()); } } |
带输出
1 2 3 4 5 6 7 | // new of inner class and i = 0 innerclass.OuterClass$StaticInnerClass i=1 innerclass.OuterClass$StaticInnerClass i=2 // new of inner class and i = 0 innerclass.OuterClass$StaticInnerClass i=1 innerclass.OuterClass$StaticInnerClass i=2 |
参考文献:https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html。
完整路径类似于
因此,
确实与以下内容没有什么不同: