外部class调用内部class的方法
Way to call inner class by outer class
我知道要实例化一个内部成员class,你有两个不同的构造函数:
第一个:
Outer out = new Outer();
Outer.Inner in = out.new Inner();
第二个:
Outer.Inner in = new Outer().new Inner();
现在,我不知道为什么这段代码可以编译:
public class Outer {
private String greeting="Hi";
protected class Inner {
public int repeat=3;
public void go() {
for (int i =0; i<repeat; i++) {
System.out.println(greeting);
}
}
}
public void callInner() {
Inner in = new Inner(); //in my opinion the correct constructor is Outer.Inner in = new Inner()
in.go();
}
public static void main(String[] args) {
Outer out = new Outer();
out.callInner();
}
}
为什么编译?
非常感谢!
当您在 Outer
的范围内实例化 Inner
(在实例方法中)时,您不需要显式实例化引用 Outer
类,就像在您的示例中一样:
Outer.Inner in = new Outer().new Inner();
只要引用就可以实例化Inner
:
Inner in = new Inner();
这适用于 class 中的所有实例方法,只要它们不是静态的。
将调用第一个主要方法
public static void main(String[] args){
Outer out = new Outer();
out.callInner();
}
从这里您创建了一个 Outer class 的对象并调用了如下所示的 callInner 方法
public void callInner() {
Inner in = new Inner(); //in my opinion the correct constructor is Outer.Inner in = new Inner()
in.go();
}
现在您已经创建了一个 Inner 对象并调用了 go 方法。
protected class Inner {
public int repeat=3;
public void go() {
for (int i =0; i<repeat; i++) {
System.out.println(greeting);
}
}
}
所以这是一个简单的调用,所有调用都在同一范围内。所以需要 outer.Inner 概念来调用。
了解外在和内在是相关的很重要。更具体地说,您需要一个外部实例才能创建一个内部实例。
如您的解释所示,您需要 Outer
的实例来创建 Inner
的实例。由于方法 callInner
是 Outer
的实例方法(未声明 [=17=]),因此已经存在 Outer
的实例:this
代码也可以这样写:
public void callInner() {
Outer out = this;
Inner in = out.new Inner();
in.go();
}
现在代码看起来与您的第一个示例相似。
但是让我们保持代码如图所示:
public void callInner() {
Inner in = new Inner();
in.go();
}
现在,如果我们看一下引擎盖,它基本上是一样的:
public void callInner();
Code:
0: new #21 // class playground/Outer$Inner
3: dup
4: aload_0
5: invokespecial #23 // Method playground/Outer$Inner."<init>":(Lplayground/Outer;)V
8: astore_1
9: aload_1
10: invokevirtual #26 // Method playground/Outer$Inner.go:()V
13: return
在第 4 行我们得到 aload_0
,其中 loads in instance methods this
。
当你调用callInner
方法时,你实际上是在Outer
class的范围内。为什么编译器接受调用 new Inner()
是完全相同的,为什么你不必明确地写出 class 你想象中的静态变量来自什么(当它是同一个 class 你叫它)。请参见下面的示例:
public class Outer {
private static int x = 1;
private void innerCall() {
x++;
}
}
在上面的例子中,你做的和你的例子完全一样,除了例外,你使用 class 而不是变量(这在这里并不真正相关)。如果想从 class(作用域)外部访问 class/variable,您的语法是必需的。然后它看起来像下面的东西:
public class Outer {
public static int x = 1;
}
Outer.x++;
在上面,您必须明确指定要从哪个范围访问变量 x
。就像您想从给定目录中访问文件一样。如果您在此目录中,则只需通过文件名访问该文件。但是,当你在它外面时,你还必须写下目录的名称才能看到你想要获取的文件。
我知道要实例化一个内部成员class,你有两个不同的构造函数:
第一个:
Outer out = new Outer();
Outer.Inner in = out.new Inner();
第二个:
Outer.Inner in = new Outer().new Inner();
现在,我不知道为什么这段代码可以编译:
public class Outer {
private String greeting="Hi";
protected class Inner {
public int repeat=3;
public void go() {
for (int i =0; i<repeat; i++) {
System.out.println(greeting);
}
}
}
public void callInner() {
Inner in = new Inner(); //in my opinion the correct constructor is Outer.Inner in = new Inner()
in.go();
}
public static void main(String[] args) {
Outer out = new Outer();
out.callInner();
}
}
为什么编译?
非常感谢!
当您在 Outer
的范围内实例化 Inner
(在实例方法中)时,您不需要显式实例化引用 Outer
类,就像在您的示例中一样:
Outer.Inner in = new Outer().new Inner();
只要引用就可以实例化Inner
:
Inner in = new Inner();
这适用于 class 中的所有实例方法,只要它们不是静态的。
将调用第一个主要方法
public static void main(String[] args){
Outer out = new Outer();
out.callInner();
}
从这里您创建了一个 Outer class 的对象并调用了如下所示的 callInner 方法
public void callInner() {
Inner in = new Inner(); //in my opinion the correct constructor is Outer.Inner in = new Inner()
in.go();
}
现在您已经创建了一个 Inner 对象并调用了 go 方法。
protected class Inner {
public int repeat=3;
public void go() {
for (int i =0; i<repeat; i++) {
System.out.println(greeting);
}
}
}
所以这是一个简单的调用,所有调用都在同一范围内。所以需要 outer.Inner 概念来调用。
了解外在和内在是相关的很重要。更具体地说,您需要一个外部实例才能创建一个内部实例。
如您的解释所示,您需要 Outer
的实例来创建 Inner
的实例。由于方法 callInner
是 Outer
的实例方法(未声明 [=17=]),因此已经存在 Outer
的实例:this
代码也可以这样写:
public void callInner() {
Outer out = this;
Inner in = out.new Inner();
in.go();
}
现在代码看起来与您的第一个示例相似。
但是让我们保持代码如图所示:
public void callInner() {
Inner in = new Inner();
in.go();
}
现在,如果我们看一下引擎盖,它基本上是一样的:
public void callInner();
Code:
0: new #21 // class playground/Outer$Inner
3: dup
4: aload_0
5: invokespecial #23 // Method playground/Outer$Inner."<init>":(Lplayground/Outer;)V
8: astore_1
9: aload_1
10: invokevirtual #26 // Method playground/Outer$Inner.go:()V
13: return
在第 4 行我们得到 aload_0
,其中 loads in instance methods this
。
当你调用callInner
方法时,你实际上是在Outer
class的范围内。为什么编译器接受调用 new Inner()
是完全相同的,为什么你不必明确地写出 class 你想象中的静态变量来自什么(当它是同一个 class 你叫它)。请参见下面的示例:
public class Outer {
private static int x = 1;
private void innerCall() {
x++;
}
}
在上面的例子中,你做的和你的例子完全一样,除了例外,你使用 class 而不是变量(这在这里并不真正相关)。如果想从 class(作用域)外部访问 class/variable,您的语法是必需的。然后它看起来像下面的东西:
public class Outer {
public static int x = 1;
}
Outer.x++;
在上面,您必须明确指定要从哪个范围访问变量 x
。就像您想从给定目录中访问文件一样。如果您在此目录中,则只需通过文件名访问该文件。但是,当你在它外面时,你还必须写下目录的名称才能看到你想要获取的文件。