简体   繁体   中英

Does default constructor for inner class need an object of an outer class?

I was fiddling around with java, and I created two classes, Outer and Inner

public class Outer {
    public class Inner { 
    }
}

Inner class is using default constructor. I can create new instance of Inner class inside Outer just by calling non-args default constructor new Inner() . But when I tried do same thing using reflection, I noticed constructor require Outer type object.

Is that mean inner class default constructor is not non-args? Why there is disjoint between calling constructor in normal way and reflection?

There is no "disjoint between calling constructor in normal way and reflection", only between calling constructor from inside the Outer class and from outside of Outer class.

Since the Inner class is not static , it has a reference to Outer . If you want to create an instance of Inner from outside of Outer , you must write it like this:

Outer outerObj = new Outer();
Outer.Inner innerObj = outerObj.new Inner();

The requirement to provide outerObj to the constructor of Inner is exactly the same as when you instantiate the Inner class through reflection. The only difference is that the syntax places outerObj on the left of operator new , while reflection passes outerObj to the constructor. Java compiler adds a hidden argument to the constructor that it generates automatically, in the same way that it adds a hidden field to the generated class in order to hold a reference to the Outer object.

Note that this is true only for non-static inner classes. When your inner class is static , there is no hidden parameter and no hidden field, so reflection lets you create instances of the inner class without an Outer object.

内部类不是静态的,因此只有在拥有外部对象时才能创建内部实例。

I can create new instance of Inner class inside Outer just by calling non-args default constructor new Inner()

Inside yes, but his won't compile outside of Outer or from a static method of Outer :

new Outer.Inner();

This is because when you call new Inner() inside Outer this is implicitly passed to the constructor such that this:

public class Outer {
    public class Inner {
    }

    public example(){
        new Inner();
    }
}

Is equivalent to this static version:

public class Outer {
    public static class Inner {
        private Outer mOuter;
        public Inner(Outer outer){
            mOuter = outer;
        }
    }

    public example(){
        new Inner(this);
    }
}

The hidden reference to the Outer allows the inner to invoke methods on Outer as though they are it's own.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM