Inner classes do not work how you think they work.
An inner class looks like this:
class Outer /* must be a class; not an interface */ {
class Inner /* A class (not an interface), AND, not static {
}
}
Inner class have a secret, invisible final field that looks like:
private final Outer magicThis;
that cannot be null
. Every constructor that Inner
has, has as first parameter Outer magicThis
, but this parameter is also hidden. To pass it, you use this weird syntax:
outerInstance.new Inner();
and, crucially, which makes it 'magic', in the sense that you didn't know it worked this way, if Outer.this
was a legal expression (which it is, in any non-static method inside Outer
, for exmaple), Outer.this
is silently assumed as outerInstance: In those contexts, and only in those, just new Inner()
works.
Now that you know all this, you then understand that invoking newInstance()
on a non-static inner class does not work: That requires a no-args constructor and there isn't one: All constructors have that secret, invisible Outer magicThis
parameter.
You can observe all this by using the javap
tool.
The solution is simple: Mark your inner class as static
. In fact, go ahead and mark all your inner classes as static. Only make non-static inner class if you really know what you are doing and you are absolutely sure you really want that - the magic stuff tends to throw people off and make it easy to make wrong assumptions about code. For example, that secret ref to the outer? That can really trip you up with garbage collection (it prevents the outer instance from being collected!).
Note that your code has very crappy quality. A few things to look into:
The correct "I have no idea what to do" exception handler is NEVER to just log it and forget it, and System.out is not an appropriate logging locatino. Just e
throws away almost all relevant information - in particular the cause which is what you do NOT want to throw away. The right I dunno handler for an exception block is always this: throw new RuntimeException("Unhandled", e);
. This is short, simple, does not cause code to continue to run in an unknown state, and preserves all information. Fix this.
Don't call newInstance()
on a class; it is deprecated. It has crazy exception behaviour. You want c.getConstructor().newInstance()
instead.
objs[-1] = null
of course throws ; there is no -1 index. Presumably you want objs[icur] = null
? Or perhaps objs[objs.length - 1] = null;
? I'm not sure what repay
is trying to accomplish.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…