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.