开发者

Dynamically instantiating an inner class nested inside an abstract class

开发者 https://www.devze.com 2023-01-30 02:26 出处:网络
I understand that to instantiate an inner class (i.e. non-static), you need an instance of the enclosing class. This makes things a little more complicated if the enclosing class is abstract (don\'t a

I understand that to instantiate an inner class (i.e. non-static), you need an instance of the enclosing class. This makes things a little more complicated if the enclosing class is abstract (don't ask). Consider the following.

abstract class Outer {
   class Inner {}
}

Instantiating Inner is still plenty doable statically with, for example, an anonymous class, like this.

Inner instance = new Outer() {}.new Inner();

But then how to accomplish the same thing dynamically with Constructor.newInstance? (Notice that I said dynamically; assume you don't know the name of the outer class.) You'd need to pass an instance of the enclosing class for the first argument, as per JLS 15.9.3, and if there's a way to create something on the fly to 开发者_JS百科satisfy an abstract parameter, I'm not aware of it (bonus points for any ideas there).

Long story short, I ended up accidentally passing in null, like this.

Constructor<Inner> constructor = Inner.class.getDeclaredConstructor(Outer.class);
Object argument = null;
Inner instance = constructor.newInstance(argument);

Imagine my surprise when that worked. My question is, why did that work? And will that always work?


It worked because the constructor just sets the Outer.this field. It probably should check that its not null, (so it fails fast) but its faster if it doesn't.

I wouldn't rely on it always working, there is every possibility that different JVMs, even different updates will work differently.

based on your previous example, this should work.

Inner instance = constructor.newInstance(new Outer(){});
0

精彩评论

暂无评论...
验证码 换一张
取 消