Way to call inner class by outer class

喜夏-厌秋 提交于 2021-02-10 06:46:03

问题


I know that to instantiate a member inner class, you have two different constructors:

First:

Outer out = new Outer();
Outer.Inner in = out.new Inner();

Second:

Outer.Inner in = new Outer().new Inner();

Now, I don't know why this code compiles:

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();

    }
}

Why does it compile?

Thanks a lot!


回答1:


As you are instantiating Inner within the scope of Outer (inside an instance method), you do not need to explicitly instantiate referencing the Outer clas, like in your example:

Outer.Inner in = new Outer().new Inner();

It is fine to instantiate by just referencing Inner:

 Inner in = new Inner();

This applies to all instance methods within a class, as long as they are not static.




回答2:


First main method will be called

public static void main(String[] args){
        Outer out = new Outer();
        out.callInner();
}

from here you have create an object of Outer class and called callInner method like below

public void callInner() {
        Inner in = new Inner(); //in my opinion the correct constructor is Outer.Inner in = new Inner()
        in.go();
    }

and now you have created an object of Inner and called go method.

 protected class Inner {
        public int repeat=3;

        public void go() {
            for (int i =0; i<repeat; i++) {
                System.out.println(greeting);
            }
        }
    }

so it's a simple call all are in a same scope. so need for outer.Inner concept to call.

It's important to understand that Outer and Inner are related. More specifically, you need an Outer instance in order to create an Inner instance.




回答3:


As your explanation shows, you need an instance of Outer to create an instance of Inner. Since the method callInner is an instance method of Outer (it is not declared static) there is already an instance of Outer present: this

The code could also be written like that:

public void callInner() {
    Outer out = this;
    Inner in = out.new Inner();
    in.go();
}

Now the code looks similar to your first example.

But let's keep the code as shown:

public void callInner() {
    Inner in = new Inner();
    in.go();
}

Now if we look under the hood it's basically the same:

 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

On line 4 we get aload_0 which loads in instance methods this.


Compare: Java Tutorials - Inner Class Example




回答4:


When you call the callInner method, you are actually within the scope of Outer class. And the reason, why the compiler accepts calling new Inner() is exactly the same, why you don't have to write explicitly what class your some imagined static variable comes from (when it's the part of the same class you call it). See example below:

public class Outer {
  private static int x = 1;

  private void innerCall() {
    x++;
  }
}

In above case, you do exactly the same as in your example with exception, that you use the class and not the variable (which is not really relevant in here). Your syntax would be necessary if wanted to access the class/variable from the outside of the class (scope). It would then look like the thing below:

public class Outer {
  public static int x = 1;
}

Outer.x++;

Above, you have to explicitly specify what scope you want to access your variable x from. It's just like you wanted to access the file from within the given directory. If you're in this directory, you just access the file by it's name. However, when you are outside of it, you have to write also the directory's name to see the file you want to get.



来源:https://stackoverflow.com/questions/53278873/way-to-call-inner-class-by-outer-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!