I don't have the answer, but I'm able to confirm that, and reduce the snippet to the following:
public class OuterClass {
private class PrivateInnerClass {
}
public void instantiate() {
new PrivateInnerClass();
}
}
This creates OuterClass$1.class
Compiled from "OuterClass.java"
class OuterClass$1 extends java.lang.Object{
}
And here's javap -c
for OuterClass.class
:
Compiled from "OuterClass.java"
public class OuterClass extends java.lang.Object{
public OuterClass();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public void instantiate();
Code:
0: new #2; //class OuterClass$PrivateInnerClass
3: dup
4: aload_0
5: aconst_null
6: invokespecial #3; //Method OuterClass$PrivateInnerClass."<init>":
//(LOuterClass;LOuterClass$1;)V
9: pop
10: return
}
And for OuterClass$PrivateInnerClass
:
Compiled from "OuterClass.java"
class OuterClass$PrivateInnerClass extends java.lang.Object{
final OuterClass this$0;
OuterClass$PrivateInnerClass(OuterClass, OuterClass$1);
Code:
0: aload_0
1: aload_1
2: invokespecial #1; //Method "<init>":(LOuterClass;)V
5: return
}
As you can see, the synthesized constructor takes an OuterClass$1
argument.
So javac
creates the default constructor to take an extra argument, of type $1
, and the value of that default argument is 5: aconst_null
.
I've found that $1
doesn't get created if either of the following is true:
- You make
public class PrivateInnerClass
- You declare a nullary constructor for
PrivateInnerClass
- Or you don't call the
new
on it
- Probably other things (e.g.
static
nested, etc).
Possibly related
- Bug ID:4295934: Compiling a private inner class creates an anonymous class file in the wrong dir
Create the following source in a directory called test:
package test;
public class testClass
{
private class Inner
{
}
public testClass()
{
Inner in = new Inner();
}
}
Compile the file from the parent directory javac test/testClass.java
Notice that the file testClass$1.class
is created in the current directory.
Not sure why this file is even created since there is also a test/testClass$Inner.class
created as well.
EVALUATION
The testClass$1.class
file is for a dummy class needed by an "access
constructor" for the private constructor of the private inner class
testClass$Inner
. Dissassembly shows that the fully-qualified name of
this class is correctly noted, so it is unclear why the class file ends
up in the wrong directory.
class OuterClass$1 extends java.lang.Object{ }
. Weird. – Tangerine